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