SpringBoot中如何实现自定义注解配合读写分离访问Mysql数据库?

2026-05-16 00:421阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计686个文字,预计阅读时间需要3分钟。

SpringBoot中如何实现自定义注解配合读写分离访问Mysql数据库?

需求场景:为防止代码中存在SQL慢查询,影响线上主数据库的性能。我们需要将SQL查询操作切换到从库中执行。

解决方案:- 使用自定义注解的格式来方便使用。- MySQL导入的依赖关系:`depends`

需求场景

为了防止代码中有的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); } }

启动类上添加注解

SpringBoot中如何实现自定义注解配合读写分离访问Mysql数据库?

@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内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!

本文共计686个文字,预计阅读时间需要3分钟。

SpringBoot中如何实现自定义注解配合读写分离访问Mysql数据库?

需求场景:为防止代码中存在SQL慢查询,影响线上主数据库的性能。我们需要将SQL查询操作切换到从库中执行。

解决方案:- 使用自定义注解的格式来方便使用。- MySQL导入的依赖关系:`depends`

需求场景

为了防止代码中有的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); } }

启动类上添加注解

SpringBoot中如何实现自定义注解配合读写分离访问Mysql数据库?

@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内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!