SpringBoot整合MybatisPius實(shí)現(xiàn)數(shù)據(jù)庫多數(shù)據(jù)源及讀寫分離

一 . 概述

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:
#           ......
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刻盐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子劳翰,更是在濱河造成了極大的恐慌敦锌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佳簸,死亡現(xiàn)場離奇詭異乙墙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)生均,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門听想,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人马胧,你說我怎么就攤上這事哗魂。” “怎么了漓雅?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長朽色。 經(jīng)常有香客問我邻吞,道長,這世上最難降的妖魔是什么葫男? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任抱冷,我火速辦了婚禮,結(jié)果婚禮上梢褐,老公的妹妹穿的比我還像新娘旺遮。我一直安慰自己,他們只是感情好盈咳,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布耿眉。 她就那樣靜靜地躺著,像睡著了一般鱼响。 火紅的嫁衣襯著肌膚如雪鸣剪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天丈积,我揣著相機(jī)與錄音筐骇,去河邊找鬼。 笑死江滨,一個(gè)胖子當(dāng)著我的面吹牛铛纬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播唬滑,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼告唆,長吁一口氣:“原來是場噩夢啊……” “哼棺弊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起悔详,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤镊屎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后茄螃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缝驳,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年归苍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了用狱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,567評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拼弃,死狀恐怖夏伊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吻氧,我是刑警寧澤溺忧,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站盯孙,受9級特大地震影響鲁森,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜振惰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一歌溉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骑晶,春花似錦痛垛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至羽圃,卻和暖如春乾胶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背朽寞。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工识窿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脑融。 一個(gè)月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓喻频,卻偏偏與公主長得像,于是被迫代替她去往敵國和親肘迎。 傳聞我的和親對象是個(gè)殘疾皇子甥温,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容