Spring Boot realizes multi data source integration Mybatis version

Posted by Tyche on Wed, 22 Dec 2021 03:41:34 +0100

preface

This blog only talks about how to realize multi data source configuration in Spring Boot project from zero to one, not about the source code (later, Spring Boot automatic configuration and other source codes).

This blog is based on spring boot version 2.5 1.

background

Multiple data sources need to be connected in a project. We need to access different data sources at different interfaces of the business layer. At this time, we need to integrate the project to adapt to multiple data sources. This blog starts from this.

Implementation steps

1. Configure multiple data source parameters in the configuration file

After the data source, add characters identifying the corresponding data source, such as action and quotation in my case. The detailed code is pasted below

Notice: the url configuration item here must write JDBC url, otherwise it will report an illegal parameter exception.

 spring:
   datasource:
     # Market center 
     quotation:
       driver-class-name: com.mysql.cj.jdbc.Driver
       jdbc-url: jdbc:mysql://10.253.49.32:3306/quotation_test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
       username: root
       password: 123456
     # Actual project corresponding database
     action:
       driver-class-name: com.mysql.cj.jdbc.Driver
       jdbc-url: jdbc:mysql://localhost:3306/stupid_kid_action?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
       username: root
       password: 123456

2. Define the interfaces and xml files corresponding to accessing different data sources

  1. Interfaces accessing different data sources are stored separately according to the directory, as shown in the figure

  2. XML files accessing different data sources are stored separately according to the directory, as shown in the figure

3. Create configuration classes for each data source

  1. Create a configuration class, introduce corresponding configuration parameters, and create multiple data source objects with complete code attached.

    • @Bean (name = "action datasource"): defines the name of the created data source object, which will be used later
    • @ConfigurationProperties(prefix = "spring.datasource.action"): declare the source of data source parameters in the configuration file
     @Configuration
     public class DataSourceConfig {
         @Bean(name = "action-datasource")
         @ConfigurationProperties(prefix = "spring.datasource.action")
         public DataSource actionDbDataSource() {
             return DataSourceBuilder.create().build();
         }
     ​
         @Bean(name = "quotation-datasource")
         @ConfigurationProperties(prefix = "spring.datasource.quotation")
         public DataSource quotaDbDataSource() {
             return DataSourceBuilder.create().build();
         }
     }
  2. Create corresponding SqlSessionFactory objects and SqlSessionTemplate objects according to different data sources, with complete code attached below.

    • @Qualifier ("action data source"): inject the corresponding data source
    • @MapperScan(basePackages = {"com.tree.action.multidatasource.mapper.action"}, sqlSessionFactoryRef = "actionSqlSessionFactoryDb"): configure the dao layer interface location corresponding to accessing the corresponding data source and the method name referencing actionSqlSessionFactory
    • getResources("classpath:mapping/action/*.xml"): configure the location of the resource file
     @Configuration // If this annotation is not added here, it will cause errors in calling each other between bean s
     @MapperScan(basePackages = {"com.tree.action.multidatasource.mapper.action"},
         sqlSessionFactoryRef = "actionSqlSessionFactoryDb")
     public class ActionDbConfig {
         @Autowired
         @Qualifier("action-datasource")
         private DataSource actionDataSourceDb;
     ​
         @Bean
         public SqlSessionFactory actionSqlSessionFactoryDb() throws Exception {
             SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
             factoryBean.setDataSource(actionDataSourceDb);
             factoryBean.setMapperLocations(
                 new PathMatchingResourcePatternResolver().getResources("classpath:mapping/action/*.xml"));
             return factoryBean.getObject();
         }
     ​
         @Bean
         public SqlSessionTemplate actionSqlSessionTemplateDb() throws Exception {
             return new SqlSessionTemplate(actionSqlSessionFactoryDb());
         }
     }
     ​
     ​
     @Configuration // If this annotation is not added here, it will cause errors in calling each other between bean s
     @MapperScan(basePackages = {"com.tree.action.multidatasource.mapper.quotation"},
         sqlSessionFactoryRef = "quotationSqlSessionFactoryDb")
     public class QuotationDbConfig {
     ​
         @Autowired
         @Qualifier("quotation-datasource")
         private DataSource actionDataSourceDb;
     ​
         @Bean
         public SqlSessionFactory quotationSqlSessionFactoryDb() throws Exception {
             SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
             factoryBean.setDataSource(actionDataSourceDb);
             factoryBean.setMapperLocations(
                 new PathMatchingResourcePatternResolver().getResources("classpath:mapping/quotation/*.xml"));
             return factoryBean.getObject();
         }
     ​
         @Bean
         public SqlSessionTemplate quotationSqlSessionTemplateDb() throws Exception {
             return new SqlSessionTemplate(quotationSqlSessionFactoryDb());
         }
     }

4. Develop the test interface under the corresponding directory to see the effect of the test

  1. Develop the corresponding interface and call the interface

  2. Call interface test effect

Tips

If you switch from a single data source, you need to delete the annotation @ MapperScan on the startup class, otherwise the corresponding dao layer interface bean will be generated twice (it can be understood that in the multi data source environment, you declare the corresponding dao layer location yourself and configure the automatic scanning assembly on the startup class twice). In this case, the following warning will be reported:

Reflection and harvest

Just as I told a friend today, the integration of multiple data sources has touched a small point, that is, after the integration of multiple data sources, the default automatic assembly annotation previously configured in the startup class should be deleted, otherwise the warning of repeated bean creation will be reported

Topics: Java Spring Spring Boot