欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

帶你了解mybatis如何實(shí)現(xiàn)讀寫分離

 更新時(shí)間:2021年08月04日 10:44:12   作者:alexander137  
本篇文章主要介紹了MyBatis實(shí)現(xiàn)數(shù)據(jù)讀寫分離的實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能給你帶來幫助

1、spring aop實(shí)現(xiàn)

首先application-test.yml增加如下數(shù)據(jù)源的配置

spring:
  datasource:
    master:
      jdbc-url: jdbc:mysql://master域名:3306/test
      username: root
      password: 123456
      driver-class-name: com.mysql.jdbc.Driver
    slave1:
      jdbc-url: jdbc:mysql://slave域名:3306/test
      username: root   # 只讀賬戶
      password: 123456
      driver-class-name: com.mysql.jdbc.Driver
    slave2:
      jdbc-url: jdbc:mysql://slave域名:3306/test
      username: root   # 只讀賬戶
      password: 123456
      driver-class-name: com.mysql.jdbc.Driver
package com.cjs.example.enums;
public enum DBTypeEnum {
    MASTER, SLAVE1, SLAVE2;
}

定義ThreadLocal上下文,將當(dāng)前線程的數(shù)據(jù)源進(jìn)行動(dòng)態(tài)修改

public class DBContextHolder {
    private static  volatile ThreadLocal<DBTypeEnum> contextHolder = new ThreadLocal<>();
    public static synchronized void set(DBTypeEnum dbType) {
        contextHolder.set(dbType);
    }
    public static synchronized DBTypeEnum get() {
        return contextHolder.get();
    }
    public static void master() {
        set(DBTypeEnum.MASTER);
    }
    public static void slave() {
        set(DBTypeEnum.SLAVE1);
    }
    public static void slave2(){ set(DBTypeEnum.SLAVE2); }
    // 清除數(shù)據(jù)源名
    public static void clearDB() {
        contextHolder.remove();
    }
}

重寫mybatis數(shù)據(jù)源路由接口,在此修改數(shù)據(jù)源為我們上一塊代碼設(shè)置的上下文的數(shù)據(jù)源

public class MyRoutingDataSource extends AbstractRoutingDataSource {
    @Nullable
    @Override
    protected Object determineCurrentLookupKey() {
        DBTypeEnum dbTypeEnum=DBContextHolder.get();
        return dbTypeEnum;
    }
}

將yml配置的多數(shù)據(jù)源手動(dòng)指定注入

@Configuration
public class DataSourceConfig {
    @Bean
    @ConfigurationProperties("spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }
    @Bean
    @ConfigurationProperties("spring.datasource.slave1")
    public DataSource slave1DataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public DataSource myRoutingDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
                                          @Qualifier("slave1DataSource") DataSource slave1DataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DBTypeEnum.MASTER, masterDataSource);
        targetDataSources.put(DBTypeEnum.SLAVE1, slave1DataSource);
        MyRoutingDataSource myRoutingDataSource = new MyRoutingDataSource();
        myRoutingDataSource.setDefaultTargetDataSource(masterDataSource);
        myRoutingDataSource.setTargetDataSources(targetDataSources);
        return myRoutingDataSource;
    }
}

sqlsession注入以上我們配置的datasource路由

@EnableTransactionManagement
@Configuration
@Import({TableSegInterceptor.class})
public class MyBatisConfig {
    @Resource(name = "myRoutingDataSource")
    private DataSource myRoutingDataSource;
    @Autowired
    private MybatisConfigProperty mybatisConfigProperty;
    @Autowired
    private TableSegInterceptor tableSegInterceptor;
    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(myRoutingDataSource);
        // SpringBoot項(xiàng)目集成mybatis打包為jar運(yùn)行時(shí)setTypeAliasesPackage無效解決
        VFS.addImplClass(SpringBootVFS.class);
        sqlSessionFactoryBean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources(mybatisConfigProperty.getMapperLocations()));
        sqlSessionFactoryBean.setTypeAliasesPackage(mybatisConfigProperty.getTypeAliasesPackage());
        sqlSessionFactoryBean.setConfigLocation(
                new PathMatchingResourcePatternResolver().getResource(mybatisConfigProperty.getConfigLocation()));
        sqlSessionFactoryBean.setPlugins(new Interceptor[]{tableSegInterceptor});
        return sqlSessionFactoryBean.getObject();
    }
    @Bean
    public PlatformTransactionManager platformTransactionManager() {
        return new DataSourceTransactionManager(myRoutingDataSource);
    }
}

