Spring Boot + MyBatis 实现多数据源连接
文章目录
- 前言
- 利用Maven框架引入Druid技术和数据库驱动机制
- 在application.properties文件中配置必要的数据库访问参数
- 实现数据源管理的核心步骤介绍
-
具体包括数据源1的相关配置细节说明
-
四、关闭数据源自动设置
-
建议
-
其他
-
前言
项目中有访问多个数据源的需求
一、Maven引入Druid和数据库驱动
<!-- Druid 数据连接池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.18</version>
</dependency>
驱动请自行选择合适的驱动
二、application.properties中设置数据库访问参数
我们可以自定义参数。然而需要注意的是, 这些参数并非由Spring Boot自动注入数据源, 而是后续操作中需要我们手动引用它们
#mysql1
mysql1.datasource.driverClassName=com.mysql.jdbc.Driver
mysql1.datasource.url=jdbc:mysql://localhost:3306/db1?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
mysql1.datasource.username=root
mysql1.datasource.password=123456
#mysql2
mysql2.datasource.driverClassName=com.mysql.jdbc.Driver
mysql2.datasource.url=jdbc:mysql://localhost:3306/db2?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
mysql2.datasource.username=root
mysql2.datasource.password=123456
三、编写数据源的配置文件
1.数据源1配置文件示例
@Configuration
@MapperScan(basePackages = DB1DataSourceConfig.PACKAGE, sqlSessionFactoryRef = "DB1SqlSessionFactory")
public class DB1DataSourceConfig {
// 存放Mapper的包,项目中Mapper使用@Mapper注解
static final String PACKAGE = "com.naristc.scsdeci.mapper.mysql1";
@Value("${mysql1.datasource.url}")
private String url;
@Value("${mysql1.datasource.username}")
private String user;
@Value("${mysql1.datasource.password}")
private String password;
@Value("${mysql1.datasource.driverClassName}")
private String driverClass;
// 配置数据源连接参数
@Bean(name = "DB1DataSource")
public DruidDataSource DB1DataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setValidationQuery("SELECT 1");
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(password);
return dataSource;
}
@Bean(name = "DB1TransactionManager")
public DataSourceTransactionManager DB1TransactionManager() {
return new DataSourceTransactionManager(DB1DataSource());
}
// SessionFactory
@Bean(name = "DB1SqlSessionFactory")
public SqlSessionFactory DB1SqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(DB1DataSource());
return sqlSessionFactoryBean.getObject();
}
@Bean
public SqlSessionTemplate DB1SqlSessionTemplate() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(DB1SqlSessionFactory());
return template;
}
}
注释如下:值得注意的是,在多数据源的情景下通常建议选择一个作为主数据源,并在该主数据源的工厂设置中添加@Primary标签。然而,在实际应用中我发现未启用此功能时并未遇到异常问题;如有后续出现相关问题可进行相应更新。
一个数据源一个配置文件
四、关闭数据源自动设置
由于SpringBoot预设为单数据源模式,默认情况下无需进行此自动配置;在SpringBootApplication注解中添加 exclude 字段即可完成相关配置。
// 由于Spring Boot默认单数据源,所以在启动类中需要使用注解去除该默认项
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class ScsdeciApp extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure (SpringApplicationBuilder builder){
// 注意这里要指向原先用main方法执行的Application启动类
return builder.sources(ScsdeciApp.class);
}
public static void main(String[] args) {
SpringApplication.run(ScsdeciApp.class, args);
}
}
建议
生成配置文件时通常会指定一组包,并对这些包中的Mapper进行扫描。推荐将不同来源的数据模型、实例以及对应的Mapper等分别存储起来。避免因名称相似或相同导致混淆的问题

其他
虽然并不影响程序运行,但是Druid确实会报出一个错误,如图所示:

那么这句话具体表达什么意思呢?
testWhileIdle直译上意为:程序在空闲时段执行查询操作以检测连接状态;
而validationQuery意指用于检测连接状态的查询并未被配置。
在网络上的一些博客资源中提供了针对该问题的解决方案方法。

这个方法或许以前可能可行, 但现在不可行, 因为SpringBoot的新版本不再自动生成Druid数据库, 当然在application.properties中进行配置也失去了作用.
然而,在这种情况下,并非通过SpringBoot自动注入数据源Bean来实现多样化的数据源配置;而是我们采用了人工配置的方式
因此,在所有数据库的Config文件中配置一下与数据源相关的validationQuery参数即可解决问题。
dataSource.setValidationQuery("SELECT 1");
另外一种情况是:从另一个角度来看,可以关闭检测连接的状态;这样就不必再设置那个查询语句了。
dataSource.setTestWhileIdle(false);
两者选一就可以了,当然我更倾向于第一种方法
