1、配置一主两从数据库
具体操作过程:
CentOS7下的linux的MySQL5.7主从数据库的配置
地址: https://blog.youkuaiyun.com/m0_37459945/article/details/78577105?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-1.control&dist_request_id=1328680.64181.16164973606295389&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-1.control
2、具体过程
整体介绍:
1.创建数据库,并配置多数据源2.创建对应的 EntityMapper,Service,Controller3.根据“AbstractRoutingDataSource”类去实现子类“DynamicDataSource”。重点重写方法是“determineCurrentLookupKey”4.通过代码的方式实例化DataSource和DynamicDataSource5.创建注解“DynaminDataSource”,并为该注解编写切面类“DataSourceAspect”;
1. 创建数据库,并配置多数据源
•创建数据库SQL

•多数据源配置

2. 创建对应的 EntityMapper,Service,Controller
不进行详细讲解,有经验的小伙伴都会!

3. 根据“AbstractRoutingDataSource”类去实现子类“DynamicDataSource”
AbstractRoutingDataSource分析的讲解参考博客 AbstractRoutingDataSource分析(https://www.jianshu.com/p/edc282e6bbb9)
具体代码:
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;import javax.sql.DataSource;import java.util.Map;/*** 扩展 Spring 的 AbstractRoutingDataSource 抽象类,重写 determineCurrentLookupKey 方法* 动态数据源* determineCurrentLookupKey() 方法决定使用哪个数据源** @author RedAnts*/public class DynamicDataSource extends AbstractRoutingDataSource {/*** ThreadLocal 用于提供线程局部变量,在多线程环境可以保证各个线程里的变量独立于其它线程里的变量。* 也就是说 ThreadLocal 可以为每个线程创建一个【单独的变量副本】,相当于线程的 private static 类型变量。*/private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>();/*** 决定使用哪个数据源之前需要把多个数据源的信息以及默认数据源信息配置好** @param defaultTargetDataSource 默认数据源* @param targetDataSources 目标数据源*/public DynamicDataSource(DataSource defaultTargetDataSource, Map targetDataSources) {super.setDefaultTargetDataSource(defaultTargetDataSource);super.setTargetDataSources(targetDataSources);super.afterPropertiesSet();}@Overrideprotected Object determineCurrentLookupKey() {return getDataSource();}public static void setDataSource(String dataSource) {CONTEXT_HOLDER.set(dataSource);}public static String getDataSource() {return CONTEXT_HOLDER.get();}public static void clearDataSource() {CONTEXT_HOLDER.remove();}}
4. 通过代码的方式实例化DataSource和DynamicDataSource
直接上代码
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import javax.sql.DataSource;import java.util.HashMap;import java.util.Map;/*** 配置多数据源** @author RedAnts*/@Configurationpublic class DynamicDataSourceConfig {@Bean@ConfigurationProperties("spring.datasource.druid.master")public DataSource masterDataSource() {return DruidDataSourceBuilder.create().build();}@Bean@ConfigurationProperties("spring.datasource.druid.slave1")public DataSource slave1DataSource() {return DruidDataSourceBuilder.create().build();}@Bean@ConfigurationProperties("spring.datasource.druid.slave2")public DataSource slave2DataSource() {return DruidDataSourceBuilder.create().build();}@Bean@Primarypublic DynamicDataSource dataSource() {Map targetDataSources = new HashMap<>(5);targetDataSources.put(DataSourceNames.MASTER.getKey(), masterDataSource());targetDataSources.put(DataSourceNames.SLAVE1.getKey(), slave1DataSource());targetDataSources.put(DataSourceNames.SLAVE2.getKey(), slave2DataSource());return new DynamicDataSource(masterDataSource(), targetDataSources);}}
5. 创建注解“DynaminDataSource”,并为该注解编写切面类“DataSourceAspect”;
直接上代码
/*** 多数据源注解*
* 指定要使用的数据源,如果指定多数据源随机使用 * * @author RedAnts */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface DynaminDataSource { String[] names() default {};}
import cn.hutool.core.util.RandomUtil;import lombok.extern.slf4j.Slf4j;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.core.Ordered;import org.springframework.stereotype.Component;import java.lang.reflect.Method;/*** 多数据源,切面处理类** @author RedAnts*/@Slf4j@Aspect@Componentpublic class DataSourceAspect implements Ordered {@Pointcut("@annotation(cn.guangboyuan.dynamindatasource.config.datasource.DynaminDataSource)")public void dataSourcePointCut() {}@Around("dataSourcePointCut()")public Object around(ProceedingJoinPoint point) throws Throwable {MethodSignature signature = (MethodSignature) point.getSignature();Method method = signature.getMethod();DynaminDataSource ds = method.getAnnotation(DynaminDataSource.class);if (ds == null) {DynamicDataSource.setDataSource(DataSourceNames.MASTER.getKey());log.debug("set datasource is " + DataSourceNames.MASTER.getKey());} else {String[] names = ds.names();String target = DataSourceNames.MASTER.getKey();if (1 == names.length) {target = names[0];DynamicDataSource.setDataSource(target);} else if (2 == names.length) {int randomInt = RandomUtil.randomInt(0, 2);target = names[randomInt];DynamicDataSource.setDataSource(target);} else {DynamicDataSource.setDataSource(target);}log.debug("set datasource is " + target);}try {return point.proceed();} finally {DynamicDataSource.clearDataSource();log.debug("clean datasource");}}@Overridepublic int getOrder() {return 1;}}
注:DataSourceAspect 切面类中有使用随机数实现对两个从库的负载
6. 在Service层的实现类上使用注解

需要资料的小伙伴,点赞加收藏,关注我之后添加小助理vx:bjmsb0606006 即可获取免费下载方式
737

被折叠的 条评论
为什么被折叠?