spring aop攔截指定前綴的service方法,并設(shè)置對(duì)應(yīng)所屬的上下文

@Aspect
@Component
public class DataSourceAop {
    @Pointcut("!@annotation(com.ask.student.interceptor.annotation.Master) " +
            "&& (execution(* com.ask.student.service..*.select*(..)) " +
            "|| execution(* com.ask.student.service..*.get*(..))" +
            "|| execution(* com.ask.student.service..*.find*(..))" +
            ")")
    public void readPointcut() {
    }
    @Pointcut("@annotation(com.ask.student.interceptor.annotation.Master) " +
            "|| execution(* com.ask.student.service..*.insert*(..)) " +
            "|| execution(* com.ask.student.service..*.clean*(..)) " +
            "|| execution(* com.ask.student.service..*.reset*(..)) " +
            "|| execution(* com.ask.student.service..*.add*(..)) " +
            "|| execution(* com.ask.student.service..*.update*(..)) " +
            "|| execution(* com.ask.student.service..*.edit*(..)) " +
            "|| execution(* com.ask.student.service..*.delete*(..)) " +
            "|| execution(* com.ask.student.service..*.remove*(..))")
    public void writePointcut() {
    }
    @Before("readPointcut()")
    public void read() {
        DBContextHolder.slave();
    }
    @Before("writePointcut()")
    public void write() {
        DBContextHolder.master();
    }
    @After("readPointcut()||writePointcut()")
    public void afterSwitchDS(){
        DBContextHolder.clearDB();
    }
}

以上最后一個(gè)方法的作用,在攔截器中獲取后及時(shí)清除避免導(dǎo)致來回切換當(dāng)前線程變量延遲問題導(dǎo)致某些操作的數(shù)據(jù)源錯(cuò)誤

DBContextHolder.clearDB();

@After("readPointcut()||writePointcut()")

public void afterSwitchDS(){

DBContextHolder.clearDB();

}

2、mybatis-plus的實(shí)現(xiàn)方式

這個(gè)方式配置簡(jiǎn)單,代碼少,很多事情mybatis-plus都已經(jīng)做好了,推薦使用

yml配置如下

  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í)候會(huì)拋出異常,不啟動(dòng)則使用默認(rèn)數(shù)據(jù)源.
      datasource:
        master:
          url: jdbc:mysql://xxx:3306/db0?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
          username: admin
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
          type: com.zaxxer.hikari.HikariDataSource
          hikari:
            minimum-idle: 5
            maximum-pool-size: 15
            auto-commit: true
            idle-timeout: 30000
            pool-name: springHikariCP
            max-lifetime: 1800000
            connection-timeout: 30000
            connection-test-query: SELECT 1
        slave1:
          url: jdbc:mysql://xxx:3306/db2?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
          username: admin
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
          type: com.zaxxer.hikari.HikariDataSource
          hikari:
            minimum-idle: 5
            maximum-pool-size: 15
            auto-commit: true
            idle-timeout: 30000
            pool-name: springHikariCP
            max-lifetime: 1800000
            connection-timeout: 30000
            connection-test-query: SELECT 1
        slave2:
          url: jdbc:mysql://xxx:3306/db3?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
          username: admin
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
          type: com.zaxxer.hikari.HikariDataSource
          hikari:
            minimum-idle: 5
            maximum-pool-size: 15
            auto-commit: true
            idle-timeout: 30000
            pool-name: springHikariCP
            max-lifetime: 1800000
            connection-timeout: 30000
            connection-test-query: SELECT 1

