The complexity of the business system has increased. In order to solve the database I/O bottleneck, it is natural to disassemble the database, table and split services to deal with it. This will lead to multiple databases that may be accessed in a system and multiple data sources need to be configured.
The first scenario: the project service retrieves basic data from other databases for business processing, so there will be no retables between each database.
The second scenario: In order to reduce the pressure of writing, read and write to the library, read and leave the library and write to the main library. This type of table name and other information are consistent.
The third scenario: Both of the above are available. For some businesses, it is hoped that the summary statistics of large data volumes will not affect the normal business, and the database must be followed by the database (the table information is consistent). Some configuration information does not have read and write pressure, and there will be no database separation (the table information is inconsistent)
Project source code:
/zzsong/
There are three directories:
one:
Directly use multi-@Bean configuration, @MapperScan to distinguish the reading library
two:
Use annotations to identify dataSource, AOP intercepts and injects dynamic data sources
third:
Use spring's Bean naming strategy to distinguish data sources
Project technical selection: springBoot2.2.5 + mybatis + druid + mysql
Look at the main pom package first
<parent> <groupId></groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.</version> <relativePath/> </parent> <dependency> <groupId></groupId> <artifactId>spring-boot-starter-data-jdbc</artifactId> </dependency> <dependency> <groupId></groupId> <artifactId>spring-boot-starter-data-jdbc</artifactId> </dependency> <dependency> <groupId></groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId></groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.19</version> </dependency> <dependency> <groupId></groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.21</version> </dependency>
spring: datasource: druid: core: url: jdbc:mysql:///kc_core?characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: type: schedule: url: jdbc:mysql:///kc_schedule?characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: type:
The new version of mysql must have serverTimezone, otherwise a connection exception will be reported.
The first type: Scan the relevant data sources through @MapperScans
@Configuration @MapperScans({ @MapperScan(basePackages = "", sqlSessionTemplateRef = "coreSqlSessionTemplate",sqlSessionFactoryRef = "coreSqlSessionFactory"), @MapperScan(basePackages = "", sqlSessionTemplateRef = "scheduleSqlSessionTemplate",sqlSessionFactoryRef = "scheduleSqlSessionFactory") }) public class MybatisOneConfig { @Bean @ConfigurationProperties(prefix = "") public DataSource coreDataSource(){ return ().build(); } @Bean public SqlSessionFactory coreSqlSessionFactory(@Qualifier("coreDataSource") DataSource coreDataSource) throws Exception { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); (coreDataSource); ().getConfiguration().setJdbcTypeForNull(null); ().getConfiguration().setMapUnderscoreToCamelCase(true); return (); } @Bean public SqlSessionTemplate coreSqlSessionTemplate(@Qualifier("coreSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } //======schedule======== @Bean @ConfigurationProperties(prefix = "") public DataSource scheduleDataSource(){ return ().build(); } @Bean public SqlSessionFactory scheduleSqlSessionFactory(@Qualifier("scheduleDataSource") DataSource coreDataSource) throws Exception { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); (coreDataSource); ().getConfiguration().setJdbcTypeForNull(null); ().getConfiguration().setMapUnderscoreToCamelCase(true); return (); } @Bean public SqlSessionTemplate scheduleSqlSessionTemplate(@Qualifier("scheduleSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
The second is the dynamic data source mode, which guides the use of data source through AOP cutting annotation. Use custom annotation @interface to identify the corresponding data source.
Note: The methods in the class call the method with data source and cannot be cut into by AOP.
@Target({, }) @Retention() @Documented public @interface TargetDataSource { String value(); }
extends spring dynamic DataSource route to match
public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return (); } }
@Configuration //@EnableConfigurationProperties()//Don't use this public configuration, Configuration will destroy the configuration of the relevant dataSource@MapperScan("") public class MybatisConfig { @Bean @ConfigurationProperties(prefix = "") public DataSource coreDataSource() { return ().build(); } @Bean @ConfigurationProperties(prefix = "") public DataSource scheduleDataSource() { return ().build(); } @Autowired @Qualifier("coreDataSource") private DataSource coreDataSource; @Autowired @Qualifier("scheduleDataSource") private DataSource scheduleDataSource; @Bean public DynamicDataSource dataSource() { Map<Object, Object> targetDataSources = new HashMap<>(); (DataSourceConstants.CORE_DATA_SOURCE, coreDataSource); (DataSourceConstants.SCHEDULE_DATA_SOURCE, scheduleDataSource); DynamicDataSource dataSource = new DynamicDataSource(); //Set the data source mapping (targetDataSources); ///// Set the default data source, and the default data source will be used when it cannot be mapped to the data source (coreDataSource); (); return dataSource; } /** * Create SqlSessionFactory based on the data source */ @Bean public SqlSessionFactory sqlSessionFactory(DynamicDataSource dataSource) throws Exception { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); (dataSource); ().getConfiguration().setJdbcTypeForNull(null); ().getConfiguration().setMapUnderscoreToCamelCase(true); return (); } @Bean public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); }
The third type is to customize the bean naming strategy, and automatically match the data source according to beanName.
@Component public class CoreBeanNameGenerator implements BeanNameGenerator { @Override public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { return "core"+ (()); } } @Component public class ScheduleBeanNameGenerator implements BeanNameGenerator { @Override public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { return "schedule"+ (()); } }
Use mybatis MapperScannerConfigurer to automatically scan, inject Mapper interface generation into spring
@Bean public MapperScannerConfigurer coreMapperScannerConfig(CoreBeanNameGenerator coreBeanNameGenerator){ MapperScannerConfigurer configurer = new MapperScannerConfigurer(); (coreBeanNameGenerator); (","); ("coreSqlSessionFactory"); ("coreSqlSessionTemplate"); return configurer; } @Bean public MapperScannerConfigurer scheduleMapperScannerConfig(ScheduleBeanNameGenerator scheduleBeanNameGenerator){ MapperScannerConfigurer configurer = new MapperScannerConfigurer(); (scheduleBeanNameGenerator); (","); ("scheduleSqlSessionFactory"); ("scheduleSqlSessionTemplate"); return configurer; }
At this point, the main points of matching three multiple data sources have been introduced, and the github project will be downloaded in detail. The resources/db contains relevant test tables and data scripts.
This is the article about springboot2+mybatis implementing multi-data configuration methods. For more related springboot2+mybatis, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!