Spring Boot项目在整合Mybatis过程中全部使用了注解配置,由于业务系统涉及多个数据源,查阅后整理输出供需要的伙伴参考。
难点
由于全部使用@Mapper注解在接口中定义了DAO层逻辑,且在使用过程中直接使用@Autowired注入了该接口的代理对象,因此在有多个数据源的场景下在什么位置安全的切换数据源是需要考虑的问题。
分析
Mybatis中Session是和SqlSessionFactory对象绑定的,如果多个数据源共用一个SqlSessionFactory且数据源可修改则可能出现在修改数据源期间,同一业务模块在不同时刻获取到不同的数据源对象,当然SqlSessionFactory和
SqlSession都不支持动态修改数据源,因此现有的解决方案可以为不同的数据源创建不同的SqlSessionFactory实例并绑定到特定的数据源中。
实现
使用两个独立的配置文件配置数据源,同时指定不同的SqlSessionFactory实例扫描不同包下的@Mapper接口,这样的可以使用不同的包来区分针对不同数据源的业务逻辑。
配置数据源“analysis”只扫描com.ehl.tvc.dap.business包下的Dao层对象;
@Configuration
@MapperScan(basePackages = "com.ehl.tvc.dap.business", sqlSessionFactoryRef = "analysisSqlSessionFactoryBean")
public class DapPortalConfigurationDataSourceAnalysis {
@Bean("analysis")
@Primary
@ConfigurationProperties(prefix = "analysis")
public DataSource analysis() {
DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
@Bean("analysisSqlSessionFactoryBean")
public SqlSessionFactory analysisSqlSessionFactoryBean(@Qualifier("analysis") DataSource analysis)
throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(analysis);
return sqlSessionFactoryBean.getObject();
}
}
配置数据源“application”扫描包com.ehl.tvc.dap.application下的DAO层对象
@Configuration
@MapperScan(basePackages = "com.ehl.tvc.dap.application", sqlSessionFactoryRef = "applicationSqlSessionFactory")
public class DapPortalConfigurationDataSourceApplication {
@Bean("application")
@ConfigurationProperties(prefix = "application")
public DataSource application() {
DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
@Bean("applicationSqlSessionFactory")
public SqlSessionFactory applicationSqlSessionFactory(@Qualifier("application") DataSource application)
throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(application);
return sqlSessionFactoryBean.getObject();
}
}
这样设计后使用数据源analysis的业务皆在com.ehl.tvc.dap.business包下定义,使用数据源application的业务皆在包com.ehl.tvc.dap.application下定义。
依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot-starter-version>2.1.0.RELEASE</spring-boot-starter-version>
<spring-cloud-starter-version>2.1.0.RELEASE</spring-cloud-starter-version>
<mybatis-version>3.5.0</mybatis-version>
<spring-version>5.1.2.RELEASE</spring-version>
<mybatis-spring-version>2.0.0</mybatis-spring-version>
<junit-version>4.12</junit-version>
<druid-version>1.1.12</druid-version>
<freemaker-version>1.8.1</freemaker-version>
<oracle-version>11.2.0.3</oracle-version>
<thymeleaf-version>3.0.11.RELEASE</thymeleaf-version>
<swagger-version>2.9.2</swagger-version>
<jedis-version>2.9.0</jedis-version>
<rabbitmq-version>4.8.3</rabbitmq-version>
<quartz-version>2.3.0</quartz-version>
<ant-version>1.9.4</ant-version>
<jsr311-api-version>1.1.1</jsr311-api-version>
<commons-compress-version>1.18</commons-compress-version>
</properties>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
配置
analysis.driverClassName=oracle.jdbc.driver.OracleDriver
analysis.url=
analysis.username=
analysis.password=
analysis.initialSize=2
analysis.maxActive=30
#
application.driverClassName=oracle.jdbc.driver.OracleDriver
application.url=
application.username=
application.password=
application.initialSize=2
application.maxActive=30