溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

spring boot多數(shù)據(jù)源動(dòng)態(tài)切換代碼實(shí)例

發(fā)布時(shí)間:2020-08-22 09:42:40 來源:腳本之家 閱讀:235 作者:炫舞風(fēng)中 欄目:編程語言

這篇文章主要介紹了spring boot多數(shù)據(jù)源動(dòng)態(tài)切換代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

當(dāng)項(xiàng)目中存在多數(shù)據(jù)源時(shí),就涉及到數(shù)據(jù)源的動(dòng)態(tài)切換,通過研究,特此記錄一下。

1、maven依賴

<!--數(shù)據(jù)庫連接-->
<dependency>
      <groupId>com.oracle</groupId>
      <artifactId>ojdbc6</artifactId>
      <version>11.2.0.4</version>
      <scope>runtime</scope>
    </dependency>
<!--數(shù)據(jù)庫連接池->
<dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid-spring-boot-starter</artifactId>
      <version>1.1.10</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
<!--aop->
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>

2、多數(shù)據(jù)源信息配置

#多數(shù)據(jù)源測(cè)試
spring:
 datasource:
  druid:
   master:
    driver-class-name: oracle.jdbc.driver.OracleDriver
    username: test
    password: test
    url: jdbc:oracle:thin:@//ip1:1521/orcl
   slave:
    driver-class-name: oracle.jdbc.driver.OracleDriver
    username: test
    password: test
    url: jdbc:oracle:thin:@//ip2:1521/orcl

3、數(shù)據(jù)源配置信息轉(zhuǎn)換成實(shí)體類

@ConfigurationProperties(prefix = "spring.datasource.druid")
@Data
@Component
public class DataSourceProperties {
  private Map<String,String>master;
  private Map<String,String>slave;
}

4、動(dòng)態(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();
  }
}

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

@Configuration
public class DynamicDataSourceConfig {

  @Bean
  public DataSource master(@Autowired DataSourceProperties dataSourceProperties){
    DruidDataSource druidDataSource = new DruidDataSource();
    Map<String, String> master = dataSourceProperties.getMaster();
    druidDataSource.setUsername(master.get("username"));
    druidDataSource.setPassword(master.get("password"));
    druidDataSource.setUrl(master.get("url"));
    //其他參數(shù)配置 省略
    return druidDataSource;
  }

  @Bean
  public DataSource slave(@Autowired DataSourceProperties dataSourceProperties){
    DruidDataSource druidDataSource = new DruidDataSource();
    Map<String, String> slave = dataSourceProperties.getSlave();
    druidDataSource.setUsername(slave.get("username"));
    druidDataSource.setPassword(slave.get("password"));
    druidDataSource.setUrl(slave.get("url"));
    //其他參數(shù)配置 省略
    return druidDataSource;
  }

  @Bean
  @Primary
  public DynamicDataSource dataSource(DataSource master,DataSource slave){
    Map<Object,Object>map = new HashMap<>(4);
    map.put("master",master);
    map.put("slave",slave);
    return new DynamicDataSource(master,map);
  }
}

6、自定義@DataSource注解

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

  String name() default "master";
}

7、Aop切面類配置

@Component
@Aspect
public class DataSourceAspect {

  @Pointcut("@annotation(com.zxgeo.sso.muiltDatasource.anons.DataSource)")
  public void dataSourcePointCut(){}

  @Around(value = "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("master");
    }else {
      DynamicDataSource.setDataSource(dataSource.name());
    }
    try {
      return point.proceed();
    } finally {
      DynamicDataSource.clearDataSource();
    }
  }
}

8、啟動(dòng)配置注解信息,重要(不然運(yùn)行會(huì)報(bào)錯(cuò))

@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})

9、測(cè)試

(1)、service層(此處沒有使用mybatis)

@Service
public class TestService {

  @Autowired
  private javax.sql.DataSource dataSource;

  @DataSource
  public Map<String,Object> getMasterDataSource() throws SQLException {
    Connection connection = dataSource.getConnection();
    Map<String,Object> map;
    try (PreparedStatement preparedStatement
           = connection.prepareStatement("SELECT * FROM AA WHERE A=10001")) {
      ResultSet resultSet = preparedStatement.executeQuery();
      map = new HashMap<>();
      while (resultSet.next()){
        map.put("A",resultSet.getString("A"));
        map.put("B",resultSet.getString("B"));
        map.put("C",resultSet.getString("C"));
      }
    }
    return map;
  }
  @DataSource(name = "slave")
  public Map<String,Object> getSlaveDataSource() throws SQLException {
    Connection connection = dataSource.getConnection();
    Map<String,Object> map;
    try (PreparedStatement preparedStatement
           = connection.prepareStatement("SELECT * FROM AA WHERE A=10002")) {
      ResultSet resultSet = preparedStatement.executeQuery();
      map = new HashMap<>();
      while (resultSet.next()){
        map.put("A",resultSet.getString("A"));
        map.put("B",resultSet.getString("B"));
        map.put("C",resultSet.getString("C"));
      }
    }
    return map;
  }
}

(2)、單元測(cè)試

@SpringBootTest
@RunWith(SpringRunner.class)
class SsoApplicationTests {

  @Autowired
  private TestService testService;

  @Test
  public void muliDatasorce() throws SQLException {
    Map<String, Object> masterDataSourceUrl = testService.getMasterDataSource();
    System.out.println(masterDataSourceUrl);
    Map<String, Object> slaveDataSourceUrl = testService.getSlaveDataSource();
    System.out.println(slaveDataSourceUrl);
  }
}

(3)、結(jié)果:

spring boot多數(shù)據(jù)源動(dòng)態(tài)切換代碼實(shí)例

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

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI