1. 程式人生 > 程式設計 >SpringBoot自定義註解使用讀寫分離Mysql資料庫的例項教程

SpringBoot自定義註解使用讀寫分離Mysql資料庫的例項教程

需求場景

為了防止程式碼中有的SQL慢查詢,影響我們線上主資料庫的效能。我們需要將sql查詢操作切換到從庫中進行。為了使用方便,將自定義註解的形式使用。

mysql匯入的依賴

		<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>8.0.16</version>
  </dependency>

程式碼實現

配置檔案

application.yml

spring:
 datasource:
 master:
  username: root
  password: 123456
  jdbc-url: jdbc:mysql://localhost:3306/master?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
  driver-class-name: com.mysql.cj.jdbc.Driver
 slave:
  username: root
  password: 123456
  jdbc-url: jdbc:mysql://localhost:3306/slave?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
  driver-class-name: com.mysql.cj.jdbc.Driver

DataSourceType

/**
 * 資料來源型別列舉
 * @author yangjc01
 * @create 2020/11/02
 */
public enum DataSourceType {
 /**
  * 主庫,主要進行寫操作
  */
 MASTER,/**
  * 從庫,進行讀操作
  */
 SLAVE
}

DynamicDataSource

/**
 * 動態資料來源
 * @author yangjc01
 * @create 2020/11/02
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

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

 @Override
 protected Object determineCurrentLookupKey() {
  return DynamicDataSourceContextHolder.getDateSourceType();
 }
}

DynamicDataSourceContextHolder

public class DynamicDataSourceContextHolder {

 /**
  * 使用ThreadLocal維護變數,ThreadLocal為每個使用該變數的執行緒提供獨立的變數副本,
  * 所以每一個執行緒都可以獨立地改變自己的副本,而不會影響其它執行緒所對應的副本。
  */
 private static final ThreadLocal<String> CONTEXT_HOLDER = 
 new ThreadLocal<>();

 /**
  * 設定資料來源的變數
  */
 public static void setDateSourceType(String dsType) {
  CONTEXT_HOLDER.set(dsType);
 }

 /**
  * 獲得資料來源的變數
  */
 public static String getDateSourceType() {
  return CONTEXT_HOLDER.get();
 }

 /**
  * 清空資料來源變數
  */
 public static void clearDateSourceType() {
  CONTEXT_HOLDER.remove();
 }
}

DataSource 註解

/**
 * @author yangjc01
 * @create 2020/11/01
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
 /**
  * 切換資料來源
  */
 DataSourceType value() default DataSourceType.MASTER;

}

DataSourceAspect 切面

@Aspect
@Order(1)
@Component
public class DataSourceAspect {

 @Pointcut("@annotation(com.jgame.mis.annotation.DataSource)")
 public void dsPointCut() {

 }

 @Around("dsPointCut()")
 public Object around(ProceedingJoinPoint point) throws Throwable {
  MethodSignature signature = (MethodSignature) point.getSignature();

  Method method = signature.getMethod();

  DataSource dataSource = method.getAnnotation(DataSource.class);

  if (null!=dataSource) {
   DynamicDataSourceContextHolder.
   setDateSourceType(dataSource.value().name());
  }

  try {
   return point.proceed();
  } finally {
   // 銷燬資料來源 在執行方法之後
   DynamicDataSourceContextHolder.clearDateSourceType();
  }
 }
}

DataSourceConfig

@Configuration
public class DataSourceConfig {

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

 @Bean
 @ConfigurationProperties("spring.datasource.slave")
 public DataSource slaveDataSource() {
  return DataSourceBuilder.create().build();
 }

 @Bean(name = "dynamicDataSource")
 @Primary
 public DynamicDataSource dataSource()
 {
  Map<Object,Object> targetDataSources = new HashMap<>();
  targetDataSources.put(DataSourceType.MASTER.name(),masterDataSource());
  targetDataSources.put(DataSourceType.SLAVE.name(),slaveDataSource());
  return new DynamicDataSource(masterDataSource(),targetDataSources);
 }
}

啟動類上添加註解

@Import({DataSourceConfig.class})
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

需要使用的方法上

@DataSource(value = DataSourceType.SLAVE)

DEMO

	@Select("select * from user")
  @DataSource(value = DataSourceType.SLAVE)
  List<User> selectUserList();

總結

到此這篇關於SpringBoot自定義註解使用讀寫分離Mysql資料庫的文章就介紹到這了,更多相關SpringBoot自定義註解使用讀寫分離Mysql內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!