mybatis plugins实现项目【全局】读写分离
在之前的文章中讲述过数据库主从同步和通过注解来为部分方法切换数据源实现读写分离
注解实现读写分离: 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实现项目【全局】读写分离的更多相关文章
- Spring Boot + Mybatis 多数据源配置实现读写分离
本文来自网易云社区 作者:王超 应用场景:项目中有一些报表统计与查询功能,对数据实时性要求不高,因此考虑对报表的统计与查询去操作slave db,减少对master的压力. 根据网上多份资料测试发现总 ...
- mybatis通过插件方式实现读写分离
原理:通过自定义mybatis插件,拦截Executor的update和query方法,检查sql中有select就用读的库,其它的用写的库(如果有调用存储过程就另当别论了) @Intercepts( ...
- SpringMVC4+MyBatis+SQL Server2014实现读写分离
前言 基于mybatis的AbstractRoutingDataSource和Interceptor用拦截器的方式实现读写分离,根据MappedStatement的boundsql,查询sql的sel ...
- J2EE 项目读写分离
先回答下 1.为啥要读写分离? 大家都知道最初开始,一个项目对应一个数据库,基本是一对一的,但是由于后来用户及数据还有访问的急剧增多, 系统在数据的读写上出现了瓶颈,为了让提高效率,想读和写不相互影响 ...
- 基于Spring和Mybatis拦截器实现数据库操作读写分离
首先需要配置好数据库的主从同步: 上一篇文章中有写到:https://www.cnblogs.com/xuyiqing/p/10647133.html 为什么要进行读写分离呢? 通常的Web应用大多数 ...
- Spring aop应用之实现数据库读写分离
Spring加Mybatis实现MySQL数据库主从读写分离 ,实现的原理是配置了多套数据源,相应的sqlsessionfactory,transactionmanager和事务代理各配置了一套,如果 ...
- java 读写分离
源码地址:http://git.oschina.net/xiaochangwei 先回答下 1.为啥要读写分离? 大家都知道最初开始,一个项目对应一个数据库,基本是一对一的,但是由于后来用户及数据还有 ...
- ShardingJdbc-分表;分库;分库分表;读写分离;一主多从+分表;一主多从+分库分表;公共表;数据脱敏;分布式事务
目录 创建项目 分表 导包 表结构 Yml 分库 Yml Java 分库分表 数据库 Yml 读写分离 数据库 Yml 其他 只请求主库 读写分离判断逻辑代码 一主多从+分表 Yml 一主多从+分库分 ...
- Spring + Mybatis项目实现数据库读写分离
主要思路:通过实现AbstractRoutingDataSource类来动态管理数据源,利用面向切面思维,每一次进入service方法前,选择数据源. 1.首先pom.xml中添加aspect依赖 & ...
随机推荐
- ZIP压缩算法详细分析及解压实例解释
最近自己实现了一个ZIP压缩数据的解压程序,觉得有必要把ZIP压缩格式进行一下详细总结,数据压缩是一门通信原理和计算机科学都会涉及到的学科,在通信原理中,一般称为信源编码,在计算机科学里,一般称为数据 ...
- 3.Windows Server 2012 R2数据库部署
很多人竟然不会安装数据库....好吧,来个图文教程,其实和windows里面一样安装,和安装2008一样的 先安装3.5:http://www.cnblogs.com/dunitian/p/53487 ...
- 07.LoT.UI 前后台通用框架分解系列之——轻巧的文本编辑器
LoT.UI汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui 上次说的是强大的百度编辑器 http://www.cnblogs.com/d ...
- C# 正则表达式大全
文章导读 正则表达式的本质是使用一系列特殊字符模式,来表示某一类字符串.正则表达式无疑是处理文本最有力的工具,而.NET提供的Regex类实现了验证正则表达式的方法.Regex 类表示不可变(只读)的 ...
- 引人瞩目的 CSS 变量(CSS Variable)
这是一个令人激动的革新. CSS 变量,顾名思义,也就是由网页的作者或用户定义的实体,用来指定文档中的特定变量. 更准确的说法,应该称之为 CSS 自定义属性 ,不过下文为了好理解都称之为 CSS 变 ...
- 香蕉云APP,2016下半年开发日记
2016-6-17 数据库设计不应该过多依赖范式,适度的冗余可以加快搜索速度,在服务器的配置还可以的情况下,可以采用冗余来解决查找慢的问题.还一个是要选择好数据库引擎,例如 InnoDB 和 myi ...
- Http请求
HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的.HTTP有两类报文:请求报文和响应报文. 请求报文 一个HTTP请求报文由请求行(request line ...
- js 基础篇(点击事件轮播图的实现)
轮播图在以后的应用中还是比较常见的,不需要多少行代码就能实现.但是在只掌握了js基础知识的情况下,怎么来用较少的而且逻辑又简单的方法来实现呢?下面来分析下几种不同的做法: 1.利用位移的方法来实现 首 ...
- Zabbix 漏洞分析
之前看到Zabbix 出现SQL注入漏洞,自己来尝试分析. PS:我没找到3.0.3版本的 Zabbix ,暂用的是zabbix 2.2.0版本,如果有问题,请大牛指点. 0x00 Zabbix简介 ...
- Android中Activity运行时屏幕方向与显示方式详解
现在我们的手机一般都内置有方向感应器,手机屏幕会根据所处位置自动进行横竖屏切换(前提是未锁定屏幕方向).但有时我们的应用程序仅限在横屏或者竖屏状态下才可以运行,此时我们需要锁定该程序Activity运 ...