Springboot 整合Mybatis多數(shù)據(jù)源并動態(tài)切換

首先需要建立兩個庫進行測試教硫,我這里使用的是master_test和slave_test兩個庫厕怜,兩張庫都有一張同樣的表(偷懶)惶傻,表名 t_user

字段名 類型 備注
id int 主鍵自增ID
name varchar 名稱



表中分別添加兩條不同數(shù)據(jù)谨设,方便測試 主數(shù)據(jù)庫記錄name為xiaobin割粮,從庫為xiaoliu袁铐。
目錄結(jié)構(gòu)



開始使用Springboot 整合mybatis刊咳,首先引入pom文件秘遏。
   <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.1.4.RELEASE</version>
   </parent>
   <groupId>com.xiaobin</groupId>
   <artifactId>mysql_master_slave</artifactId>
   <version>1.0-SNAPSHOT</version>

   <properties>
       <java.version>1.8</java.version>
       <lombok.version>1.18.6</lombok.version>
       <mybatis.version>1.3.2</mybatis.version>
       <lombox.version>1.18.6</lombox.version>
   </properties>

   <dependencies>
       <!-- 添加web啟動坐標 -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <!-- 添加lombok工具坐標 -->
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <version>${lombok.version}</version>
       </dependency>
       <!-- 添加springboot 測試坐標 -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
       </dependency>
       <!-- 添加lombox 測試坐標 -->
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <version>${lombox.version}</version>
       </dependency>
       <!-- 添加mybatis依賴坐標 -->
       <dependency>
           <groupId>org.mybatis.spring.boot</groupId>
           <artifactId>mybatis-spring-boot-starter</artifactId>
           <version>${mybatis.version}</version>
       </dependency>
       <!-- 添加mysql驅(qū)動器坐標 -->
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-jdbc</artifactId>
       </dependency>
       <!-- 添加druid數(shù)據(jù)源坐標 -->
       <dependency>
           <groupId>com.alibaba</groupId>
           <artifactId>druid-spring-boot-starter</artifactId>
           <version>1.1.10</version>
       </dependency>
       <!-- 添加AOP坐標 -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-aop</artifactId>
       </dependency>

   </dependencies>
</project>

動態(tài)數(shù)據(jù)源配置

這里使用的數(shù)據(jù)源為druid蛛勉,實現(xiàn)數(shù)據(jù)源之間的切換用@DataSource自定義注解鹿寻,配置Aop進行切換 application.yml 配置文件。

spring:
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        druid:
          xiaobin-master: # 主數(shù)據(jù)源
            driverClassName: com.mysql.jdbc.Driver
            username: root
            password: root
            url: jdbc:mysql://localhost:3306/master_test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8
          xiaobin-slave: # 從數(shù)據(jù)源
            driverClassName: com.mysql.jdbc.Driver
            username: root
            password: root
            url: jdbc:mysql://localhost:3306/slave_test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8
mybatis:
 mapper-locations: classpath:mapper/*.xml

多數(shù)據(jù)源配置類

@Configuration
@Component
public class DynamicDataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.druid.xiaobin-master")
    public DataSource  xiaobinMasterDataSource(){
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.druid.xiaobin-slave")
    public DataSource  xiaobinSlaveDataSource(){
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public DynamicDataSource dataSource(DataSource xiaobinMasterDataSource, DataSource xiaobinSlaveDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("xiaobin-master",xiaobinMasterDataSource);
        targetDataSources.put("xiaobin-slave", xiaobinSlaveDataSource);
        return new DynamicDataSource(xiaobinMasterDataSource, targetDataSources);
    }
}

動態(tài)數(shù)據(jù)源切換類

public class DynamicDataSource  extends AbstractRoutingDataSource {

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return getDataSource();
    }

    public static void setDataSource(String dataSource) {
        contextHolder.set(dataSource);
    }

    public static String getDataSource() {
        return contextHolder.get();
    }

    public static void clearDataSource() {
        contextHolder.remove();
    }
}

自定義@DataSource注解
在需要切換數(shù)據(jù)的Dao添加此注解

/**
 * 備注:自定義數(shù)據(jù)源選擇注解
 **/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    String name() default "";
}

Aop切面類配置

@Aspect
@Component
public class DataSourceAspect {

