十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这篇文章给大家介绍如何将Spring的动态数据源进行读写分离,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
我们提供的服务有:成都做网站、网站设计、微信公众号开发、网站优化、网站认证、吉林ssl等。为成百上千企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的吉林网站制作公司
一、创建基于ThreadLocal的动态数据源容器,保证数据源的线程安全性
package com.bounter.mybatis.extension; /** * 基于ThreadLocal实现的动态数据源容器,保证DynamicDataSource的线程安全性 * @author simon * */ public class DynamicDataSourceHolder { private static final ThreadLocaldataSourceHolder = new ThreadLocal<>(); public static void setDataSource(String dataSourceKey) { dataSourceHolder.set(dataSourceKey); } public static String getDataSource() { return dataSourceHolder.get(); } public static void clearDataSource() { dataSourceHolder.remove(); } }
二、定义Spring动态数据源扩展类,用来实现Master、Slave数据源动态切换
package com.bounter.mybatis.extension; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; /** * 自定义的Spring 动态数据源扩展类,用来实现Master、Slave数据源动态切换 * @author simon * */ public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { //使用DynamicDataSourceHolder保证线程安全 return DynamicDataSourceHolder.getDataSource(); } }
三、配置Master、Slave数据源
1. db.properties配置Master、Slave数据信息
# Master DB db.master.url=jdbc:MySQL://192.168.168.110:3306/bounter?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=PRC&useSSL=false db.master.username=bounter # AES encrypt,Base64 encode db.master.password=ZNhnEjauk3pecZxxS84ofA== # Slave DB db.slave.url=jdbc:mysql://192.168.168.111:3306/database?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=PRC&useSSL=false db.slave.username=bounter # AES encrypt,Base64 encode db.slave.password=jFYmt2f57RHhzItYDhWiSA==
2. Spring 配置文件配置Master、Slave连接池,动态数据源
四、创建数据源切面,通过AOP实现根据Dao层方法前缀动态选取读、写数据源
package com.bounter.mybatis.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.stereotype.Component; import com.bounter.mybatis.extension.DynamicDataSourceHolder; /** * 数据源切面,通过dao方法前缀决定访问读、写数据源 * @author simon * */ @Component @Aspect @EnableAspectJAutoProxy(proxyTargetClass = true) public class DataSourceAspect { //读库数据源key private static final String DATASOURCE_KEY_READ = "read"; //查询方法清单 String[] queryMethods = {"find","get","query","count","select"}; /** * dao层方法执行前选择数据源 * @param point */ @Before("execution(* com.bounter.mybatis.dao..*.*(..))") public void before(JoinPoint point) { // 获取到当前执行的方法名 String methodName = point.getSignature().getName(); //匹配查询方法 for(String queryMethod : queryMethods) { if(methodName.startsWith(queryMethod)) { //查询方法设置数据源为读库 DynamicDataSourceHolder.setDataSource(DATASOURCE_KEY_READ); break; } } } /** * dao层方法执行完后清空数据源选择 * @param point */ @After("execution(* com.bounter.mybatis.dao..*.*(..))") public void after(JoinPoint point) { DynamicDataSourceHolder.clearDataSource(); } }
关于如何将Spring的动态数据源进行读写分离就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。