使用起來非常簡(jiǎn)單,只需要加上這個(gè)master的注解即可

    @Override
    @DS("master")
    public DestMedia getOneByCodeFromEpg(String code) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("code", code);
        return super.getOne(queryWrapper);
    }

總結(jié)

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • 淺談兩個(gè)jar包中包含完全相同的包名和類名的加載問題

    淺談兩個(gè)jar包中包含完全相同的包名和類名的加載問題

    下面小編就為大家?guī)硪黄獪\談兩個(gè)jar包中包含完全相同的包名和類名的加載問題。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • java8傳函數(shù)方法圖文詳解

    java8傳函數(shù)方法圖文詳解

    在本篇文章中小編給大家整理了關(guān)于java8傳函數(shù)方法和相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。
    2019-04-04
  • java多線程編程實(shí)例

    java多線程編程實(shí)例

    這篇文章主要介紹了java多線程編程實(shí)例,分享了幾則多線程的實(shí)例代碼,具有一定參考價(jià)值,加深多線程編程的理解還是很有幫助的,需要的朋友可以參考下。
    2017-11-11
  • idea項(xiàng)目打開后出現(xiàn)橙色的時(shí)鐘圖標(biāo)的解決

    idea項(xiàng)目打開后出現(xiàn)橙色的時(shí)鐘圖標(biāo)的解決

    本文主要介紹了idea項(xiàng)目打開后出現(xiàn)橙色的時(shí)鐘圖標(biāo)的解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Mybatis無法獲取帶有下劃線前綴的字段的值問題

    Mybatis無法獲取帶有下劃線前綴的字段的值問題

    這篇文章主要介紹了Mybatis無法獲取帶有下劃線前綴的字段的值問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 學(xué)生視角手把手帶你寫Java?線程池初版

    學(xué)生視角手把手帶你寫Java?線程池初版

    作者是一個(gè)來自河源的大三在校生,以下筆記都是作者自學(xué)之路的一些淺薄經(jīng)驗(yàn),如有錯(cuò)誤請(qǐng)指正,將來會(huì)不斷的完善筆記,幫助更多的Java愛好者入門
    2022-03-03
  • Java中Calendar類用法實(shí)例詳解

    Java中Calendar類用法實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于Java中Calendar類用法的相關(guān)資料,Calendar類是Java.util包中提供的一個(gè)抽象類,該類從JDK1.1開始出現(xiàn),作為Date類的替代方案,Calendar類中包含了對(duì)不同國(guó)家地區(qū)日歷的處理,需要的朋友可以參考下
    2023-09-09
  • 關(guān)于Mybatis使用collection分頁(yè)問題

    關(guān)于Mybatis使用collection分頁(yè)問題

    項(xiàng)目中mybatis分頁(yè)的場(chǎng)景是非常高頻的,當(dāng)使用ResultMap并配置collection做分頁(yè)的時(shí)候,我們可能會(huì)遇到獲取當(dāng)前頁(yè)的數(shù)據(jù)少于每頁(yè)大小的數(shù)據(jù)問題。接下來通過本文給大家介紹Mybatis使用collection分頁(yè)問題,感興趣的朋友一起看看吧
    2021-11-11
  • Java實(shí)現(xiàn)Random隨機(jī)數(shù)生成雙色球號(hào)碼

    Java實(shí)現(xiàn)Random隨機(jī)數(shù)生成雙色球號(hào)碼

    使用Random類是Java中用于生成隨機(jī)數(shù)的標(biāo)準(zhǔn)類,本文主要介紹了Java實(shí)現(xiàn)Random隨機(jī)數(shù)生成雙色球號(hào)碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • Spring系統(tǒng)屬性及spring.properties配置文件示例詳解

    Spring系統(tǒng)屬性及spring.properties配置文件示例詳解

    spring中有一個(gè)SpringProperties類,來保存spring的系統(tǒng)屬性,本文結(jié)合實(shí)例代碼對(duì)Spring系統(tǒng)屬性及spring.properties配置文件相關(guān)知識(shí)給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-07-07

最新評(píng)論