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

Springboot整合多數(shù)據(jù)源代碼示例詳解

 更新時(shí)間:2020年08月07日 10:15:18   作者:william_zhao  
這篇文章主要介紹了Springboot整合多數(shù)據(jù)源代碼示例詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

最近有個(gè)老項(xiàng)目想逐步將新業(yè)務(wù)的數(shù)據(jù)放到新的數(shù)據(jù)庫,以前的業(yè)務(wù)還得連接以前的數(shù)據(jù)庫,于是需要整合多數(shù)據(jù)源 。

多數(shù)據(jù)源實(shí)際上是繼承了AbstractRoutingDataSource類,這個(gè)類最終實(shí)現(xiàn)了DataSource接口,DataSource里只有一個(gè)getConnection方法,數(shù)據(jù)庫每次訪問的時(shí)候都要先通過這個(gè)方法獲取連接,所有多數(shù)據(jù)源就是每次訪問數(shù)據(jù)庫之前動(dòng)態(tài)的改變數(shù)據(jù)源。

在請(qǐng)求前改變數(shù)據(jù)源當(dāng)然需要用到SpringAOP,自定義注解操作

項(xiàng)目結(jié)構(gòu)

下面上代碼:

首先是依賴:

<!--數(shù)據(jù)庫連接-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <!--sqlserver-->
    <dependency>
      <groupId>com.microsoft.sqlserver</groupId>
      <artifactId>mssql-jdbc</artifactId>
      <scope>runtime</scope>
    </dependency>
    <!--mybatis-plus-->
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.1.2</version>
    </dependency>
    <!--數(shù)據(jù)庫連接池-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.8</version>
    </dependency>      <!--AOP-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>

yml配置數(shù)據(jù)源

server:
 port: 8888

spring:
 jackson:
  time-zone: GMT+8
  date-format: yyyy-MM-dd HH:mm:ss
 datasource:
  druid:
   first:
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    jdbc-url: jdbc:mysql://rm-uf6265pj340sc9447oo.mysql.rds.54565.com:3306/dm?serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=utf-8
    username: username
    password: password
   second:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    jdbc-url: jdbc:sqlserver://39.104.203.222:1433;DatabaseName=TestTLcom
    username: root
    password: 123456

mybatis-plus:
 mapper-locations: classpath*:/mapper/*Mapper.xml
 type-aliases-package: com.zdyl.dynamicdatasourcedemo.entity
 global-config:
  #主鍵類型 0:"數(shù)據(jù)庫ID自增", 1:"用戶輸入ID",2:"全局唯一ID (數(shù)字類型唯一ID)", 3:"全局唯一ID UUID";
  id-type: 3
  #字段策略 0:"忽略判斷",1:"非 NULL 判斷"),2:"非空判斷"
  field-strategy: 2
  #駝峰下劃線轉(zhuǎn)換
  db-column-underline: true
  #刷新mapper 調(diào)試神器
  refresh-mapper: true
  #數(shù)據(jù)庫大寫下劃線轉(zhuǎn)換
  #capital-mode: true
  #序列接口實(shí)現(xiàn)類配置
  #key-generator: com.baomidou.springboot.xxx
  #邏輯刪除配置
  #logic-delete-value: 0
  #logic-not-delete-value: 1
  #自定義填充策略接口實(shí)現(xiàn)
  #meta-object-handler: com.baomidou.springboot.xxx
  #自定義SQL注入器
  #sql-injector: com.baomidou.springboot.xxx
 configuration:
  map-underscore-to-camel-case: true
  cache-enabled: false

定義數(shù)據(jù)庫名稱

/**
 * 數(shù)據(jù)庫名稱
 */
public interface DataSourceNames {

  String FIRST = "first";
  String SECOND = "second";
}

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

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 動(dòng)態(tài)數(shù)據(jù)源
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

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

  public DynamicDataSource(DataSource defaultTargetDataSource, Map<String, DataSource> targetDataSources) {

    super.setDefaultTargetDataSource(defaultTargetDataSource);
    super.setTargetDataSources(new HashMap<>(targetDataSources));
    super.afterPropertiesSet();
  }

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

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

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

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

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

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.zdyl.dynamicdatasourcedemo.dynamicdatasource.DataSourceNames;
import com.zdyl.dynamicdatasourcedemo.dynamicdatasource.DynamicDataSource;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 多數(shù)據(jù)源配置
 */
