(一)需求
基于 Spring Boot + MyBatis 是目前最流行的后端 CRUD 开发框架组合,在 CRUD 项目开发过程中,往往会需要连接多个数据库。目前解决方案有 JPA 多数据源方案、AOP 动态切换等,但都比较复杂,比如引入 JPA 甚至要求开发工程师能够熟悉 JPA 框架的CRUD。
本文本着最简化解决方案的原则,立足于 Spring Boot + MyBatis 来做多数据源的配置。
(二)代码
application 配置
在 application.yml
中,进行了双数据源 MySQL 和 Oracle 的配置:
spring:
datasource:
core:
jdbc-url: jdbc:mysql://192.168.0.1:3306/auto_test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
jira:
jdbc-url: jdbc:oracle:thin:@//192.168.0.2:1521/test
username: root
password: root
driver-class-name: oracle.jdbc.driver.OracleDriver
其中自定义属性 spring.datasource.core
和 spring.datasource.jira
是按照业务命名的。
@Configuration 配置
对于双数据源,需要在代码中进行如下配置:
core 业务 MySQL 数据源:CoreDataSourceConfig
@Configuration
@MapperScan(basePackages = {"com.aac.autotest.mapper.core"}, sqlSessionTemplateRef = "coreSqlSessionTemplate")
public class CoreDataSourceConfig {
@Bean(name = "coreDataSource")
@ConfigurationProperties(prefix = "spring.datasource.core")
@Primary
public DataSource coreDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "coreSqlSessionFactory")
@Primary
public SqlSessionFactory coreSqlSessionFactory(
@Qualifier("coreDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/core/*.xml"));
return bean.getObject();
}
@Bean(name = "coreTransactionManager")
@Primary
public DataSourceTransactionManager coreTransactionManager(
@Qualifier("coreDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "coreSqlSessionTemplate")
@Primary
public SqlSessionTemplate coreSqlSessionTemplate(
@Qualifier("coreSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
jira 业务 Oracle 数据源:JiraDataSourceConfig
@Configuration
@MapperScan(basePackages = {"com.aac.autotest.mapper.jira"}, sqlSessionTemplateRef = "jiraSqlSessionTemplate")
public class JiraDataSourceConfig {
@Bean(name = "jiraDataSource")
@ConfigurationProperties(prefix = "spring.datasource.jira")
public DataSource jiraDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "jiraSqlSessionFactory")
public SqlSessionFactory jiraSqlSessionFactory(
@Qualifier("jiraDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/jira/*.xml"));
return bean.getObject();
}
@Bean(name = "jiraTransactionManager")
public DataSourceTransactionManager jiraTransactionManager(
@Qualifier("jiraDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "jiraSqlSessionTemplate")
public SqlSessionTemplate jiraSqlSessionTemplate(
@Qualifier("jiraSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
注意,在多数据源中必须指定唯一一个数据源为主数据源,即在 DataSource
, SqlSessionFactory
, TransactionManager
, SqlSessionTemplate
的 Bean 类创建方法上加入 @Primary
注解,否则在项目启动时会报错。
mapper 层
将mapper 层的 Java 接口代码和 MyBatis xml 文件分别放置到以下路径:
- core 业务 —— MySQL 数据库
main/java/com.jake.demo.mapper.core
:存放 Java 接口
main/resources/mapper/core/
:存放 XxxMapper.xml 文件 - jira 业务 —— Oracle 数据库
main/java/com.jake.demo.mapper.jira
:存放 Java 接口
main/resources/mapper/jira/
:存放 XxxMapper.xml 文件