[SpringBoot]Springboot+mybatis multi-data source configuration scheme

Posted by webren on Thu, 28 Nov 2019 03:58:21 +0100

There are many demand scenarios for multiple data sources, while springboot only provides a single data source configuration, so when we need to configure multiple data sources, we need to do it by ourselves.

The configuration of multiple data sources described in this article distinguishes different data sources by subcontracting, that is, code under the same package uses the same data source, and code under different packages uses different data sources.

Multiple data source configuration, only 3 steps:

1. Configure multiple data sources in the configuration file.

2. Write multi-data source configuration classes.

3. Subcontract the code related to each data source.

Next, let's step by step:

1. Configure multiple data sources in the configuration file

The author likes the yml format profile, so the yml profile will be shown as follows:

financial:
  datasource:
    url: jdbc:sqlserver://localhost:1433;databasename=financal_user
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    username: sa
    password: 123456
count:
  datasource:
    url: jdbc:sqlserver://localhost:1433;databasename=financal
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    username: sa
    password: 123456
doubtful:
  datasource:
    url: jdbc:sqlserver://localhost:1433;databasename=financial_doubtful
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    username: sa
    password: 123456

The Sql Server database driver is used here. Students who use other databases should modify it themselves.

Note: springboot comes with its own data source configuration, with the top level being spring, where the top level name has been changed to distinguish data sources.

2. Write multi-data source configuration classes.

Here, each data source needs to write two classes, the data source parameter class and the configuration class.When configuring multiple data sources, you need to specify the primary and secondary data sources, for example:

(1) Data source parameter class

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Getter
@Setter
@ConfigurationProperties(prefix = "count.datasource")
@ConditionalOnProperty(prefix = "count.datasource")
public class CountDataSourceProperty {

    private String url;

    private String username;

    private String password;

    private String driverClass;
}

2) Data Source Configuration Class

import com.alibaba.druid.pool.DruidDataSource;
import com.tond.financial.config.properties.CountDataSourceProperty;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@EnableConfigurationProperties(CountDataSourceProperty.class)
@MapperScan(basePackages = "com.tond.count.mapper.count", sqlSessionFactoryRef = "countSqlSessionFactory")
public class CountDataSourceConfig {

    private final String mapperLocation = "classpath:com/tond/financial/mapper/count/*.xml";

    @Bean
    @Primary
    @ConditionalOnClass(CountDataSourceProperty.class)
    public DataSource countDataSource(CountDataSourceProperty property) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(property.getDriverClass());
        dataSource.setUrl(property.getUrl());
        dataSource.setUsername(property.getUsername());
        dataSource.setPassword(property.getPassword());
        return dataSource;
    }

    @Bean
    @Primary
    @ConditionalOnBean(name = "countDataSource")
    public DataSourceTransactionManager countTransactionManager(@Qualifier("countDataSource") DataSource countDataSource) {
        return new DataSourceTransactionManager(countDataSource);
    }


    @Bean
    @Primary
    @ConditionalOnBean(name = "countDataSource")
    public SqlSessionFactory countSqlSessionFactory(@Qualifier("countDataSource") DataSource countDataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(countDataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(mapperLocation));
        return sessionFactory.getObject();
    }
}

In the configuration class, where the @MapperScan annotation is used to specify that different data sources are used under different packages.The mapperLocation property specifies the location of the xml.The @Primary comment is used to indicate that this is the primary data source and not the other secondary data sources.Note: Only one primary data source is allowed in a system.

3. Subcontracting code for each data source

Next, as long as you place code that uses different data sources under different packages, you can accomplish the need for separate use of multiple data sources.

        

Finally, in a multiple data source configuration, if you need to use a transaction mechanism, you need to manually specify which transaction to use:

@Transactional(value = "financialTransactionManager")

Setting the transaction name in the value property configures the transaction in the data source configuration class.

Conclusion: springboot provides many convenient configurations to simplify our use of the framework and reduce the cost of building it, but it is still necessary to understand the original use and principles of the framework.

Topics: JDBC SpringBoot Spring SQL