前言:本內容主要是按照mybatis-plus官方文檔實現。官網地址:https://mp.baomidou.com
優勢
網上關於動態數據源的切換的文檔有很多,核心只有兩種。
- 構建多套環境,優勢是方便控制也容易集成一些簡單的分佈式事務,缺點是非動態同時代碼量較多,配置難度大。
- 基於spring提供原生的
AbstractRoutingDataSource
,參考一些文檔自己實現切換。
如果你的數據源較少,場景不復雜,選擇以上任意一種都可以。如果你需要更多特性,請嘗試本動態數據源。
- 數據源分組,適用於多種場景 純粹多庫 讀寫分離 一主多從 混合模式。
- 簡單集成Druid數據源監控多數據源,簡單集成Mybatis-Plus簡化單表,簡單集成P6sy格式化sql,簡單集成Jndi數據源。
- 簡化Druid和HikariCp配置,提供全局參數配置。
- 提供自定義數據源來源(默認使用yml或properties配置)。
- 項目啓動後能動態增減數據源。
- 使用spel動態參數解析數據源,如從session,header和參數中獲取數據源。(多租戶架構神器)
- 多層數據源嵌套切換。(一個業務ServiceA調用ServiceB,ServiceB調用ServiceC,每個Service都是不同的數據源)
- 使用正則匹配或spel表達式來切換數據源(實驗性功能)。
#劣勢
不能使用多數據源事務(同一個數據源下能使用事務),網上其他方案也都不能提供。
如果你需要使用到分佈式事務,那麼你的架構應該到了微服務化的時候了。
如果呼聲強烈,項目達到800 star,作者考慮集成分佈式事務。
PS: 如果您只是幾個數據庫但是有強烈的需求分佈式事務,建議還是使用傳統方式自己構建多套環境集成atomic這類,網上百度很多。
#約定
- 本框架只做 切換數據源 這件核心的事情,並不限制你的具體操作,切換了數據源可以做任何CRUD。
- 配置文件所有以下劃線
_
分割的數據源 首部 即爲組的名稱,相同組名稱的數據源會放在一個組下。 - 切換數據源即可是組名,也可是具體數據源名稱,切換時默認採用負載均衡機制切換。
- 默認的數據源名稱爲 master ,你可以通過spring.datasource.dynamic.primary修改。
- 方法上的註解優先於類上註解。
#建議
強烈建議在 主從模式 下遵循普遍的規則,以便他人能更輕易理解你的代碼。
主數據庫 建議 只執行 INSERT
UPDATE
DELETE
操作。
從數據庫 建議 只執行 SELECT
操作。
#使用方法
引入依賴:
<properties>
<java.version>1.8</java.version>
<mybatis-plus.version>3.0.5</mybatis-plus.version>
<velocity.version>2.0</velocity.version>
</properties>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- velocity 模板引擎, Mybatis Plus 代碼生成器需要 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!--開發者工具-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!--mybatis-plus 持久層-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!--添加tomcat-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
主要是這個依賴:dynamic-datasource-spring-boot-starter<
接下來看看我的的配置文件:如果想配置多主多從,或者純粹多庫,混合配置的話,可以參考官網配置:https://mp.baomidou.com/guide/dynamic-datasource.html
# 服務端口
server.port=8099
# 服務名
spring.application.name=test
# 環境設置:dev、test、prod
spring.profiles.active=dev
# mysql數據庫連接
spring.datasource.dynamic.primary=mysql
spring.datasource.dynamic.datasource.mysql.username=root
spring.datasource.dynamic.datasource.mysql.password=xxx
spring.datasource.dynamic.datasource.mysql.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.dynamic.datasource.mysql.url=jdbc:mysql://122.51.97.164:3306/jk?useSSL=false&serverTimezone=UTC
spring.datasource.dynamic.datasource.slave_1.username=root
spring.datasource.dynamic.datasource.slave_1.password=xxxx
spring.datasource.dynamic.datasource.slave_1.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.dynamic.datasource.slave_1.url=jdbc:mysql://127.0.0.1:3306/travel?useSSL=false&serverTimezone=UTC
#mybatis日誌
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#返回json的全局時間格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
#spring.jackson.time-zone=GMT+8
接下來,我們看看我的數據表,我的數據表很簡單,就是兩個特別簡單的表。
就是這兩個表
下面貼出這兩個實體類的代碼
public class Ss {
Integer id;
String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Ss{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
public class Tt {
Integer id;
String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Tt{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
還有兩個mapper的代碼
public interface SsMapper extends BaseMapper<Ss> {
}
public interface TtMapper extends BaseMapper<Tt> {
}
然後是兩個service的代碼,裏面的方法就是簡單的全部查詢。
public interface SsService extends IService<Ss> {
List<Ss> info();
}
public interface TtService extends IService<Tt> {
List<Tt> info();
}
兩個impl的代碼
@Service
@DS("mysql")
public class SsServiceImpl extends ServiceImpl<SsMapper, Ss> implements SsService {
@Autowired
private SsMapper ssMapper;
@Override
public List<Ss> info() {
List<Ss> sses = ssMapper.selectList(null);
return sses;
}
}
@Service
@DS("slave_1")
public class TtServiceImpl extends ServiceImpl<TtMapper, Tt> implements TtService {
@Autowired
private TtMapper ttMapper;
@Override
public List<Tt> info() {
List<Tt> tts = ttMapper.selectList(null);
return tts;
}
}
這裏我們實現動態數據源,主要就是用得到@DS註解。
下面是我從官網拷貝來的
使用 @DS 切換數據源。
@DS 可以註解在方法上和類上,同時存在方法註解優先於類上註解。
註解在service實現或mapper接口方法上,但強烈不建議同時在service和mapper註解。 (可能會有問題)
註解 結果
沒有@DS 默認數據源
@DS("dsName") dsName可以爲組名也可以爲具體某個庫的名稱
就是@DS裏面寫自己在配置文件中的數據庫,配置文件中可以配置很多數據源,都像我的impl裏面的添加註解就行
ok!到此我們就算簡單實現了動態數據源的配置,接下來我們就測試一下吧。
我麼寫兩個test方法
@Test
public void contextLoads() {
List<Tt> info = ttService.info();
System.out.println(info);
}
@Test
public void contextLoad() {
List<Ss> info = ssService.info();
System.out.println(info);
}
執行第一個測試方法
測試第二個測試方法。
怎麼樣,是不是超級簡單就實現了動態數據源,相比傳統的aop實現動態數據源,這樣是不是超級簡單?
我們這樣就實現了多個數據庫查詢數據,簡單實現了動態數據源。在這裏我們多感謝mybatis-plus開發人員,給我們提供了這麼好的開發工具,真的是幫我們解決了很多開發中繁瑣的事情。
如果有問題的話,歡迎給我留言。
相關代碼在github上:https://github.com/Wujungang/more-datasources.git