# myabtis-dynamic-data-source2
**Repository Path**: Instinctb/myabtis-dynamic-data-source2
## Basic Information
- **Project Name**: myabtis-dynamic-data-source2
- **Description**: 通过包路径指定数据源
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-01-17
- **Last Updated**: 2026-01-17
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# SpringBoot 整合Mybatis 多数据源
在业务场景中,随着数据量迅速增长,一个库一个表已经满足不了我们的需求的时候,我们就会考虑分库分表的操作,本文主要介绍SpringBoot + Mybatis 如何实现多数据源,动态数据源切换,可用于读写分离或多库存储。
> 主要的配置说明见代码注释
## 一、 数据库准备
> 为了展示本文多数据源配置的灵活性,本文先配置两个数据库,最后新增第三个数据库,真正实现“零配置扩展”。
1. 新建二个数据库名分别为master,slave1;
2. 分别在master、slave1中创建表和插入测试数据。
* master 库 sql
```sql
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) AUTO_INCREMENT PRIMARY KEY COMMENT '自增主键',
`user_name` varchar(50) NOT NULL COMMENT '用户名',
`user_age` int(3) DEFAULT 0 COMMENT '用户年龄'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT = '主库用户表';
INSERT INTO `user` VALUES (1, '张三', 27);
```
* slave1 库 sql
```sql
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) AUTO_INCREMENT PRIMARY KEY COMMENT '自增主键',
`user_name` varchar(50) NOT NULL COMMENT '用户名',
`user_age` int(3) DEFAULT 0 COMMENT '用户年龄'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT = '从库slave1用户表';
INSERT INTO `user` VALUES (2, '李四', 30);
```
## 二、 项目配置
### 2.1 项目依赖
```pom
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
mysql
mysql-connector-java
runtime
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
com.alibaba
druid-spring-boot-starter
1.1.10
org.projectlombok
lombok
1.8.4
```
### 2.2 项目配置文件`application.yml`
其中 `master` 数据源一定是要配置,它是我们的默认数据源,其次`cluster`集群中,其他的数据不配置也不会影响程序员运行,如果你想添加新的一个数据源 就在cluster下新增一个数据源即可,其中key为必须项,用于数据源的唯一标识,以及接下来切换数据源的标识。
```
server:
port: 8084
spring:
datasource:
# 主数据库
master:
password: master
url: jdbc:mysql://47.98.178.84:3306/master?useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.cj.jdbc.Driver
username: master
# type: com.alibaba.druid.pool.DruidDataSource
# 从数据库集群(可继续扩展)
cluster:
- key: slave1
password: slave_1
url: jdbc:mysql://47.98.178.84:3306/slave_1?useUnicode=true&characterEncoding=UTF-8
# idle-timeout: 20000
driver-class-name: com.mysql.cj.jdbc.Driver
username: slave_1
# type: com.alibaba.druid.pool.DruidDataSource
druid:
# 使用druid数据源
type: com.alibaba.druid.pool.DruidDataSource
# 配置获取连接等待超时的时间
# 下面为连接池的补充设置,应用到上面所有数据源中
# 初始化大小,最小,最大
initialSize: 1
minIdle: 3
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 30000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
useGlobalDataSourceStat: true
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: cn.van.mybatis.multipleData.entity
# mybatis sql 日志
logging:
level:
cn:
van:
mybatis:
multipleData:
mapper: debug
```
## 三、 多数据源配置
### 3.1 动态数据源注册`DynamicDataSourceRegister`
SpringBoot 无法为我们自动配置我们刚在配置文件中配置的多个数据源的,所以需要我们实现 `ImportBeanDefinitionRegistrar `接口实现数据源注册,同时实现 `EnvironmentAware` 读取`application.yml`配置。
```java
@Slf4j
public class DynamicDataSourceRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware {
/**
* 配置上下文(也可以理解为配置文件的获取工具)
*/
private Environment evn;
/**
* 别名
*/
private final static ConfigurationPropertyNameAliases aliases = new ConfigurationPropertyNameAliases();
/**
* 由于部分数据源配置不同,所以在此处添加别名,避免切换数据源出现某些参数无法注入的情况
*/
static {
aliases.addAliases("url", new String[]{"jdbc-url"});
aliases.addAliases("username", new String[]{"user"});
}
/**
* 存储我们注册的数据源
*/
private Map customDataSources = new HashMap();
/**
* 参数绑定工具 springboot2.0新推出
*/
private Binder binder;
/**
* ImportBeanDefinitionRegistrar接口的实现方法,通过该方法可以按照自己的方式注册bean
*
* @param annotationMetadata
* @param beanDefinitionRegistry
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
// 获取所有数据源配置
Map config, defauleDataSourceProperties;
defauleDataSourceProperties = binder.bind("spring.datasource.master", Map.class).get();
// 获取数据源类型(我这里都用druid连接池,所以修改下)
// String typeStr = evn.getProperty("spring.datasource.master.type");
String typeStr = evn.getProperty("spring.datasource.druid.type");
// 获取数据源类型
Class extends DataSource> clazz = getDataSourceType(typeStr);
// 绑定默认数据源参数 也就是主数据源
DataSource consumerDatasource, defaultDatasource = bind(clazz, defauleDataSourceProperties);
DynamicDataSourceContextHolder.keys.add("master");
log.info("注册默认数据源成功");
// 获取其他数据源配置
List