一、创建基于ThreadLocal的动态数据源容器,保证数据源的线程安全性
package com.bounter.mybatis.extension;
/**
* 基于ThreadLocal实现的动态数据源容器,保证DynamicDataSource的线程安全性
* @author simon
*
*/
public class DynamicDataSourceHolder {
private static final ThreadLocal<String> dataSourceHolder = 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连接池,动态数据源
<!-- Master数据源 -->
<bean id="masterDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${db.master.url}" />
<property name="username" value="${db.master.username}" />
<property name="password" value="${db.master.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="20" />
<property name="minIdle" value="1" />
<property name="maxActive" value="40" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 'x'" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat" />
</bean>
<!-- Slave数据源 -->
<bean id="slaveDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${db.slave.url}" />
<property name="username" value="${db.slave.username}" />
<property name="password" value="${db.slave.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="20" />
<property name="minIdle" value="1" />
<property name="maxActive" value="40" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 'x'" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat" />
</bean>
<!-- 自定义动态数据源 -->
<bean id="dataSource" class="com.bounter.mybatis.extension.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- 配置读写数据源 -->
<entry value-ref="masterDataSource" key="write"></entry>
<entry value-ref="slaveDataSource" key="read"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="masterDataSource"></property>
</bean>
四、创建数据源切面,通过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();
}
}
github源码地址:https://github.com/13babybear/bounter-mybatis
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Spring
# 数据源
# 读写分离
# 详解Nginx服务器中HTTP Headers相关的模块配置使用
# Spring配置动态数据源实现读写分离的方法
# Mybatis注解实现多数据源读写分离详解
# resty更新header控制api版本数据源读写分离
# 自定义
# 池中
# 多久
# 完后
# 配置文件
# 大家多多
# 清空
# 连接池
# mysql
# url
# DB
# master
# useUnicode
# true
# Object
# determineCurrentLookupKey
# protected
# extends
# Override
# properties
相关文章:
如何通过VPS建站实现广告与增值服务盈利?
如何在万网ECS上快速搭建专属网站?
如何在建站之星绑定自定义域名?
建站之星展会模板:智能建站与自助搭建高效解决方案
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
兔展官网 在线制作,怎样制作微信请帖?
清单制作人网站有哪些,近日“兴风作浪的姑奶奶”引起很多人的关注这是什么事情?
头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?
贸易公司网站制作流程,出口贸易网站设计怎么做?
如何通过FTP空间快速搭建安全高效网站?
整蛊网站制作软件,手机不停的收到各种网站的验证码短信,是手机病毒还是人为恶搞?有这种手机病毒吗?
SAX解析器是什么,它与DOM在处理大型XML文件时有何不同?
如何在Golang中使用replace替换模块_指定本地或远程路径
深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?
已有域名如何免费搭建网站?
如何快速搭建虚拟主机网站?新手必看指南
上海网站制作开发公司,上海买房比较好的网站有哪些?
北京制作网站的公司排名,北京三快科技有限公司是做什么?北京三快科技?
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
在线制作视频的网站有哪些,电脑如何制作视频短片?
网站制作员失业,怎样查看自己网站的注册者?
如何选择靠谱的建站公司加盟品牌?
教育培训网站制作流程,请问edu教育网站的域名怎么申请?
南阳网站制作公司推荐,小学电子版试卷去哪里找资源好?
如何通过服务器快速搭建网站?完整步骤解析
Python路径拼接规范_跨平台处理说明【指导】
Android自定义控件实现温度旋转按钮效果
制作农业网站的软件,比较好的农业网站推荐一下?
家具网站制作软件,家具厂怎么跑业务?
建站之星ASP如何实现CMS高效搭建与安全管理?
想学网站制作怎么学,建立一个网站要花费多少?
网站制作与设计教程,如何制作一个企业网站,建设网站的基本步骤有哪些?
建站之星好吗?新手能否轻松上手建站?
制作假网页,招聘网的薪资待遇,会有靠谱的吗?一面试又各种折扣?
宝塔面板创建网站无法访问?如何快速排查修复?
如何制作算命网站,怎么注册算命网站?
手机网站制作与建设方案,手机网站如何建设?
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
制作网站建设的公司有哪些,网站建设比较好的公司都有哪些?
公司网站制作费用多少,为公司建立一个网站需要哪些费用?
表情包在线制作网站免费,表情包怎么弄?
,怎么用自己头像做动态表情包?
潮流网站制作头像软件下载,适合母子的网名有哪些?
百度网页制作网站有哪些,谁能告诉我百度网站是怎么联系?
如何在IIS7中新建站点?详细步骤解析
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
如何选择服务器才能高效搭建专属网站?
香港服务器建站指南:免备案优势与SEO优化技巧全解析
Android滚轮选择时间控件使用详解
建站主机是什么?如何选择适合的建站主机?
*请认真填写需求信息,我们会在24小时内与您取得联系。