Spring Mabatis 多数据源配置

实际的业务场景中,有时需要使用多数据源,我们看看如何快速地进行配置。

基础环境

Spring boot 2.1.1.RELEASE
Mybatis 1.3.1
HikariCP 3.1.0
pom文件
    
    1.8
    

    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.1.1
        

        
            com.zaxxer
            HikariCP
            3.1.0
        

        
            javax.inject
            javax.inject
            1
        

        
            mysql
            mysql-connector-java
            runtime
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

主要配置

1 application.properties
spring.datasource.primary.jdbc-url=url1
spring.datasource.primary.username=usr1
spring.datasource.primary.password=pw1
spring.datasource.schema.jdbc-url=url2
spring.datasource.schema.username=usr2
spring.datasource.schema.password=pw2

注意配置多数据源时,url的key需要配置成jdbc-url

2 数据库连接池配置类

DatabaseConfiguration.java
用于使用不同url连接池的实例化

@Configuration
public class DatabaseConfiguration {

    public static final String PRIMARY_DATASOURCE = "PriDS";
    public static final String METADATA_DATASOURCE = "MetaDS";

    @Bean(name = PRIMARY_DATASOURCE, destroyMethod = "")
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    @Primary
    public DataSource dataSourcePrimary(){
        return new HikariDataSource();
    }

    @Bean(name = METADATA_DATASOURCE, destroyMethod = "")
    @ConfigurationProperties(prefix = "spring.datasource.schema")
    public DataSource dataSourceMetadata(){
        return new HikariDataSource();
    }

}
3 创建Mybatis mapper bean配置类

MyBatisConfiguration.java

@Configuration
@MapperScan("com.example.multiDatasourceDemo.mapper")
public class MyBatisConfiguration {
    public static final String PRIMARY_SESSION_FACTORY = "primarySessionFactory";
    public static final String METADATA_SESSION_FACTORY = "metadataSessionFactory";

    /*primary datasource factory bean,use @MapperScan for creating mapper bean */
    @Bean(name = PRIMARY_SESSION_FACTORY)
    @Primary
    public SqlSessionFactoryBean primarySqlSessionFactory(
            @Named(DatabaseConfiguration.PRIMARY_DATASOURCE)final DataSource primaryDataSource) throws Exception{
        final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(primaryDataSource);
        VFS.addImplClass(SpringBootVFS.class);
        PathMatchingResourcePatternResolver pathM3R = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(pathM3R.getResources("classpath:mapper/**/*Mapper.xml"));
        sqlSessionFactoryBean.setTypeAliasesPackage("com.example.multiDatasourceDemo.domain");
        SqlSessionFactory sqlSessionFactory;
        sqlSessionFactory = sqlSessionFactoryBean.getObject();
        return sqlSessionFactoryBean;
    }

    /*another datasource factory bean*/
    @Bean(name = METADATA_SESSION_FACTORY)
    public SqlSessionFactoryBean metaSqlSessionFactory(
            @Named(DatabaseConfiguration.METADATA_DATASOURCE) final DataSource anotherDataSource) throws Exception {
        final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(anotherDataSource);
        VFS.addImplClass(SpringBootVFS.class);
        PathMatchingResourcePatternResolver pathM3R = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(pathM3R.getResources("classpath:anothermapper/anotherMapper.xml"));
        sqlSessionFactoryBean.setTypeAliasesPackage("com.example.multiDatasourceDemo.domain");
        final SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
        return sqlSessionFactoryBean;
    }

    @Bean
    public MapperFactoryBean dbMapper(
            @Named(METADATA_SESSION_FACTORY) final SqlSessionFactoryBean sqlSessionFactoryBean) throws Exception {
        MapperFactoryBean factoryBean = new MapperFactoryBean<>(AnotherMapper.class);
        factoryBean.setSqlSessionFactory(sqlSessionFactoryBean.getObject());
        return factoryBean;
    }
}

创建两个使用不同连接池的工厂bean,作用是通以此创建mapper bean。其中primaryDataSource使用了@MapperScan注解进行mapper class的扫描,在需要被扫描的mapper class上添加@Mapper注解。在项目中mapper数量较多的情况下使用此方式,减少手动创建的代码量。anotherDataSource实例化的mapper使用手动创建的方式,即dbMapper方法,指定了mapper class。

此外如果sql在xml文件内,需要配置setMapperLocations,将xml文件路径配置成要扫描的内容。

setTypeAliasesPackage用于配置sql中使用的resultType当参数的类的包路径,配置后使用时只需要写类名即可。否则需要写完整的包路径和类名。当整个项目打包jar文件后,setTypeAliasesPackage配置不生效,导致部分类扫描不到,需要添加VFS.addImplClass(SpringBootVFS.class)配置。

4 使用实例

详见github的项目,包含测试的controller、mapper、sql与测试用例

参考链接

https://medium.com/@d.lopez.j...

项目地址

https://github.com/tifazxy/Mu...

你可能感兴趣的:(spring)