一、简介
dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。
其支持 Jdk 1.7+, SpringBoot 1.4.x 1.5.x 2.x.x。
二、特性
- 支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
- 支持数据库敏感配置信息 加密 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的分布式事务方案。
- 提供 本地多数据源事务方案。 附:不能和原生spring事务混用。
三、约定
- 本框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何CRUD。
- 配置文件所有以下划线
_分割的数据源 首部 即为组的名称,相同组名称的数据源会放在一个组下。 - 切换数据源可以是组名,也可以是具体数据源名称。组名则切换时采用负载均衡算法切换。
- 默认的数据源名称为 master ,你可以通过
spring.datasource.dynamic.primary修改。 - 方法上的注解优先于类上注解。
- DS支持继承抽象类上的DS,暂不支持继承接口上的DS。
四、使用方法
1、引入dynamic-datasource-spring-boot-starter。(maven-central v3.6.1)
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${version}</version>
</dependency>
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
# 多主多从 纯粹多库(记得设置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:
3、使用 @DS 切换数据源
@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解。
| 注解 | 结果 |
|---|---|
| 没有@DS | 默认数据源 |
| @DS(“dsName”) | dsName可以为组名也可以为具体某个库的名称 |
@Service
@DS("slave")
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、集成Druid
基础介绍
- Druid Github GitHub - alibaba/druid: 阿里云计算平台DataWorks(https://help.aliyun.com/document_detail/137663.html) 团队出品,为监控而生的数据库连接池
- Druid 文档 Home · alibaba/druid Wiki · GitHub
本组件能简单高效完成对Druid的集成并完成其他参数的多元化配置。
提示
1、各个库可以使用不同的数据库连接池,如master使用Druid监控,从库使用HikariCP。
2、如果项目同时存在Druid和HikariCP并且未配置连接池type类型,默认Druid优先于HiKariCP。
如何集成
1、项目引入druid-spring-boot-starter依赖(maven-central v1.2.)
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
2、排除原生Druid的快速配置类
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class RuoYiAuthApplication
{
public static void main(String[] args)
{
SpringApplication.run(RuoYiAuthApplication.class, args);
}
}
3、排除springboot的版本上面可能无法排除可用以下方式排除。
spring:
autoconfigure:
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
参数配置
1、如果参数都未配置,则保持原组件默认值。
2、如果配置了全局参数,则每一个数据源都会继承对应参数。
3、每一个数据源可以单独设置参数覆盖全局参数。
spring:
datasource:
druid:
stat-view-servlet:
enabled: true
loginUsername: admin
loginPassword: 123456
dynamic:
druid:
initial-size:
max-active:
min-idle:
max-wait:
time-between-eviction-runs-millis:
time-between-log-stats-millis:
stat-salmax-size:
min-evictable-idle-time-millis:
max-evictable-idle-time-millis:
test-while-idle:
test-on-borrow:
test-on-return:
validation-query:
validation-query-timeout:
use-global-datasource-stat:
async-init:
clear-filters-enable:
reset-stat-enable:
not-full-timeout-retry-count:
max-wait-thread-count:
fail-fast:
phyTimeout-millis:
keep-alive:
pool-prepared-statements:
init-variants:
init-global-variants:
use-unfair-lock:
kil1-when-socket-read-timeout:
connection-properties:
max-pool-prepared-statement-per-connection-size:init-connection-sqls:
share-prepared-statements:
connection-errorretry-attempts:
break-after-acquire-failure:
filters: stat,wall # 注意这个值和druid原生不一致,默认启动了stat,wall
wall:
noneBaseStatementAllow:
callAllow:
selectAllow:
selectIntoAllow:
selectInto0utfileAllow:
selectwhereAlwayTrueCheck:
selectHavingAlwayTrueCheck:
selectUnionCheck:
selectminusCheck:
selectExceptCheck:
selectIntersectCheck:
createTableAllow:
dropTableAllow:
alterTableAllow:
renameTableAllow:
hintAllow:
lockTableAllow:
startTransactionAllow:blockAllow:
conditionAndAlwayTrueAllow:
conditionAndAlwayFalseAllow:
conditionDoubleConstAllow:
conditionLikeTrueAllow:
selectAllColumnAllow:
deleteAllow:deletewhereAlwayTrueCheck:
deletewhereNoneCheck:
updateAllow:
updatewhereAlayTrueCheck:
updatewhereNonecheck:
insertAllow:
mergeAllow:
minusAllow:
intersectAllow:
replaceAllow:
setAllow:
commitAllow:
rollbackAllow:
useAllow:
multistatementAllow:
truncateAllow:
commentAllow:
strictsyntaxCheck:
constArithmeticAllow:
limitZeroAllow:
describeAl1ow:showAllow:
schemaCheck:
tableCheck:
functionCheck:
objectCheck:
variantCheck:
mustParameterized:
doPrivilegedAllow:
dir:
tenantTablePattern:
tenantColumn:
wrapAllow:
metadataAllow:
conditionOpXorAllow:
conditionOpBitwseAllow:
caseConditionConstAllow:
completeInsertValuesCheck:
insertValuesChecksize:
selectLimit:
stat:
merge-sq1:
og-slow-5q1:
slow-sql-millis:
datasource:
# 主库数据源
master:
driver-class-name:
url:
username:
password:
druid: # 以下是独立参数,每个库可以重新设置
initial-size:
validation-query: select 1 from dual #比如oracle就需要重新设置这个
public-key: #(非全局参数)设置即表示启动加密,底层会自动帮你配置相关的连接参数
......
#生成publickey和密码,推荐使用本项目自带的加密方法
#java -cp druid-1.1.10.jar com.alibaba.druid.filter.config.ConfigTools youpassword
# 从库数据源
# slave:
# username:
# password:
# url:
# driver-class-name:
如下即可配置访问用户和密码,访问http://localhost:8080/druid/index.html查看druid监控
六、若依多数据源
1、引入ruoyi-common-datasource模块
引入相关依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- Dynamic DataSource -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-ds.version}</version>
</dependency>
创建注解
主库数据源只有一个,从库数据源可以配置多个(目前只有一个从库数据源,且从库数据源的名称为slave)
package com.ruoyi.common.datasource.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.baomidou.dynamic.datasource.annotation.DS;
/**
* 主库数据源
*
* @author ruoyi
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@DS("master")
public @interface Master
{
}
package com.ruoyi.common.datasource.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.baomidou.dynamic.datasource.annotation.DS;
/**
* 从库数据源
*
* @author ruoyi
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@DS("slave")
public @interface Slave
{
}
2、ruoyi-system模块使用
ruoyi-system-dev.yml
# spring配置
spring:
redis:
host: localhost
port: 6379
password:
datasource:
druid:
stat-view-servlet:
enabled: true
loginUsername: admin
loginPassword: 123456
dynamic:
druid:
initial-size: 5
min-idle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
filters: stat,slf4j
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
# 主库数据源
master:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: admin0625
# 从库数据源
slave:
username: root
password: admin0625
url: jdbc:mysql://localhost:3306/ry-test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
# seata: true # 开启seata代理,开启后默认每个数据源都代理,如果某个不需要代理可单独关闭
# seata配置
seata:
# 默认关闭,如需启用spring.datasource.dynami.seata需要同时开启
enabled: false
# Seata 应用编号,默认为 ${spring.application.name}
application-id: ${spring.application.name}
# Seata 事务组编号,用于 TC 集群名
tx-service-group: ${spring.application.name}-group
# 关闭自动代理
enable-auto-data-source-proxy: false
# 服务配置项
service:
# 虚拟组和分组的映射
vgroup-mapping:
ruoyi-system-group: default
config:
type: nacos
nacos:
serverAddr: 127.0.0.1:8848
group: SEATA_GROUP
namespace:
registry:
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
namespace:
# mybatis配置
mybatis:
# 搜索指定包别名
typeAliasesPackage: com.ruoyi.system
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath:mapper/**/*.xml
# swagger配置
swagger:
title: 系统模块接口文档
license: Powered By ruoyi
licenseUrl: https://ruoyi.vip
修改SysConfigController
/**
* @Slave注解为从库数据源的注解,也可替换为@DS("slave")
* 自动切换数据源使用@Slave注解
* 手动切换数据源比如根据参数不同切换数据源,使用DynamicDataSourceContextHolder.push("slave");及DynamicDataSourceContextHolder.clear();方法
*/
@GetMapping(value = "/{configId}")
//@Slave
public AjaxResult getInfo(@PathVariable Long configId)
{
SysConfig config=new SysConfig();
config.setConfigId(configId);
if (configId==1){
DynamicDataSourceContextHolder.push("slave");
config=configService.selectConfigById(configId);
DynamicDataSourceContextHolder.clear();
return AjaxResult.success(config);
}
return AjaxResult.success(configService.selectConfigById(configId));
}
public AjaxResult getInfo(@PathVariable Long configId)
{
SysConfig config=new SysConfig();
config.setConfigId(configId);
if (configId==1){
DynamicDataSourceContextHolder.push("slave");
config=configService.selectConfigById(configId);
DynamicDataSourceContextHolder.clear();
return AjaxResult.success(config);
}
return AjaxResult.success(configService.selectConfigById(configId));
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HAKMxX5Z-1680335578059)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
dynamic-datasource-spring-boot-starter 是一个用于快速集成多数据源的启动器,支持Jdk 1.7+和SpringBoot 1.4.x到2.x.x。特性包括数据源分组、敏感信息加密、自定义注解和动态增加移除数据源等。该框架提供了Druid等连接池的集成,以及Mybatis-Plus等组件的解决方案。使用方法包括引入依赖、配置数据源和使用@DS注解进行数据源切换。
3022

被折叠的 条评论
为什么被折叠?



