最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mybatis plus 配置多數(shù)據(jù)源的實(shí)現(xiàn)示例

 更新時(shí)間:2020年08月26日 14:31:20   作者:迷神圖卷  
這篇文章主要介紹了Mybatis plus 配置多數(shù)據(jù)源的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

記得面試時(shí)候,有面試官會(huì)問道,你們多數(shù)據(jù)源是怎么實(shí)現(xiàn)的呀。.......,一陣蒙蔽中,然后說道我們之前項(xiàng)目中,沒有用到多數(shù)據(jù)源。

所幸,目前做得項(xiàng)目中有一個(gè)業(yè)務(wù)邏輯中,用到多個(gè)數(shù)據(jù)庫數(shù)據(jù)情況,多數(shù)據(jù)源華麗上線。

一. mybatis plus

因?yàn)槲覀冺?xiàng)目是springboot+mybatis plus,有些人一看,mybatis還知道對(duì)吧,mybatis plus是什么鬼,其實(shí)字面意思可以理解,就是對(duì)mybatis進(jìn)行一些功能改造,一些封裝升級(jí),然后用起來特別方便。

核心功能的升級(jí)主要是以下三點(diǎn):

支持通用的 CRUD、代碼生成器與條件構(gòu)造器。

通用 CRUD:定義好 Mapper 接口后,只需要繼承 BaseMapper<T> 接口即可獲得通用的增刪改查功能,無需編寫任何接口方法與配置文件
條件構(gòu)造器:通過 EntityWrapper<T> (實(shí)體包裝類),可以用于拼接 SQL 語句,并且支持排序、分組查詢等復(fù)雜的 SQL
代碼生成器:支持一系列的策略配置與全局配置,比 MyBatis 的代碼生成更好用

二.多數(shù)據(jù)源配置開始

思路:

1、yml中配置多個(gè)數(shù)據(jù)源信息
2、通過AOP切換不同數(shù)據(jù)源
3、配合mybatis plus使用

1、yml配置

spring:
 aop:
   proxy-target-class: true
   auto: true
 datasource:
  druid:
   db1:
    url: jdbc:mysql://localhost:3306/eboot
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
    initialSize: 5
    minIdle: 5
    maxActive: 20
   db2:
    url: jdbc:oracle:thin:@192.168.136.222:ORCL
    username: sa
    password: sa123456
    driver-class-name: oracle.jdbc.OracleDriver
    initialSize: 5
    minIdle: 5
    maxActive: 20

2、啟動(dòng)多個(gè)數(shù)據(jù)源

@EnableTransactionManagement //開啟事務(wù)
@Configuration //spring中常用到注解,與xml配置相對(duì)立。是兩種加載bean方式
@MapperScan("com.df.openapi.**.mapper.db*") // 掃描mapperdao的地址
public class MybatisPlusConfig {
 
  @Bean
  public PaginationInterceptor paginationInterceptor() {
    PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
//    paginationInterceptor.setLocalPage(true); // 由于版本問題,有些類可能招不到這個(gè)方法,需要升級(jí)jar包
    return paginationInterceptor;
  }
 
  @Bean(name = "db1")
  @ConfigurationProperties(prefix = "spring.datasource.druid.db1")
  public DataSource db1() {
    return DruidDataSourceBuilder.create().build();
  }
 
  @Bean(name = "db2")
  @ConfigurationProperties(prefix = "spring.datasource.druid.db2")
  public DataSource db2() {
    return DruidDataSourceBuilder.create().build();
  }
 
  /**
   * 動(dòng)態(tài)數(shù)據(jù)源配置
   *
   * @return
   */
  @Bean
  @Primary
  public DataSource multipleDataSource(@Qualifier("db1") DataSource db1,
                     @Qualifier("db2") DataSource db2) {
    DynamicDataSource dynamicDataSource = new DynamicDataSource();
    Map<Object, Object> targetDataSources = new HashMap<>();
    targetDataSources.put(DBTypeEnum.db1.getValue(), db1);
    targetDataSources.put(DBTypeEnum.db2.getValue(), db2);
    dynamicDataSource.setTargetDataSources(targetDataSources);
    dynamicDataSource.setDefaultTargetDataSource(db2); // 程序默認(rèn)數(shù)據(jù)源,這個(gè)要根據(jù)程序調(diào)用數(shù)據(jù)源頻次,經(jīng)常把常調(diào)用的數(shù)據(jù)源作為默認(rèn)
    return dynamicDataSource;
  }
 