    @Pointcut("@annotation(com.xiaobin.annotation.DataSource)")
    public void dataSourcePointCut() {

    }

    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();

        DataSource dataSource = method.getAnnotation(DataSource.class);
        if(dataSource == null){
            DynamicDataSource.setDataSource("xiaobin-master");
        }else {
            DynamicDataSource.setDataSource(dataSource.name());
        }

        try {
            return point.proceed();
        } finally {
            DynamicDataSource.clearDataSource();
        }
    }
}

啟動配置注解信息诽凌,重要(不然運行會報錯)

@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
@MapperScan(basePackages = "com.xiaobin.mapper")
@Import({DynamicDataSourceConfig.class})
public class StartApp {
    public static void main(String[] args) {
        SpringApplication.run(StartApp.class);
    }
}
測試controller

@RestController
@RequestMapping
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @GetMapping("/{name}/list")
    public List<TUser> list(@PathVariable("name")String name){
        if(name.equals("master")){
            return userMapper.queryAllWithMaster();
        }else{
            return userMapper.queryAllWithSlave();
        }
    }
}

效果圖

更具路徑傳值毡熏,進行主從數(shù)據(jù)源切換



?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市侣诵,隨后出現(xiàn)的幾起案子痢法,更是在濱河造成了極大的恐慌恬试,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疯暑,死亡現(xiàn)場離奇詭異训柴,居然都是意外死亡,警方通過查閱死者的電腦和手機妇拯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進店門幻馁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人越锈,你說我怎么就攤上這事仗嗦。” “怎么了甘凭?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵稀拐,是天一觀的道長。 經(jīng)常有香客問我丹弱,道長德撬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任躲胳,我火速辦了婚禮蜓洪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘坯苹。我一直安慰自己隆檀,他們只是感情好,可當我...
    茶點故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布粹湃。 她就那樣靜靜地躺著恐仑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪为鳄。 梳的紋絲不亂的頭發(fā)上裳仆,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天,我揣著相機與錄音济赎,去河邊找鬼鉴逞。 笑死,一個胖子當著我的面吹牛司训,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播液南,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼壳猜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了滑凉?” 一聲冷哼從身側(cè)響起统扳,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤喘帚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后咒钟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吹由,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年朱嘴,在試婚紗的時候發(fā)現(xiàn)自己被綠了倾鲫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡萍嬉,死狀恐怖乌昔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情壤追,我是刑警寧澤磕道,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站行冰,受9級特大地震影響溺蕉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜悼做,卻給世界環(huán)境...
    茶點故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一焙贷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贿堰,春花似錦辙芍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至纵搁,卻和暖如春吃衅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背腾誉。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工徘层, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人利职。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓趣效,卻偏偏與公主長得像,于是被迫代替她去往敵國和親猪贪。 傳聞我的和親對象是個殘疾皇子跷敬,可洞房花燭夜當晚...
    茶點故事閱讀 44,665評論 2 354

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

  • MyBatis多數(shù)據(jù)源切換 項目結(jié)構(gòu)為: 項目相關(guān)依賴pom.xml: 1、配置文件application.yml...
    zenghi閱讀 13,082評論 5 13
  • 多數(shù)據(jù)源跳庫組件及分析 連接池介紹 多數(shù)據(jù)源使用 多數(shù)據(jù)源應用場景 多數(shù)據(jù)源配置spring + druid 多數(shù)...
    朱萬宇閱讀 7,400評論 2 9
  • 文:‖18歲的小仙女 這是一臺有故事的小風扇热押。 2016年那年西傀,6月15號斤寇,快要踏進七月狂熱的地域,外訓了拥褂。 駐扎...
    Visby閱讀 475評論 3 1
  • 下雪前網(wǎng)購的瑜伽墊今天終于到貨了娘锁。 送你去輔導班回來,爸爸來電話說不回來吃晚飯了饺鹃,也不能去接你下課了莫秆,我雖然嘴上沒...
    素面迎風閱讀 79評論 0 0
  • 這個哥們是我初中同學, 我們當時很要好尤慰, 相當于一起經(jīng)歷過叛逆的伙伴馏锡, 大概有十來年沒見了, 樣子其實都有了變化伟端,...
    玖月的喵閱讀 156評論 0 1