使用mybatis-plus超級簡單是實現動態數據源,整合mybatis-plus和dynamic-datasource-spring-boot-starter,

前言:本內容主要是按照mybatis-plus官方文檔實現。官網地址:https://mp.baomidou.com

優勢

網上關於動態數據源的切換的文檔有很多,核心只有兩種。

  1. 構建多套環境,優勢是方便控制也容易集成一些簡單的分佈式事務,缺點是非動態同時代碼量較多,配置難度大。
  2. 基於spring提供原生的 AbstractRoutingDataSource ,參考一些文檔自己實現切換。

如果你的數據源較少,場景不復雜,選擇以上任意一種都可以。如果你需要更多特性,請嘗試本動態數據源。

  1. 數據源分組,適用於多種場景 純粹多庫 讀寫分離 一主多從 混合模式。
  2. 簡單集成Druid數據源監控多數據源,簡單集成Mybatis-Plus簡化單表,簡單集成P6sy格式化sql,簡單集成Jndi數據源。
  3. 簡化Druid和HikariCp配置,提供全局參數配置。
  4. 提供自定義數據源來源(默認使用yml或properties配置)。
  5. 項目啓動後能動態增減數據源。
  6. 使用spel動態參數解析數據源,如從session,header和參數中獲取數據源。(多租戶架構神器)
  7. 多層數據源嵌套切換。(一個業務ServiceA調用ServiceB,ServiceB調用ServiceC,每個Service都是不同的數據源)
  8. 使用正則匹配或spel表達式來切換數據源(實驗性功能)。

#劣勢

不能使用多數據源事務(同一個數據源下能使用事務),網上其他方案也都不能提供。

如果你需要使用到分佈式事務,那麼你的架構應該到了微服務化的時候了。

如果呼聲強烈,項目達到800 star,作者考慮集成分佈式事務。

PS: 如果您只是幾個數據庫但是有強烈的需求分佈式事務,建議還是使用傳統方式自己構建多套環境集成atomic這類,網上百度很多。

#約定

  1. 本框架只做 切換數據源 這件核心的事情,並不限制你的具體操作,切換了數據源可以做任何CRUD。
  2. 配置文件所有以下劃線 _ 分割的數據源 首部 即爲組的名稱,相同組名稱的數據源會放在一個組下。
  3. 切換數據源即可是組名,也可是具體數據源名稱,切換時默認採用負載均衡機制切換。
  4. 默認的數據源名稱爲 master ,你可以通過spring.datasource.dynamic.primary修改。
  5. 方法上的註解優先於類上註解。

#建議

強烈建議在 主從模式 下遵循普遍的規則,以便他人能更輕易理解你的代碼。

主數據庫 建議 只執行 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章