mybatis plugins实现项目【全局】读写分离

时间:2022-03-31 07:47:32

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

注解实现读写分离: 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 &plus; Mybatis 多数据源配置实现读写分离

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

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

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

  3. SpringMVC4&plus;MyBatis&plus;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. Spring &plus; Mybatis项目实现数据库读写分离

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

  9. 通过spring抽象路由数据源&plus;MyBatis拦截器实现数据库自动读写分离

    前言 之前使用的读写分离的方案是在mybatis中配置两个数据源,然后生成两个不同的SqlSessionTemplate然后手动去识别执行sql语句是操作主库还是从库.如下图所示: 好处是,你可以人为 ...

随机推荐

  1. sklearn学习笔记1

    Image recognition with Support Vector Machines #our dataset is provided within scikit-learn #let's s ...

  2. mac下使用brew安装ffmpeg支持x265

    使用brew install ffmpeg 安装ffmpeg默认是没有支持x265的, 使用brew info ffmpeg 获取安装选项帮助, 使用brew reinstall ffmpeg --w ...

  3. Android 中的 Service 全面总结 (转)

    原文地址:http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html 1.Service的种类   按运行地点分类: 类别 区别  优点 ...

  4. BZOJ 1270&colon; &lbrack;BeijingWc2008&rsqb;雷涛的小猫&lpar; dp &rpar;

    简单的dp.. dp(i,j) = max(dp(x,y))+cnt[i][j], (x,y)->(i,j)是合法路径. 设f(i)= max(dp(x,y))(1≤x≤N, 1≤y≤i), g ...

  5. 利用Apach ab对nodejs进行并发负载的压力测试

    大家应该都有听过,nodejs性能优越,并发也很好之类的话,那我们用Apache ab对node这个空框架测试一下,然后再对一些网站测试一下,或或少一定的参考意义把. Apache ab测试工具是模拟 ...

  6. leetcode 5 Longest Palindromic Substring--最长回文字符串

    问题描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...

  7. 洛谷P2084 进制转换

    题目背景 无 题目描述 今天小明学会了进制转换,比如(10101)2 ,那么它的十进制表示的式子就是 : 1*2^4+0*2^3+1*2^2+0*2^1+1*2^0, 那么请你编程实现,将一个M进制的 ...

  8. Jquery UI的日历控件datepicker限制日期&lpar;转&rpar;

    网上找到这篇文章:http://www.jssay.com/blog/index.php/2010/04/27/%E5%A6%82%E4%BD%95%E7%A6%81%E7%94%A8datepick ...

  9. Android App优化之ANR详解

    引言 背景:Android App优化, 要怎么做? Android App优化之性能分析工具 Android App优化之提升你的App启动速度之理论基础 Android App优化之提升你的App ...

  10. springmvc 开涛 注解式控制器

    版本 定义处理器类 处理器映射适配器 备注 支持的注解 2.5前 controller       2.5 注解 DefaultAnnotationHandlerMapping AnnotationM ...

相关文章