@Configuration
@MapperScan("com.zdyl.dynamicdatasourcedemo.**.mapper*")
public class MybatisPluConfig {

  /**
   * 數(shù)據(jù)源配置
   * @return
   */
  @Bean
  @ConfigurationProperties(prefix="spring.datasource.druid.first")
  public DataSource firstDataSource() {
    return DataSourceBuilder.create().build();
  }

  @Bean
  @ConfigurationProperties(prefix="spring.datasource.druid.second")
  public DataSource secondDataSource() {
    return DataSourceBuilder.create().build();
  }

  @Bean
  @Primary
  public DynamicDataSource dataSource(DataSource firstDataSource, DataSource secondDataSource){
    Map<String, DataSource> targetDataSources = new HashMap<>();
    targetDataSources.put(DataSourceNames.FIRST, firstDataSource);
    targetDataSources.put(DataSourceNames.SECOND, secondDataSource);
    return new DynamicDataSource(firstDataSource, targetDataSources);
  }

  /**
   * mybatis-plus分頁插件<br>
   * 文檔:http://mp.baomidou.com<br>
   */
  @Bean
  public PaginationInterceptor paginationInterceptor() {
    return new PaginationInterceptor();
  }

}

下面就是自定義注解

import java.lang.annotation.*;

/**
 * 多數(shù)據(jù)源注解
 * AOP攔截此注解更換數(shù)據(jù)源
 */

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CurDataSource {

  String name() default "";
}

AOP

import com.zdyl.dynamicdatasourcedemo.dynamicdatasource.DataSourceNames;
import com.zdyl.dynamicdatasourcedemo.dynamicdatasource.DynamicDataSource;
import com.zdyl.dynamicdatasourcedemo.dynamicdatasource.annotation.CurDataSource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;


/**
 * 多數(shù)據(jù)源,切面處理類
 * AOP攔截多數(shù)據(jù)源注解 @CurDataSource 注解更換數(shù)據(jù)源
 */

@Slf4j
@Aspect
@Component
public class DataSourceAspect implements Ordered {


  /**
   * 切點(diǎn)
   */
  @Pointcut("@annotation(com.zdyl.dynamicdatasourcedemo.dynamicdatasource.annotation.CurDataSource)")
  public void dataSourcePointCut() {

  }

  @Around("dataSourcePointCut()")
  public Object around(ProceedingJoinPoint point) throws Throwable {
    MethodSignature signature = (MethodSignature) point.getSignature();
    Method method = signature.getMethod();
    CurDataSource curDataSource = method.getAnnotation(CurDataSource.class);
    if (curDataSource == null) {
      DynamicDataSource.setDataSource(DataSourceNames.FIRST);
      log.info("set datasource is " + DataSourceNames.FIRST);
    } else {
      DynamicDataSource.setDataSource(curDataSource.name());
      log.info("set datasource is " + curDataSource.name());
    }
    try {
      return point.proceed();
    } finally {
      DynamicDataSource.clearDataSource();
      log.info("clean datasource");
    }
  }

  @Override
  public int getOrder() {
    return 1;
  }
}

最后主啟動(dòng)了去掉數(shù)據(jù)源自動(dòng)加載

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

最后我們來跑起來請(qǐng)求一下,測試一下是否正確

@RestController
public class CfgDeviceController {
  @Resource
  CfgDeviceService cfgDeviceService;
  @Resource
  CfgChargeStartInfoService cfgChargeStartInfoService;
  
  @CurDataSource(name = DataSourceNames.FIRST)
  @GetMapping("/test")
  public void getUser() {
    CfgDevice byId = cfgDeviceService.getById(19);
    System.out.println(byId.toString());
  }

  @CurDataSource(name = DataSourceNames.SECOND)
  @GetMapping("/test1")
  public void getUser1() {
    CfgChargeStartInfo byId = cfgChargeStartInfoService.getById(1);
    System.out.println(byId.toString());
  }
}

**如果不加注解,使用默認(rèn)數(shù)據(jù)源

