首先,设置一个拦截器,拦截数据库操作,判断类型,动态选择数据源
DynamicDataSourceinterceptor.java

package com.mlr.dao.split;import java.util.Locale;
import java.util.Properties;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.keygen.SelectKeyGenerator;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.support.TransactionSynchronizationManager;@Intercepts({@Signature(type = Executor.class,method = "update",args={MappedStatement.class,Object.class}),@Signature(type = Executor.class,method = "query",args={MappedStatement.class,Object.class,RowBounds.class, ResultHandler.class})})
public class DynamicDataSourceinterceptor implements Interceptor {private static Logger logger = LoggerFactory.getLogger(DynamicDataSourceinterceptor.class);private static final String REGEX = ".*insert\\u0020.*|.*delete\\0020.*|.*update\\u0020.*";public java.lang.Object intercept(Invocation invocation) throws Throwable {boolean synchronizationActive = TransactionSynchronizationManager.isSynchronizationActive();//对于不是事务管理的操作Object[] objects = invocation.getArgs();String lookupKey =  DynamicDataSourceHolder.DB_MASTER;//获取操作类型MappedStatement mappedStatement = (MappedStatement) objects[0];if (synchronizationActive != true) {if (mappedStatement.getSqlCommandType().equals(SqlCommandType.SELECT)) {if (mappedStatement.getId().contains(SelectKeyGenerator.SELECT_KEY_SUFFIX)) {lookupKey = DynamicDataSourceHolder.DB_MASTER;} else {BoundSql boundSql = mappedStatement.getSqlSource().getBoundSql(objects[1]);String sql = boundSql.getSql().toLowerCase(Locale.CHINA).replaceAll("[\\t\\n\\r]", "");//符合正则用主库,不符合用从库if (sql.matches(REGEX)) {lookupKey = DynamicDataSourceHolder.DB_MASTER;} else {lookupKey = DynamicDataSourceHolder.DB_SLAVE;}}}}//对于事务管理都用主库else{lookupKey = DynamicDataSourceHolder.DB_MASTER;}logger.debug("设置方法[{}],use[{}]Strategy,SqlCommandType[{}]...",mappedStatement.getId(),lookupKey,mappedStatement.getSqlCommandType().name());DynamicDataSourceHolder.setDBType(lookupKey);return invocation.proceed();}/*** Executor支持增删改查操作,当操作时候拦截下来判断用哪个数据源*/public java.lang.Object plugin(java.lang.Object target) {if (target instanceof Executor) {return Plugin.wrap(target, this);} else {return target;}}public void setProperties(Properties properties) {}
}

DynamicDataSourceHolder.java

package com.mlr.dao.split;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class DynamicDataSourceHolder {private static Logger logger = LoggerFactory.getLogger(DynamicDataSourceHolder.class);private static ThreadLocal<String> contextHolder = new ThreadLocal<String>();public static final String DB_MASTER = "master";public static final String DB_SLAVE = "slave";/*** 获取类型* @return*/public static String getDBType() {String db = contextHolder.get();if (db == null) {db = DB_MASTER;}return db;}/*** 设置连接类型* @param str*/public static void setDBType(String str) {logger.debug("所使用的数据源为" + str);contextHolder.set(str);}/*** 清理连接类型* @param str*/public static void clearDBType(String str) {contextHolder.remove();}}

DynamicDataSource .java

package com.mlr.dao.split;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource{protected Object determineCurrentLookupKey() {return DynamicDataSourceHolder.getDBType();}
}

然后配置mybatis-config.xml中添加拦截器

<plugins><plugin interceptor="com.mlr.dao.split.DynamicDataSourceinterceptor"></plugin></plugins>

在spring-dao.xml中配置数据源

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 配置整合mybatis过程 --><!-- 1.配置数据库相关参数properties的属性:${url} --><context:property-placeholder location="classpath:jdbc.properties"/><!-- 2.数据库连接池 --><bean id="abstractDataSource" abstract="true" destroy-method="close"class="com.mchange.v2.c3p0.ComboPooledDataSource"><!-- 配置连接池属性 --><property name="driverClass" value="${jdbc.driver}"/><property name="jdbcUrl" value="${jdbc.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/><!-- c3p0连接池的私有属性 --><property name="maxPoolSize" value="30"/><property name="minPoolSize" value="10"/><!-- 关闭连接后不自动commit --><property name="autoCommitOnClose" value="false"/><!-- 获取连接超时时间 --><property name="checkoutTimeout" value="10000"/><!-- 当获取连接失败重试次数 --><property name="acquireRetryAttempts" value="2"/></bean><!--主库数据源--><bean id="master" parent="abstractDataSource"><property name="driverClass" value="${jdbc.driver}"/><property name="jdbcUrl" value="${jdbc.master.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--从库数据源--><bean id="slave" parent="abstractDataSource"><property name="driverClass" value="${jdbc.driver}"/><property name="jdbcUrl" value="${jdbc.slave.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--配置动态数据源,这里targetDataSource就是路由数据源所对应名称--><bean id="dynamicDataSource" class="com.mlr.dao.split.DynamicDataSource"><property name="targetDataSources"><map><entry  value-ref="master" key="master"></entry><entry key="master" value-ref="master"></entry></map></property>
</bean><!--懒加载,程序运行后判断sql-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy"><property name="targetDataSource"><ref bean="dynamicDataSource"></ref></property>
</bean><!-- 3.配置SqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- 扫描entity包 使用别名 -->
<property name="typeAliasesPackage" value="com.mlr.entity"/>
<!-- 扫描sql配置文件:mapper需要的xml文件 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean><!-- 4.配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 给出需要扫描Dao接口包 -->
<property name="basePackage" value="com.mlr.dao"/>
</bean></beans>

最近在整理一些资源工具,放在网站分享 http://tools.maqway.com
欢迎关注公众号:麻雀唯伊 , 不定时更新资源文章,生活优惠,或许有你想看的

MySQL数据库读写分离相关推荐

  1. mybatis获取mysql源数据类型_spring集成mybatis实现mysql数据库读写分离

    前言 在网站的用户达到一定规模后,数据库因为负载压力过高而成为网站的瓶颈.幸运的是目前大部分的主流数据库都提供主从热备功能,通过配置两台数据库主从关系,可以将一台数据库的数据更新同步到另一台服务器上. ...

  2. mysql数据库字段变形_详解如何利用amoeba(变形虫)实现mysql数据库读写分离

    摘要:这篇MySQL栏目下的"详解如何利用amoeba(变形虫)实现mysql数据库读写分离",介绍的技术点是"MySQL数据库.数据库读写分离.amoeba.MySQL ...

  3. Python开发之:Django基于Docker实现Mysql数据库读写分离、集群、主从同步详解 | 原力计划...

    作者 | Pythonicc 责编 | 王晓曼 出品 | CSDN博客 简介 1.什么是数据库读写分离 读写分离,基本的原理是让主数据库处理事务性增.改.删操作(INSERT.UPDATE.DELET ...

  4. ceph集群和数据库到底是储存数据_Python开发之:Django基于Docker实现Mysql数据库读写分离、集群、主从同步详解 | 原力计划...

    作者 | Pythonicc责编 | 王晓曼出品 | CSDN博客简介1.什么是数据库读写分离读写分离,基本的原理是让主数据库处理事务性增.改.删操作(INSERT.UPDATE.DELETE),而从 ...

  5. 利用mycat实现mysql数据库读写分离

    1.这里是在mysql主从复制实现的基础上,利用mycat做读写分离,架构图如下: 2.Demo 2.1 在mysql master上创建数据库创建db1 2.2 在数据库db1创建表student ...

  6. mycat定时向mysql存储数据_【实战演练】Linux操作系统20-MyCat实现Mysql数据库读写分离与自动切换...

    #本文欢迎转载,转载请注明出处和作者. 理论部分,详见:繁星亮与鲍包包:[理论研究]业务系统高可用及负载均衡​zhuanlan.zhihu.com 本篇主要实现"8.Mysql读写分离&qu ...

  7. amoeba mysql exists_Amoeba实现MySQL数据库读写分离

    一 环境以及软件版本: 系统:CentOS Linux release 7.2.1511 (Core) MySQL:Server version: 5.6.33 Amoeba:amoeba-mysql ...

  8. Linux安装Mycat1.6.7.6实现Mysql数据库读写分离

    1.Mycat简介 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务.ACID.可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群 一个 ...

  9. 你如何理解mysql的读写分离_面试官:谈谈你对Mysql数据库读写分离的了解,并且有哪些注意事项?...

    这篇文章讲述的不是Mysql具体的如何实现读写分离,而是指什么时候需要上读写分离,及其相关的注意事项. 因为用户的增多,数据的增多,单机的数据库往往支撑不住快速发展的业务,所以数据库集群就产生了!今天 ...

  10. yii2 mysql in_yii2 mysql数据库读写分离配置

    复制和读写分离(Replication and Read-Write Splitting) 许多数据库支持数据库复制来获得更好的数据库可用性, 以及更快的服务器响应时间.通过数据库复制功能, 数据从所 ...

最新文章

  1. 如何从阿里云Code升级至Codeup
  2. PHP7天前的时间戳
  3. step4 . day6 线程与线程的创建
  4. MIPI DSI协议介绍
  5. HALCON示例程序inspect_bga.hdev测量bga焊点缺陷
  6. Android之自定义ContentProvider详解
  7. nginx php 跨域访问权限,nginx + php 实现跨域请求填坑笔记
  8. System.Drawing.Color转System.Windows.Media.Color
  9. tomcat 配置https安全认证协议报错解决方案
  10. SQL必知必会-事物处理
  11. Docker 私有仓库registry
  12. php对接海康视频教程_海康安防管理平台Web视频对接
  13. win10桌面无法新建文件夹解除管理员权限方法
  14. python参数类型为uint8_Python 改变数组类型为uint8的实现
  15. 数值求解一维定态薛定谔方程
  16. 计算机丢失MSVCR100.dll文件的解决办法
  17. 关于OpenCV for Python入门-face_recognition实现人脸识别
  18. 戴尔计算机更新程序,戴尔电脑如何更新显卡驱动 其实很简单-电脑显卡怎么升级...
  19. 移动端长按事件 vue
  20. ubuntu DNS修改

热门文章

  1. Android 启用/禁用通过otg连接T卡功能
  2. 如何使用SFC / SCANNOW修复Windows系统文件
  3. 实例示范( 泰坦尼克沉船数据分析之一)
  4. 包头中考计算机考试试题2020,2020年内蒙古包头中考数学试卷附答案解析版.docx...
  5. 央行紧急通知:你在用的这种支付方式将有重大变化
  6. CCS6-28335新建工程
  7. 解决花生壳 Aira2 路由器 树莓派中的aira2状态未连接的思路
  8. 更换头像的测试点(站在 app 的角度来分析)
  9. 手工制作绿色版 QQ 和 TM
  10. 构建ceph可视化监控(prometheu+grafana)