  @Bean("sqlSessionFactory")
  public SqlSessionFactory sqlSessionFactory() throws Exception {
    MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
    sqlSessionFactory.setDataSource(multipleDataSource(db1(), db2()));
 
    MybatisConfiguration configuration = new MybatisConfiguration();
    configuration.setJdbcTypeForNull(JdbcType.NULL);
    configuration.setMapUnderscoreToCamelCase(true);
    configuration.setCacheEnabled(false);
    sqlSessionFactory.setConfiguration(configuration);
    //PerformanceInterceptor(),OptimisticLockerInterceptor()
    //添加分頁功能
    sqlSessionFactory.setPlugins(new Interceptor[]{
        paginationInterceptor()
    });
//    sqlSessionFactory.setGlobalConfig(globalConfiguration()); //注釋掉全局配置,因?yàn)樵趚ml中讀取就是全局配置
    return sqlSessionFactory.getObject();
  }
 
 /*  @Bean
  public GlobalConfiguration globalConfiguration() {
    GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector());
    conf.setLogicDeleteValue("-1");
    conf.setLogicNotDeleteValue("1");
    conf.setIdType(0);
    conf.setMetaObjectHandler(new MyMetaObjectHandler());
    conf.setDbColumnUnderline(true);
    conf.setRefresh(true);
    return conf;
  }*/
}

3、DBType枚舉類

package com.df.openapi.config.db;
 
public enum DBTypeEnum {
 
  db1("db1"), db2("db2");
  private String value;
 
  DBTypeEnum(String value) {
    this.value = value;
  }
 
  public String getValue() {
    return value;
  }
}

4、動(dòng)態(tài)數(shù)據(jù)源決策

package com.df.openapi.config.db;
 
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final Logger LOGGER = LoggerFactory.getLogger(DynamicDataSource.class);
@Override
protected Object determineCurrentLookupKey() {
  String datasource = DataSourceContextHolder.getDbType();
  LOGGER.debug("使用數(shù)據(jù)源 {}", datasource);
  return datasource;
}
}

5、設(shè)置、獲取數(shù)據(jù)源

public class DataSourceContextHolder {
 
  private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceContextHolder.class);
 
  private static final ThreadLocal contextHolder = new ThreadLocal<>(); //實(shí)際上就是開啟多個(gè)線程,每個(gè)線程進(jìn)行初始化一個(gè)數(shù)據(jù)源
  /**
   * 設(shè)置數(shù)據(jù)源
   * @param dbTypeEnum
   */
  public static void setDbType(DBTypeEnum dbTypeEnum) {
    contextHolder.set(dbTypeEnum.getValue());
  }
 
  /**
   * 取得當(dāng)前數(shù)據(jù)源
   * @return
   */
  public static String getDbType() {
    return (String) contextHolder.get();
  }
 
  /**
   * 清除上下文數(shù)據(jù)
   */
  public static void clearDbType() {
    contextHolder.remove();
  }
}

6、AOP實(shí)現(xiàn)的數(shù)據(jù)源切換

@Order設(shè)置的足夠小是為了讓他先執(zhí)行

/**
 * aop的實(shí)現(xiàn)的數(shù)據(jù)源切換<br> * aop切點(diǎn),實(shí)現(xiàn)mapper類找尋,找到所屬大本營(yíng)以后,如db1Aspect(),則會(huì)調(diào)用<br> * db1()前面之前的操作,進(jìn)行數(shù)據(jù)源的切換。
 */
@Component
@Order(value = -100)
@Slf4j
@Aspect
public class DataSourceAspect {
 
  @Pointcut("execution(* com.zwyl.bazhong.dao.mapper.db1..*.*(..))")
  private void db1Aspect() {
  }
 
  @Pointcut("execution(* com.zwyl.bazhong.dao.mapper.db2..*.*(..))")
  private void db2Aspect() {
  }
 
  @Before("db1Aspect()")
  public void db1() {
    log.info("切換到db1 數(shù)據(jù)源...");
    DataSourceContextHolder.setDbType(DBTypeEnum.db1);
  }
 
  @Before("db2Aspect()")
  public void db2() {
    log.info("切換到db2 數(shù)據(jù)源...");
    DataSourceContextHolder.setDbType(DBTypeEnum.db2);
  }
}

7、mapper層結(jié)構(gòu)

8、寫一個(gè)service測(cè)試一下

@Service
public class DictServiceImpl implements IDictService {
 
  @Resource
  private PtDictMapper ptDictMapper; //來自db1
 
  @Resource
  private SysDictMapper sysDictMapper; // 來自db2
 
 
  @Override
  public void getById(String id) {
    PtDict dict = ptDictMapper.selectById("2bf6257fc8fe483c84c1ad7e89d632f6");
    SysDict sysDict = sysDictMapper.getById("49");
    System.out.println("123");
  }
}

9、測(cè)試結(jié)果

總結(jié): 其實(shí)整個(gè)過程可以理解成,配置多數(shù)據(jù)源 xml中  -------> 然后通過加載多數(shù)源到spring工廠中-------->然后創(chuàng)建多線程,每個(gè)數(shù)據(jù)源對(duì)應(yīng)一個(gè)數(shù)據(jù)源--------->然后實(shí)際調(diào)用時(shí)候,會(huì)先通過aop匹配到某一具體數(shù)據(jù)源------------->然后實(shí)例化當(dāng)前數(shù)據(jù)源

