一 . 概述
dynamic-datasource的具體介紹請查看dynamic-datasource官網(wǎng)
dynamic-datasource-spring-boot-starter 是一個(gè)基于springboot的快速集成多數(shù)據(jù)源的啟動(dòng)器绳矩。其支持 Jdk 1.7+, SpringBoot 1.4.x 1.5.x 2.0.x旺聚。
1.1 特性
- 數(shù)據(jù)源分組灵莲,適用于多種場景 純粹多庫 讀寫分離 一主多從 混合模式。
- 內(nèi)置敏感參數(shù)加密和啟動(dòng)初始化表結(jié)構(gòu)schema數(shù)據(jù)庫database宏粤。
- 提供對Druid,Mybatis-Plus叼架,P6sy柠逞,Jndi的快速集成。
- 簡化Druid和HikariCp配置璧亮,提供全局參數(shù)配置萧诫。
- 提供自定義數(shù)據(jù)源來源接口(默認(rèn)使用yml或properties配置)。
- 提供項(xiàng)目啟動(dòng)后增減數(shù)據(jù)源方案杜顺。
- 提供Mybatis環(huán)境下的 純讀寫分離 方案财搁。
- 使用spel動(dòng)態(tài)參數(shù)解析數(shù)據(jù)源,如從session躬络,header或參數(shù)中獲取數(shù)據(jù)源尖奔。(多租戶架構(gòu)神器)
- 提供多層數(shù)據(jù)源嵌套切換。(ServiceA >>> ServiceB >>> ServiceC,每個(gè)- - Service都是不同的數(shù)據(jù)源)
- 提供 不使用注解 而 使用 正則 或 spel 來切換數(shù)據(jù)源方案(實(shí)驗(yàn)性功能)提茁。
1.2 約定
- 本框架只做 切換數(shù)據(jù)源 這件核心的事情淹禾,并不限制你的具體操作,切換了- - 數(shù)據(jù)源可以做任何CRUD茴扁。
- 配置文件所有以下劃線 _ 分割的數(shù)據(jù)源 首部 即為組的名稱铃岔,相同組名稱的- - 數(shù)據(jù)源會(huì)放在一個(gè)組下。
- 切換數(shù)據(jù)源可以是組名峭火,也可以是具體數(shù)據(jù)源名稱毁习。組名則切換時(shí)采用負(fù)載均衡算法切換。
- 默認(rèn)的數(shù)據(jù)源名稱為 master 卖丸,你可以通過 spring.datasource.dynamic.primary 修改纺且。
- 方法上的注解優(yōu)先于類上注解。
二 . spring-boot整合
2.1 步驟一: 導(dǎo)入工具包
<!-- 導(dǎo)入配置文件處理器-->
<!-- 動(dòng)態(tài)數(shù)據(jù)庫連接包-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>2.5.6</version>
</dependency>
2.2 yml配置
spring:
datasource:
dynamic:
primary: master #設(shè)置默認(rèn)的數(shù)據(jù)源或者數(shù)據(jù)源組,默認(rèn)值即為master
strict: false #設(shè)置嚴(yán)格模式,默認(rèn)false不啟動(dòng). 啟動(dòng)后在未匹配到指定數(shù)據(jù)源時(shí)候回拋出異常,不啟動(dòng)會(huì)使用默認(rèn)數(shù)據(jù)源.
datasource:
master:
url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
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) # 內(nèi)置加密,使用請查看詳細(xì)文檔
username: ENC(xxxxx)
password: ENC(xxxxx)
driver-class-name: com.mysql.jdbc.Driver
schema: db/schema.sql # 配置則生效,自動(dòng)初始化表結(jié)構(gòu)
data: db/data.sql # 配置則生效,自動(dòng)初始化數(shù)據(jù)
continue-on-error: true # 默認(rèn)true,初始化失敗是否繼續(xù)
separator: ";" # sql默認(rèn)分號分隔符
#......省略
#以上會(huì)配置一個(gè)默認(rèn)庫master稍浆,一個(gè)組slave下有兩個(gè)子庫slave_1,slave_2
其他主從方式配置模板
# 多主多從 純粹多庫(記得設(shè)置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:
2.3 數(shù)據(jù)源切換使用
@DS 可以注解在方法上和類上载碌,同時(shí)存在方法注解優(yōu)先于類上注解。
強(qiáng)烈建議只注解在service實(shí)現(xiàn)上衅枫。
注解 | 結(jié)果 |
---|---|
沒有@DS | 默認(rèn)數(shù)據(jù)源 |
@DS("dsName") | dsName可以為組名也可以為具體某個(gè)庫的名稱 |
示例
在service實(shí)現(xiàn)層
@Service
@DS("slave")
public class UserServiceImpl implements UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<Map<String, Object>> selectAll() {
return jdbcTemplate.queryForList("select * from user");
}
@Override
@DS("slave_1")
public List<Map<String, Object>> selectByCondition() {
return jdbcTemplate.queryForList("select * from user where age >10");
}
}
三. 第三方繼承
3.1 集成Druid
springBoot2.x默認(rèn)使用HikariCP嫁艇,但在國內(nèi)Druid的使用者非常龐大,此項(xiàng)目特地對其進(jìn)行了適配弦撩,完成多數(shù)據(jù)源下使用Druid進(jìn)行監(jiān)控步咪。
注意 :主從可以使用不同的數(shù)據(jù)庫連接池,如 master使用Druid監(jiān)控孤钦,從庫使用HikariCP歧斟。如果不配置連接池type類型,默認(rèn)是 Druid優(yōu)先于HikariCP 偏形。
3.1.1 項(xiàng)目引入 druid-spring-boot-starter 依賴
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
3.1.2 排除 原生Druid的快速配置類静袖。
@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
某些springBoot的版本上面可能無法排除(嘗試使用以下方式排除)
spring:
autoconfigure:
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
- 為什么要排除DruidDataSourceAutoConfigure ?
DruidDataSourceAutoConfigure會(huì)注入一個(gè)DataSourceWrapper俊扭,其會(huì)在原生的spring.datasource下找url,username,password等队橙。而我們動(dòng)態(tài)數(shù)據(jù)源的配置路徑是變化的。
3.1.2 YML配置
spring:
datasource:
druid:
stat-view-servlet:
enabled: true
url-pattern: /druid/*
# 是否可以使用重置功能
reset-enable: false
login-username: admin
login-password: admin
# 允許訪問的id
allow: 127.0.0.1
# 和名單
deny: ""
dynamic:
druid: #以下是全局默認(rèn)值萨惑,可以全局更改
# druid 配置
# 初始化連接數(shù)
initial-size: 5
# 最大連接數(shù)
max-active: 10
# 最少連接數(shù)
min-idle: 3
# 配置監(jiān)控統(tǒng)計(jì)攔截器 日志配置 Slf4j logback
# stat 監(jiān)控?cái)?shù)據(jù)庫性能
# wall 用于防火墻
# 日志先關(guān) slf4j logback log4j log4j2
filters: stat,wall,slf4j
web-stat-filter:
enabled: true
url-pattern: /*
# 排除不攔截的 請求
exclusions: "*.js,/druid/*"
datasource:
master:
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://106.13.221.151:3316/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
druid: # 以下參數(shù)針對每個(gè)庫可以重新設(shè)置druid參數(shù)
initial-size: 5
validation-query: select 1 FROM DUAL #比如oracle就需要重新設(shè)置這個(gè)
public-key: #(非全局參數(shù))設(shè)置即表示啟用加密,底層會(huì)自動(dòng)幫你配置相關(guān)的連接參數(shù)和filter捐康。
slave_1:
username: ****
password: ****
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://106.13.221.151:3317/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
druid:
# druid 配置
# 初始化連接數(shù)
initial-size: 5
# 最大連接數(shù)
max-active: 10
# 最少連接數(shù)
min-idle: 3
程序入口開啟mappe掃描
@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
@MapperScan("com.example.demo.mapper")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
3.2 集成HikariCP
HikariCP官方地址
SpringBoot 2.+ 默認(rèn)引入了HikariCP,除非對版本有要求無需再次引入庸蔼。
使用SpringBoot 1.5.x的版本需手動(dòng)引入解总,對應(yīng)的版本請根據(jù)自己環(huán)境和HikariCP官方地址自行選擇。
3.2.1 YML配置
spring:
datasource:
dynamic:
hikari: # 全局hikariCP參數(shù)姐仅,所有值和默認(rèn)保持一致花枫。(現(xiàn)已支持的參數(shù)如下,不清楚含義不要亂設(shè)置)
catalog:
connection-timeout:
validation-timeout:
idle-timeout:
leak-detection-threshold:
max-lifetime:
max-pool-size:
min-idle:
initialization-fail-timeout:
connection-init-sql:
connection-test-query:
dataSource-class-name:
dataSource-jndi-name:
schema:
transaction-isolation-name:
is-auto-commit:
is-read-only:
is-isolate-internal-queries:
is-register-mbeans:
is-allow-pool-suspension:
data-source-properties: #以下屬性僅為演示(默認(rèn)不會(huì)引入)
serverTimezone: Asia/Shanghai
characterEncoding: utf-8
useUnicode: true
useSSL: false
autoReconnect: true
cachePrepStmts: true
prepStmtCacheSize: 250
prepStmtCacheSqlLimit: 2048
useServerPrepStmts: true
useLocalSessionState: true
rewriteBatchedStatements: true
cacheResultSetMetadata: true
cacheServerConfiguration: true
elideSetAutoCommits: true
maintainTimeStats: false
allowPublicKeyRetrieval: true
health-check-properties:
datasource:
master:
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic?characterEncoding=utf8&useSSL=false
hikari: # 以下參數(shù)針對每個(gè)庫可以重新設(shè)置hikari參數(shù)
max-pool-size:
idle-timeout:
# ......