Spring boot + mybatis configure multiple data sources

Time:2021-10-12

Spring boot + mybatis configure multiple data sources

In development, sometimes our database is read-write sub database. Then, when developing and using, we need to read databases from different sources. We need to configure spring boot mybatis for multi-source processing.

Four classes required

Spring boot + mybatis configure multiple data sources

Databasecontextholder: used in Dao layer or service layer to select which data source to use.

Datebasetype: enumeration class that enumerates all data source names.

Dynamicdatasource: inherits abstractroutingdatasource and implements the method
Determinecurrentlookupkey gets the data source of the current thread.

Mybatisconfig: set the data source, involving datasource, dynamicdatasource and sqlsessionfactory

Datasource (Interface): the objectification, driver, connection address, user name and password of the data source are its properties. We use the Druid provided by Alibaba.

Sqlsessionfactory: create sqlsession in factory mode (which can be understood as connection in JDBC)

DateBaseType

/**
 *List all data source keys (commonly named by database name)
 *Note:
 *1) the data source and database here are one-to-one
 *2) the variable name in databasetype is the name of the database
 * @Author xuelongjiang
 */
public enum DatabaseType {

    main,yuntu
}

DatabaseContextHolder

/**
 *Save a thread safe databasetype container
 * @Author xuelongjiang
 */
public class DatabaseContextHolder {

    private static final  ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<>();

    public static void setDatabaseType(DatabaseType type){
            contextHolder.set(type);
    }

    public static  DatabaseType getDatabaseType(){
        return contextHolder.get();
    }

}

DynamicDataSource

/**
 *Dynamic data source (need to inherit abstractroutingdatasource)
 * @Author xuelongjiang
 */
public class DynamicDataSource  extends AbstractRoutingDataSource{

    @Nullable
    @Override
    protected Object determineCurrentLookupKey() {
        return DatabaseContextHolder.getDatabaseType();
    }


}

MybatisConfig

/**
 *Springboot integrates the basic entry of mybatis 1) create a data source (not required if the default Tomcat JDBC data source is used)
 *2) create sqlsessionfactory 3) configure the transaction manager. Unless you need to use a transaction, you don't need to configure it
 * @Author xuelongjiang
 */
@Configuration // this annotation is similar to the spring configuration file
@ComponentScan(basePackages = "fm.xiaoai.wxmanager.dao")
public class MyBatisConfig {

    @Autowired
    private Environment environment;


    /**
     *Create a data source (the name of the data source: the method name can be xxxdatasource (), XXX is the database name, which is the name of the data source)
    */
    @Bean
    public DataSource mainDataSource() throws Exception {
        Properties props = new Properties();
        props.put("driverClassName", environment.getProperty("main-datasource.driverClassName"));
        props.put("url", environment.getProperty("main-datasource.url"));
        props.put("username", environment.getProperty("main-datasource.username"));
        props.put("password", environment.getProperty("main-datasource.password"));
        return DruidDataSourceFactory.createDataSource(props);
}

    @Bean
    public DataSource yuntuDataSource() throws Exception {
        Properties props = new Properties();
        props.put("driverClassName", environment.getProperty("yuntu-datasource.driverClassName"));
        props.put("url", environment.getProperty("yuntu-datasource.url"));
        props.put("username", environment.getProperty("yuntu-datasource.username"));
        props.put("password", environment.getProperty("yuntu-datasource.password"));
        return DruidDataSourceFactory.createDataSource(props);
}


    /**
     *@ primary this annotation indicates which implementation classes can be injected into the same interface by default, rather than making the @ autowire annotation report an error
     *@ qualifier injects by name, usually in one injection of instances with the same multiple types (for example, instances with multiple datasource types)
     */
    @Bean
    @Primary
    public DynamicDataSource dataSource(@Qualifier("mainDataSource") DataSource mainDataSource,
                                    @Qualifier("yuntuDataSource") DataSource yuntuDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DatabaseType.main, mainDataSource);
        targetDataSources.put(DatabaseType.yuntu, yuntuDataSource);

        DynamicDataSource dataSource = new DynamicDataSource();
        dataSource.setTargetDataSources(targetDataSources);//  This method is the method of abstractroutingdatasource
        dataSource.setDefaultTargetDataSource(mainDataSource);//  The default datasource is set to mytestdbdatasource

        return dataSource;
    }

    /**
     *Create sqlsessionfactory from data source
     */
    @Bean
     public SqlSessionFactory sqlSessionFactory(@Qualifier("mainDataSource") DataSource mainDataSource,
                                            @Qualifier("yuntuDataSource") DataSource yuntuDataSource) throws Exception{
                 SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
                fb.setDataSource(this.dataSource(mainDataSource, yuntuDataSource));
                   fb.setTypeAliasesPackage("fm.xiaoai.exmanager");// Can not be set
                 fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
                 return fb.getObject();
             }

    /**
     *Configure transaction manager
     */
    @Bean
    public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
        return new DataSourceTransactionManager(dataSource);
    }

}

reference resources

http://www.cnblogs.com/java-z…

Pay attention to my official account, read the interesting technical stories for the first time.
Code scanning attention:
Spring boot + mybatis configure multiple data sources
You can also search for the official account in WeChat, you can focus on me: codexiulian
Eager to grow and progress with you!