分享一个优秀的动态数据源开源库-dynamic-datasource-spring-boot-starter
- 1.1 前言
- 1.2 动态数据源开源库简介
- 1.3 特性
- 1.4 用法示例
- 1.4.1 添加依赖
- 1.4.2 配置数据源
- 1.4.3 使用 `@DS` 注解切换数据源
- 1.5 最佳实践
1.1 前言
在我们的Java后端研发工作中, 有时候由于业务的快速迭代和数据的安全隔离性,往往会为不同的 API业务线分配不同的数据库,即一个微服务经常需要和多个数据源打交道。
1.2 动态数据源开源库简介
dynamic-datasource-spring-boot-starter
是一个基于springboot的快速集成多数据源的启动器。- 其支持 Jdk 1.7+, SpringBoot 1.5.x 2.x.x 3.x.x。
- 点击查看详细文档
PS: 一般免费的文档部分就够用了,不需付费
1.3 特性
- 支持 数据源分组,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
- 支持数据库敏感配置信息 加密(可自定义) 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的分布式事务方案 。
- 提供 本地多数据源事务方案。
优点:功能强大,使用简洁,配合 mybatis plus 更能如虎添翼。
1.4 用法示例
1.4.1 添加依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.6.0</version>
</dependency>
查看最新版本
1.4.2 配置数据源
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master:
url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
slave_1:
url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
slave_2:
url: ENC(xxxxx) # 内置加密,使用请查看详细文档
username: ENC(xxxxx)
password: ENC(xxxxx)
driver-class-name: com.mysql.jdbc.Driver
#......省略
#以上会配置一个默认库master,一个组slave下有两个子库slave_1,slave_2
1.4.3 使用 @DS
注解切换数据源
虽然官网示例在 service层
@Service
@DS("slave_1")
public class UserServiceImpl implements UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
public List selectAll() {
return jdbcTemplate.queryForList("select * from user");
}
@Override
@DS("slave_1")
public List selectByCondition() {
return jdbcTemplate.queryForList("select * from user where age >10");
}
}
1.5 最佳实践
我建议使用在 Dao 层上,比如如下是我项目脱敏抽离出来的一个示例:
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
/***
* @author qingfeng.zhao
* @date 2022/4/27
* @apiNote
*/
@DS(value = "default-datasource")
@Mapper
@Repository
public interface VueElementAdminUserRoleMapper extends BaseMapper<VueElementAdminUserRoleEntity> {
}
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@DS(value = "second-data-source")
@Repository
@Mapper
public interface MyProductMapper extends BaseMapper<MyProductInfoEntity> {
}
spring:
application:
name: xxxxxxx
# 动态数据源 dynamic-datasource-spring-boot-starter
datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为master
primary: default-datasource
# 严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
default-datasource:
url: jdbc:mysql://192.168.xxx.xxx:3306/myFirstDb?serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8
username: xxxxxx
password: xxxxxx
driver-class-name: com.mysql.cj.jdbc.Driver
second-data-source:
url: jdbc:mysql://192.168.xxx.xxx:3306/mySecondDb?serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8
username: xxxxxx
password: xxxxxx
driver-class-name: com.mysql.cj.jdbc.Driver
@DS
注解的数据源名称需在application.yml 中配置
本篇完~