至此就整合完了

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java遞歸算法的實(shí)例詳解

    java遞歸算法的實(shí)例詳解

    在本篇文章里小編給大家整理了關(guān)于java遞歸算法的實(shí)例內(nèi)容,以及相關(guān)知識(shí)點(diǎn)總結(jié),需要的朋友們可以學(xué)習(xí)下。
    2020-02-02
  • Java基礎(chǔ)教程之類型轉(zhuǎn)換與多態(tài)

    Java基礎(chǔ)教程之類型轉(zhuǎn)換與多態(tài)

    這篇文章主要介紹了Java基礎(chǔ)教程之類型轉(zhuǎn)換與多態(tài),本文講解了 基本類型轉(zhuǎn)換、 upcast與多態(tài)、 Object類等內(nèi)容,需要的朋友可以參考下
    2014-09-09
  • java+mysql實(shí)現(xiàn)圖書館管理系統(tǒng)實(shí)戰(zhàn)

    java+mysql實(shí)現(xiàn)圖書館管理系統(tǒng)實(shí)戰(zhàn)

    這篇文章主要為大家詳細(xì)介紹了java+mysql實(shí)現(xiàn)圖書館管理系統(tǒng)實(shí)戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • Java實(shí)現(xiàn)局域網(wǎng)聊天室功能(私聊、群聊)

    Java實(shí)現(xiàn)局域網(wǎng)聊天室功能(私聊、群聊)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)局域網(wǎng)聊天室功能,包括私聊、群聊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Mybatis條件if test如何使用枚舉值

    Mybatis條件if test如何使用枚舉值

    這篇文章主要介紹了Mybatis條件if test如何使用枚舉值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 使用java實(shí)現(xiàn)百萬級(jí)別數(shù)據(jù)導(dǎo)出excel的三種方式

    使用java實(shí)現(xiàn)百萬級(jí)別數(shù)據(jù)導(dǎo)出excel的三種方式

    這篇文章主要介紹了使用java實(shí)現(xiàn)百萬級(jí)別數(shù)據(jù)導(dǎo)出excel的三種方式,有些業(yè)務(wù)系統(tǒng)可能動(dòng)輒涉及到百萬上千萬的數(shù)據(jù),用正常的方法效率就變得很低,今天我們來看看這幾種實(shí)現(xiàn)思路
    2023-03-03
  • 詳解如何使用MyBatis實(shí)現(xiàn)數(shù)據(jù)庫的CRUD

    詳解如何使用MyBatis實(shí)現(xiàn)數(shù)據(jù)庫的CRUD

    這篇文章主要為大家詳細(xì)介紹了如何使用MyBatis實(shí)現(xiàn)數(shù)據(jù)庫的CRUD操作,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分庫分表

    SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分庫分表

    本文主要介紹了SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分庫分表,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 詳述IntelliJ IDEA提交代碼前的 Code Analysis 機(jī)制(小結(jié))

    詳述IntelliJ IDEA提交代碼前的 Code Analysis 機(jī)制(小結(jié))

    本篇文章主要介紹了詳述IntelliJ IDEA提交代碼前的 Code Analysis 機(jī)制(小結(jié)),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-11-11
  • JavaGUI常用窗體組件與面板使用詳解

    JavaGUI常用窗體組件與面板使用詳解

    GUI即圖形用戶界面,它是基于圖形的界面,windows就是一個(gè)圖形用戶界面的操作系統(tǒng),而DOS是基于命令提示符的操作系統(tǒng),GUI編程就是編出一個(gè)圖形用戶界面的軟件,它使用圖形的方式,以菜單、按鈕、表示、圖文框等標(biāo)準(zhǔn)界面元素組成的用戶操作界面
    2023-03-03

最新評(píng)論

微山县| 方城县| 麻阳| 新昌县| 姜堰市| 永吉县| 平湖市| 潼关县| 肇庆市| 类乌齐县| 桐城市| 从化市| 安新县| 石渠县| 神农架林区| 洪泽县| 房产| 都昌县| 中山市| 岳西县| 卢氏县| 和顺县| 崇义县| 衢州市| 永昌县| 宜昌市| 称多县| 平阴县| 女性| 新邵县| 邯郸市| 罗山县| 汽车| 滨海县| 柘城县| 澄城县| 道真| 盐山县| 东海县| 涟源市| 鄂伦春自治旗|