SpringBoot自定義注解使用讀寫分離Mysql數(shù)據(jù)庫的實例教程
需求場景
為了防止代碼中有的SQL慢查詢,影響我們線上主數(shù)據(jù)庫的性能。我們需要將sql查詢操作切換到從庫中進行。為了使用方便,將自定義注解的形式使用。
mysql導入的依賴
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency>
代碼實現(xiàn)
配置文件
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
/**
* 數(shù)據(jù)源類型枚舉
* @author yangjc01
* @create 2020/11/02
*/
public enum DataSourceType {
/**
* 主庫,主要進行寫操作
*/
MASTER,
/**
* 從庫,進行讀操作
*/
SLAVE
}
DynamicDataSource
/**
* 動態(tài)數(shù)據(jù)源
* @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<>();
/**
* 設(shè)置數(shù)據(jù)源的變量
*/
public static void setDateSourceType(String dsType) {
CONTEXT_HOLDER.set(dsType);
}
/**
* 獲得數(shù)據(jù)源的變量
*/
public static String getDateSourceType() {
return CONTEXT_HOLDER.get();
}
/**
* 清空數(shù)據(jù)源變量
*/
public static void clearDateSourceType() {
CONTEXT_HOLDER.remove();
}
}
DataSource 注解
/**
* @author yangjc01
* @create 2020/11/01
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
/**
* 切換數(shù)據(jù)源
*/
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 {
// 銷毀數(shù)據(jù)源 在執(zhí)行方法之后
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();
總結(jié)
到此這篇關(guān)于SpringBoot自定義注解使用讀寫分離Mysql數(shù)據(jù)庫的文章就介紹到這了,更多相關(guān)SpringBoot自定義注解使用讀寫分離Mysql內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring MVC中使用Controller如何進行重定向
這篇文章主要介紹了Spring MVC中使用Controller如何進行重定向操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
Java執(zhí)行cmd命令兩種實現(xiàn)方法解析
這篇文章主要介紹了Java執(zhí)行cmd命令兩種實現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-07-07
Java中parallelStream().forEach()的踩坑日記
本文主要介紹了Java中parallelStream().forEach()的踩坑日記,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-06-06