到此這篇關(guān)于Mybatis plus 配置多數(shù)據(jù)源的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Mybatis plus 多數(shù)據(jù)源內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 進(jìn)階必備之ssm框架全面整合

    Java 進(jìn)階必備之ssm框架全面整合

    SSM框架是spring MVC ,spring和mybatis框架的整合,是標(biāo)準(zhǔn)的MVC模式,將整個(gè)系統(tǒng)劃分為表現(xiàn)層,controller層,service層,DAO層四層,使用spring MVC負(fù)責(zé)請(qǐng)求的轉(zhuǎn)發(fā)和視圖管理,spring實(shí)現(xiàn)業(yè)務(wù)對(duì)象管理,mybatis作為數(shù)據(jù)對(duì)象的持久化引擎
    2021-10-10
  • Springboot+Redis執(zhí)行l(wèi)ua腳本的項(xiàng)目實(shí)踐

    Springboot+Redis執(zhí)行l(wèi)ua腳本的項(xiàng)目實(shí)踐

    本文主要介紹了Springboot+Redis執(zhí)行l(wèi)ua腳本的項(xiàng)目實(shí)踐,詳細(xì)的介紹Redis與Lua腳本的結(jié)合應(yīng)用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • SpringMVC?bean加載控制的實(shí)現(xiàn)分析

    SpringMVC?bean加載控制的實(shí)現(xiàn)分析

    SpringMVC是一種基于Java,實(shí)現(xiàn)了Web?MVC設(shè)計(jì)模式,請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架,即使用了MVC架構(gòu)模式的思想,將Web層進(jìn)行職責(zé)解耦?;谡?qǐng)求驅(qū)動(dòng)指的就是使用請(qǐng)求-響應(yīng)模型,框架的目的就是幫助我們簡(jiǎn)化開發(fā),SpringMVC也是要簡(jiǎn)化我們?nèi)粘eb開發(fā)
    2023-02-02
  • SpringBoot注入配置文件的3種方法詳解

    SpringBoot注入配置文件的3種方法詳解

    這篇文章主要介紹了SpringBoot注入配置文件的3種方法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • 淺談Spring 重定向指南

    淺談Spring 重定向指南

    本篇文章主要介紹了淺談Spring 重定向指南,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • 教你如何測(cè)試Spring Data JPA的Repository

    教你如何測(cè)試Spring Data JPA的Repository

    Spring Data JPA 提供了一些便捷的方式來測(cè)試這種持久層的代碼,常見的兩種測(cè)試類型是集成測(cè)試和單元測(cè)試,本文通過示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • springboot?vue測(cè)試平臺(tái)接口定義及發(fā)送請(qǐng)求功能實(shí)現(xiàn)

    springboot?vue測(cè)試平臺(tái)接口定義及發(fā)送請(qǐng)求功能實(shí)現(xiàn)

    這篇文章主要為大家介紹了springboot+vue測(cè)試平臺(tái)接口定義及發(fā)送請(qǐng)求功能實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 如何在Springboot實(shí)現(xiàn)攔截器功能

    如何在Springboot實(shí)現(xiàn)攔截器功能

    其實(shí)spring boot攔截器的配置方式和springMVC差不多,只有一些小的改變需要注意下就ok了,下面這篇文章主要給大家介紹了關(guān)于如何在Springboot實(shí)現(xiàn)攔截器功能的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • SpringBoot環(huán)境Druid數(shù)據(jù)源使用及特點(diǎn)

    SpringBoot環(huán)境Druid數(shù)據(jù)源使用及特點(diǎn)

    Druid 是目前比較流行的高性能的,分布式列存儲(chǔ)的OLAP框架(具體來說是MOLAP)。本文給大家分享SpringBoot環(huán)境Druid數(shù)據(jù)源使用及特點(diǎn)介紹,感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • Maven pom.xml scope屬性的使用

    Maven pom.xml scope屬性的使用

    在Maven中,scope屬性用于定義依賴關(guān)系在不同生命周期階段的行為,影響依賴在構(gòu)建過程中的下載和使用,以及是否傳遞給其他項(xiàng)目,常見的scope值包括compile、provided、runtime和test等
    2025-01-01

最新評(píng)論

八宿县| 南投市| 应城市| 佛学| 揭阳市| 永和县| 富川| 南江县| 洞口县| 佛学| 蛟河市| 南川市| 阿鲁科尔沁旗| 宜章县| 黄龙县| 大庆市| 巴东县| 互助| 平利县| 大冶市| 连南| 大安市| 潜江市| 高邮市| 东乡| 武隆县| 台前县| 浪卡子县| 武川县| 岳普湖县| 察哈| 扶余县| 谢通门县| 会泽县| 泸西县| 连江县| 左云县| 修文县| 静安区| 延津县| 岳池县|