import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource{

	@Override
protected Object determineCurrentLookupKey(){
return DynamicDataSourceHolder.getDbType();
}
}

  

import org.slf4j.LoggerFactory;
import org.slf4j.Logger; 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";
public static String getDbType(){
String db=contextHolder.get();
if(db==null){
db=DB_MASTER;
}
return db;
}
public static void setDbType(String str){
logger.debug("所使用的数据源为:"+str);
contextHolder.set(str);
}
//清理连接类型
public static void clearDBType(){
contextHolder.remove();
} }

  

import java.util.Locale;
import java.util.Properties;
import java.util.concurrent.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.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.support.TransactionSynchronizationManager; /**
* @author wls
*
*/

@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\\u0020.*|.8update\\u0020.*"; @Override
public Object intercept(Invocation invocation) throws Throwable {
//判断当前是不是事物
boolean synchronizatioinActive=TransactionSynchronizationManager.
isActualTransactionActive();
Object[] objects= invocation.getArgs();
MappedStatement ms=(MappedStatement)objects[0];
String lookupKey=DynamicDataSourceHolder.DB_MASTER;
if(synchronizatioinActive!=true){ //读方法
if(ms.getSqlCommandType().equals(SqlCommandType.SELECT)){
//SELECT_KEY为自增id查询主键SELECT LAST_INSERT_ID(),使用主库
if(ms.getId().contains(SelectKeyGenerator.SELECT_KEY_SUFFIX)){
lookupKey=DynamicDataSourceHolder.DB_MASTER;
}else{
BoundSql boundSql=ms.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,SqlCommanType[{}]" ,ms.getId(),lookupKey,
ms.getSqlCommandType().name());;
DynamicDataSourceHolder.setDbType(lookupKey);
return invocation.proceed();
} @Override //返回封装好的对象
public Object plugin(Object target) {
// TODO Auto-generated method stub
if(target instanceof Executor){
return Plugin.wrap(target, this);
}else{
return target;
}
} @Override
public void setProperties(Properties arg0) {
// TODO Auto-generated method stub }
}

  配置:

mybatis配置:

<plugins>
<plugin interceptor="split.DynamicDataSourceInterceptor"></plugin>
</plugins>

  

Java Mybatis实现主从同步的更多相关文章

  1. RocketMQ 主从同步若干问题答疑

    目录 1.初识主从同步 2.提出问题 3.原理探究 3.1 RocketMQ主从读写分离机制 3.2 消息消费进度同步机制 4.总结 温馨提示:建议参考代码RocketMQ4.4版本,4.5版本引入了 ...

  2. windows下mysql 主从同步

    半路出家到Java,刚开始听说到说程序支持读写分离感觉特别高大上,也一直没接触 偶然的机会接触到了,就一定得记下来. 今天先讲讲数据库的主从同步,两个好处: 一是读写分离可以用上.比如 写操作就写到主 ...

  3. MySQL主从同步和读写分离的配置

    主服务器:192.168.1.126 从服务器:192.168.1.163 amoeba代理服务器:192.168.1.237 系统全部是CentOS 6.7 1.配置主从同步 1.1.修改主服务器( ...

  4. mysql主从同步+mycat读写分离+.NET程序连接mycat代理

    背景 最近新项目需要用到mysql数据库,并且由于数据量大的原因,故打算采用1主1从(主数据库负责增.删.改操作:从数据库负责查操作)的数据库架构,在实现主从之后还要实现读写分离的代理,在网上搜寻了很 ...

  5. 重启mysql主从同步mongodb(tungsten-replicator)

    1. 连接mysql mysql -uroot -p;(mysql从库) 输入数据库密码 2. 停止主同步 mysql> stop slave; 3. 清数据 将mongo库数据清空 4. 杀主 ...

  6. Redis主从同步分析(转)

    一.Redis主从同步原理 1.1 Redis主从同步的过程 配置好slave服务器连接的master后,slave会建立和master的连接,然后发送sync命令.无论是第一次同步建立的连接还是连接 ...

  7. mysql 主从同步-读写分离

    主从同步与读写分离测试 一.  实验环境(主从同步) Master                   centos 7.3              192.168.138.13 Slave     ...

  8. Redis主从同步分析

    一.Redis主从同步原理1.1 Redis主从同步的过程配置好slave服务器连接的master后,slave会建立和master的连接,然后发送sync命令.无论是第一次同步建立的连接还是连接断开 ...

  9. 这次一定要教会你搭建Redis集群和MySQL主从同步(非Docker)

    前言 一直都想自己动手搭建一个Redis集群和MySQL的主从同步,当然不是依靠Docker的一键部署(虽然现在企业开发用的最多的是这种方式),所以本文就算是一个教程类文章吧,但在动手搭建之前,会先聊 ...

随机推荐

  1. js 实现数据结构 -- 栈

    原文: 在 Javascript 中学习数据结构与算法. 概念: 栈是一种遵从先进后出 (LIFO) 原则的有序集合:新添加的或待删除的元素都保存在栈的末尾,称作栈顶,另一端为栈底.在栈里,新元素都靠 ...

  2. git 学习(3) ----- 代码共享和多人协作

    当我们开发项目的时候,项目会越来越大,就有可能需要其它同事进行参与,甚至进行开源,这时就需要找一个地方把代码存放起来,好供其它人下载并开发.这个地方,最好放到服务器上,因为只要能上网,就可以获取到, ...

  3. 在本机使用虚拟机安装一个linux系统,并搭建ftp服务器

    一.Linux基础使用:linux服务器环境搭建(FTP服务器), 在本机使用虚拟机安装一个linux系统,并搭建ftp服务器,要求能使用ftp服务将本机文件到保存linux虚拟机上 资料: VMwa ...

  4. Django 信号

    信号 Django 提供一个“信号分发器”,允许解耦的应用在框架的其它地方发生操作时会被通知到. 简单来说,信号允许特定的sender通知一组receiver某些操作已经发生. 这在多处代码和同一事件 ...

  5. BZOJ2616PERIODNI

    题目描述 给定一个N列的表格,每列的高度各不相同,但底部对齐,然后向表格中填入K个相同的数,填写时要求不能有两个数在同一列,或同一行,下图中b是错误的填写,a是正确的填写,因为两个a虽然在同一行,但它 ...

  6. 忘掉Ghost!利用Win10自带功能,玩转系统备份&恢复 -- 关于系统恢复的深度思考

    上一篇文章讲了,系统可以正常启动,如何从D盘恢复系统到C盘的情况. 如果系统不能启动,要怎么去恢复系统,恢复后会是什么结果? 先说明系统结构: 系统版本:Windows 10 (1709) 硬盘1(5 ...

  7. 前端ajax请求百度地图api

    $.ajax({ type: "get", url: 'http://api.map.baidu.com/place/v2/search', data:{ ak:'您的ak', q ...

  8. (转)Java8内存模型—永久代(PermGen)和元空间(Metaspace)

    背景:介绍java8中永久代到元空间的转变. Java8内存模型—永久代(PermGen)和元空间(Metaspace) 一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法 ...

  9. JavaScript中大数相加的解法

    一.两个大正整数字符串相加 在JavaScript中,数值类型满足不了大数据容量计算,可以用字符串进行操作 function add(strNum1, strNum2) { // 将传进来的数字/数字 ...

  10. 20175209 《Java程序设计》第二周学习总结

    教材学习内容总结 二三章介绍的主要是Java中的基本知识:数据类型及转换,数据的输入输出,数组,运算符表达式,和常见的一些语句,这些都是帮助我们学习Java的基本知识,而这些知识很大一部分都和C语言相 ...