• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

SpringBoot自定义注解使用读写分离Mysql数据库的实例教程

springboot 搞代码 4年前 (2022-01-09) 16次浏览 已收录 0个评论

需求场景

为了防止代码中有的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_H<div>本文来源gaodai.ma#com搞##代!^码@网3</div>OLDER.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();
  }
 }
}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:SpringBoot自定义注解使用读写分离Mysql数据库的实例教程

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址