MP的动态数据源我这里使用一个第三方拓展库;
详细文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611
1. 特性
- 支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
- 支持数据库敏感配置信息 加密 ENC()。
- 支持每个数据库独立初始化表结构schema和数据库database。
- 支持无数据源启动,支持懒加载数据源(需要的时候再创建连接)。
- 支持 自定义注解 ,需继承DS(3.2.0+)。
- 提供并简化对Druid,HikariCp,BeeCp,Dbcp2的快速集成。
- 提供对Mybatis-Plus,Quartz,ShardingJdbc,P6sy,Jndi等组件的集成方案。
- 提供 自定义数据源来源 方案(如全从数据库加载)。
- 提供项目启动后 动态增加移除数据源 方案。
- 提供Mybatis环境下的 纯读写分离 方案。
- 提供使用 spel动态参数 解析数据源方案。内置spel,session,header,支持自定义。
- 支持 多层数据源嵌套切换 。(ServiceA >>> ServiceB >>> ServiceC)。
- 提供 基于seata的分布式事务方案。
- 提供 本地多数据源事务方案。
2. 约定
- 本框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何CRUD。
- 配置文件所有以下划线
_
分割的数据源 首部 即为组的名称,相同组名称的数据源会放在一个组下。 - 切换数据源可以是组名,也可以是具体数据源名称。组名则切换时采用负载均衡算法切换。
- 默认的数据源名称为 master ,你可以通过
spring.datasource.dynamic.primary
修改。 - 方法上的注解优先于类上注解。
- DS支持继承抽象类上的DS,暂不支持继承接口上的DS。
3. 准备操作
以 mysql 为例进行演示说明,因为需要多数据源,一个最简单的 case 就是一个物理库上多个逻辑库,本文是基于本机的 mysql 进行操作。
创建数据库demo
与 mult_demo
,两个库下都存在一个表mult_druid
(同名同结构表,但是数据不同哦)
CREATE TABLE `mult_druid` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名',
`money` int(26) NOT NULL DEFAULT '0' COMMENT '钱',
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
`create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
4. 使用方法
4.1 引入依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
</dependencies>
4.2 配置数据源
spring:
datasource:
#动态数据源
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master: # 这个名字可以任意取
url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
slave_1:
url: jdbc:mysql://localhost:3306/mult_demo?useUnicode=true&characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
#以上会配置一个默认库master,一个字库slave
特殊案例:
# 多主多从 纯粹多库(记得设置primary) 混合配置
spring: spring: spring:
datasource: datasource: datasource:
dynamic: dynamic: dynamic:
datasource: datasource: datasource:
master_1: mysql: master:
master_2: oracle: slave_1:
slave_1: sqlserver: slave_2:
slave_2: postgresql: oracle_1:
slave_3: h2: oracle_2:
4.3 代码编写
相关实体类,mapper,service可以直接使用代码生成器生成。
实体类
@Data
@EqualsAndHashCode(callSuper = true)
public class MultDruid extends Model {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 用户名
*/
private String name;
/**
* 钱
*/
private Integer money;
@TableField("is_deleted")
private Integer isDeleted;
@TableField(value = "create_at")
private Timestamp createAt;
@TableField(value = "update_at")
private Timestamp updateAt;
}
Mapper
public interface MultDruidMapper extends BaseMapper<MultDruid> {
}
service
自行在数据库中添加相关数据。
public interface IMultDruidService extends IService<MultDruid> {
MultDruid findInMaster();
MultDruid findInSalve();
}
public interface IMultDruidService extends IService<MultDruid> {
MultDruid findInMaster();
MultDruid findInSalve();
}
@Service
public class MultDruidServiceImpl extends ServiceImpl<MultDruidMapper, MultDruid> implements IMultDruidService {
@Override
@DS("master")
public MultDruid findInMaster() {
return baseMapper.selectById(1);
}
@Override
@DS("slave_1")
public MultDruid findInSalve() {
return baseMapper.selectById(1);
}
}
请注意上面 Service 的注解@DS
,value 为前面数据源配置文件中的 key(spring.datasource.dynamic.datasource
下面的master
+ salve_1
)
@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解。
注解 | 结果 |
---|---|
没有@DS | 默认数据源 |
@DS(“dsName”) | dsName可以为组名也可以为具体某个库的名称 |
4.4 测试
@SpringBootTest
class SpringbootMybatisPlusDemoApplicationTests {
@Autowired
private IUserService userService;
@Autowired
private IMultDruidService multDruidService;
@Test
void contextLoads() {
System.out.println(userService.list());
}
// 测试动态数据源
@Test
void mult_test() {
System.out.println(multDruidService.findInMaster());
System.out.println(multDruidService.findInSalve());
}
}