在之前的文章中讲述过数据库主从同步和通过注解来为部分方法切换数据源实现读写分离

注解实现读写分离: http://www.cnblogs.com/xiaochangwei/p/4961807.html

mysql主从同步: http://www.cnblogs.com/xiaochangwei/p/4824355.html

如果项目所有读操作和写操作操作不同的数据库,完全读写分离,那么可以简单的通过mybaits的plugins来实现

读写分离的实现数据源切换部分,完全依靠 org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource,这是spring提供的抽象数据源方法

1.首先定义数据源切换方法

package net.zicp.xiaochangwei.web.multipeDataSource;

/**
* @author 肖昌伟 E-mail:317409898@qq.com
* @version 创建时间:2016年6月23日 下午2:04:33
*
*/
public class DataSourceSwith {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static final String UPDATE = "UPDATE";
public static final String QUERY = "QUERY"; public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
} public static String getDataSource() {
return (String) contextHolder.get();
} public static void clearDataSource() {
contextHolder.remove();
}
}

2.继承抽象数据源接口并重写方法确定用哪一个数据源

package net.zicp.xiaochangwei.web.multipeDataSource;

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

/**
* @author 肖昌伟 E-mail:317409898@qq.com
* @version 创建时间:2016年6月23日 下午2:04:01
*
*/
public class DataSources extends AbstractRoutingDataSource { @Override
protected Object determineCurrentLookupKey() {
return DataSourceSwith.getDataSource();
} }

3.配置数据源并指明数据源对应的key

<bean id="dataSource" class="net.zicp.xiaochangwei.web.multipeDataSource.DataSources">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSourceUpdate" key="UPDATE"></entry>
<entry value-ref="dataSourceQuery" key="QUERY"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSourceUpdate"></property>
</bean>

4.配置mybatis plugins(只看红色部分,除mybatis常规配置外,其它部分配置是分表用的)

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis/Configuration.xml" />
<!-- mapper配置路径 -->
<property name="mapperLocations">
<list>
<value>classpath:mybatis/*Mapper.xml</value>
</list>
</property>
<property name="plugins">
<array>
<bean class="net.zicp.xiaochangwei.web.interceptors.MybatisInterceptor">
<property name="shardTableName" value="t_feed_back"/>
</bean>
</array>
</property>
</bean>

5.实现mybatisInterceptor

package net.zicp.xiaochangwei.web.interceptors;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import net.zicp.xiaochangwei.web.multipeDataSource.DataSourceSwith;
import net.zicp.xiaochangwei.web.utils.DateUtils; import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.MappedStatement.Builder;
import org.apache.ibatis.mapping.SqlSource;
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.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectorFactory;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean; /**
* @author 肖昌伟 E-mail:317409898@qq.com
* @version 创建时间:2016年6月23日 上午9:04:47
*
*/
@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, CacheKey.class, BoundSql.class }),
@Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) })
public class MybatisInterceptor implements Interceptor, InitializingBean { @Override
public Object intercept(Invocation invocation) throws Throwable {
Method method = invocation.getMethod(); Object[] arguments = invocation.getArgs();
MappedStatement ms = (MappedStatement) arguments[MAPPED_STATEMENT_INDEX];
BoundSql boundSql = ms.getBoundSql(arguments[PARAMETER_INDEX]); log.info("对数据库执行:" + method.getName() + " 操作, sql为: "+ boundSql.getSql()); // 切换数据源
if ("query".equals(method.getName())) {
DataSourceSwith.setDataSource(DataSourceSwith.QUERY);
} else {
DataSourceSwith.setDataSource(DataSourceSwith.UPDATE);
}

配置两个不同的数据源试试看吧

mybatis plugins实现项目【全局】读写分离的更多相关文章

  1. Spring Boot + Mybatis 多数据源配置实现读写分离

    本文来自网易云社区 作者:王超 应用场景:项目中有一些报表统计与查询功能,对数据实时性要求不高,因此考虑对报表的统计与查询去操作slave db,减少对master的压力. 根据网上多份资料测试发现总 ...

  2. mybatis通过插件方式实现读写分离

    原理:通过自定义mybatis插件,拦截Executor的update和query方法,检查sql中有select就用读的库,其它的用写的库(如果有调用存储过程就另当别论了) @Intercepts( ...

  3. SpringMVC4+MyBatis+SQL Server2014实现读写分离

    前言 基于mybatis的AbstractRoutingDataSource和Interceptor用拦截器的方式实现读写分离,根据MappedStatement的boundsql,查询sql的sel ...

  4. J2EE 项目读写分离

    先回答下 1.为啥要读写分离? 大家都知道最初开始,一个项目对应一个数据库,基本是一对一的,但是由于后来用户及数据还有访问的急剧增多, 系统在数据的读写上出现了瓶颈,为了让提高效率,想读和写不相互影响 ...

  5. 基于Spring和Mybatis拦截器实现数据库操作读写分离

    首先需要配置好数据库的主从同步: 上一篇文章中有写到:https://www.cnblogs.com/xuyiqing/p/10647133.html 为什么要进行读写分离呢? 通常的Web应用大多数 ...

  6. Spring aop应用之实现数据库读写分离

    Spring加Mybatis实现MySQL数据库主从读写分离 ,实现的原理是配置了多套数据源,相应的sqlsessionfactory,transactionmanager和事务代理各配置了一套,如果 ...

  7. java 读写分离

    源码地址:http://git.oschina.net/xiaochangwei 先回答下 1.为啥要读写分离? 大家都知道最初开始,一个项目对应一个数据库,基本是一对一的,但是由于后来用户及数据还有 ...

  8. ShardingJdbc-分表;分库;分库分表;读写分离;一主多从+分表;一主多从+分库分表;公共表;数据脱敏;分布式事务

    目录 创建项目 分表 导包 表结构 Yml 分库 Yml Java 分库分表 数据库 Yml 读写分离 数据库 Yml 其他 只请求主库 读写分离判断逻辑代码 一主多从+分表 Yml 一主多从+分库分 ...

  9. Spring + Mybatis项目实现数据库读写分离

    主要思路:通过实现AbstractRoutingDataSource类来动态管理数据源,利用面向切面思维,每一次进入service方法前,选择数据源. 1.首先pom.xml中添加aspect依赖 & ...

随机推荐

  1. NiceMark——我的Markdown编辑器

    NiceMark--我的Markdown编辑器 闲来无事,写了一个Markdown编辑器.基于electron,完全采用Web前段技术(Html,css,JavaScript)实现.代码已托管在Git ...

  2. C++对C的函数拓展

    一,内联函数 1.内联函数的概念 C++中的const常量可以用来代替宏常数的定义,例如:用const int a = 10来替换# define a 10.那么C++中是否有什么解决方案来替代宏代码 ...

  3. 【.net 深呼吸】程序集的热更新

    当一个程序集被加载使用的时候,出于数据的完整性和安全性考虑,程序集文件(在99.9998%的情况下是.dll文件)会被锁定,如果此时你想更新程序集(实际上是替换dll文件),是不可以操作的,这时你得把 ...

  4. iOS开发之App间账号共享与SDK封装

    上篇博客<iOS逆向工程之KeyChain与Snoop-it>中已经提到了,App间的数据共享可以使用KeyChian来实现.本篇博客就实战一下呢.开门见山,本篇博客会封装一个登录用的SD ...

  5. Oracle 数据库语句大全

    Oracle数据库语句大全 ORACLE支持五种类型的完整性约束 NOT NULL (非空)--防止NULL值进入指定的列,在单列基础上定义,默认情况下,ORACLE允许在任何列中有NULL值. CH ...

  6. maven-sprigmvc-mybatis配置

    pom.xml配置 <?xml version="1.0"?> <project xsi:schemaLocation="http://maven.ap ...

  7. Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出现的问题

    现互联网公司后端架构常用到Spring+SpringMVC+MyBatis,通过Maven来构建.通过学习,我已经掌握了基本的搭建过程,写下基础文章为而后的深入学习奠定基础. 首先说一下这篇文章的主要 ...

  8. JavaScript求两个数字之间所有数字的和

    这是在fcc上的中级算法中的第一题,拉出来的原因并不是因为有什么好说的,而是我刚看时以为是求两个数字的和, 很显然错了.我感觉自己的文字理解能力被严重鄙视了- -.故拉出来折腾折腾. 要求: 给你一个 ...

  9. 微信小程序开发日记——高仿知乎日报(下)

    本人对知乎日报是情有独钟,看我的博客和github就知道了,写了几个不同技术类型的知乎日报APP 要做微信小程序首先要对html,css,js有一定的基础,还有对微信小程序的API也要非常熟悉 我将该 ...

  10. SharePoint 2016 入门视频教程

    之前一直有朋友让自己录一些SharePoint的入门视频,之前没有太多时间,一个巧合的机会收到CSDN学院的邮件,可以在CSDN上发布视频教程,自己就录了一些.说起录视频也是蛮辛苦的,每天下班吃完饭要 ...