Mybatis SQL拦截器实现
欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。
欢迎跳转到本文原文阅读:https://honeypps.com/java/mybatis-sql-interceptor/
主要功能:通过log4j配置mybatis的打印,只能输出到控制台,而并非真正能够实现sql的获取,本文主要通过拦截器实现sql的拦截,进而对sql进行相应的操作。
起因:因项目需要,服务器要配成双机热备,那么数据库(这里采用的是MySQL)也是双机的,这就牵涉到数据库同步的问题,由于某种原因(这就不透露了)不能采用MySQL自身的同步机制,采用原先C/S系统的同步机制进行同步。
实现方式:mybatis与主数据库正常交互,通过拦截器拦截sql并通过webservice将sql发送到C/S系统的同步模块,进而同步备数据库。
主要代码:
package com.shr.dao;import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Properties;import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;import org.apache.log4j.Logger;import javax.inject.Inject;
import javax.inject.Named;import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
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.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandlerRegistry;@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 MyBatisSQLInterceptor implements Interceptor {private Logger logger = Logger.getLogger(MyBatisSQLInterceptor.class.getSimpleName());@SuppressWarnings("unused")private Properties properties;private ConcurrentLinkedDeque<String> list = new ConcurrentLinkedDeque<String>();
// @Inject
// @Named("soapClient")
// private SoapClient soapClient;public MyBatisSQLInterceptor(){ExecutorService exec = Executors.newSingleThreadExecutor();exec.execute(new Thread(){public void run(){while(true){if(list.isEmpty() == false){String sql = list.pollFirst();logger.info("[SEND WS: ["+sql+"]]");//与WebService交互}try {TimeUnit.MILLISECONDS.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}});exec.shutdown();}public Object intercept(Invocation invocation) throws Throwable {MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];Object parameter = null;if (invocation.getArgs().length > 1) {parameter = invocation.getArgs()[1];}BoundSql boundSql = mappedStatement.getBoundSql(parameter);Configuration configuration = mappedStatement.getConfiguration();Object returnValue = null;returnValue = invocation.proceed();showSql(configuration, boundSql);return returnValue;}private String getParameterValue(Object obj) {String value = null;if (obj instanceof String) {value = "'" + obj.toString() + "'";} else if (obj instanceof Date) {DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);value = "'" + formatter.format(obj) + "'";
// System.out.println(value);} else {if (obj != null) {value = obj.toString();} else {value = "";}}return value;}public String showSql(Configuration configuration, BoundSql boundSql) {Object parameterObject = boundSql.getParameterObject();List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();String sql = boundSql.getSql().replaceAll("[\\s]+", " ");if (parameterMappings.size() > 0 && parameterObject != null) {TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {sql = sql.replaceFirst("\\?", getParameterValue(parameterObject));} else {MetaObject metaObject = configuration.newMetaObject(parameterObject);for (ParameterMapping parameterMapping : parameterMappings) {String propertyName = parameterMapping.getProperty();if (metaObject.hasGetter(propertyName)) {Object obj = metaObject.getValue(propertyName);sql = sql.replaceFirst("\\?", getParameterValue(obj));} else if (boundSql.hasAdditionalParameter(propertyName)) {Object obj = boundSql.getAdditionalParameter(propertyName);sql = sql.replaceFirst("\\?", getParameterValue(obj));}}}}logger.info(sql);if(sql.startsWith("select") == false){list.add(sql);}return sql;}public Object plugin(Object target) {return Plugin.wrap(target, this);}public void setProperties(Properties properties0) {this.properties = properties0;}
}
欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。
欢迎跳转到本文原文阅读:https://honeypps.com/java/mybatis-sql-interceptor/
Mybatis SQL拦截器实现相关推荐
- Mybatis自定义SQL拦截器
本博客介绍的是继承Mybatis提供的Interface接口,自定义拦截器,然后将项目中的sql拦截一下,打印到控制台. 先自定义一个拦截器 package com.muses.taoshop.com ...
- mysql拦截器实现crud_Mybatis自定义SQL拦截器
本博客介绍的是继承Mybatis提供的Interface接口,自定义拦截器,然后将项目中的sql拦截一下,打印到控制台. 先自定义一个拦截器 package com.muses.taoshop.com ...
- mybatis使用拦截器显示sql,使用druid配置连接信息
mybatis使用拦截器显示sql,使用druid配置连接信息 mybatis sql Druid 1.显示出sql内容: 新建2个类: MybatisInterceptor :拦截sql,并获得输出 ...
- Mybatis 通过拦截器动态修改SQL
01 使用场景 当我们在多租户的项目中,编写SQL语句都要带上tenant字段,用于区分不同的租户只能操作自己的数据. 比如,像下面的SQL select * from member where id ...
- Mybatis Interceptor 拦截器原理 源码分析
Mybatis采用责任链模式,通过动态代理组织多个拦截器(插件),通过这些拦截器可以改变Mybatis的默认行为(诸如SQL重写之类的),由于插件会深入到Mybatis的核心,因此在编写自己的插件前最 ...
- mybatis 自定义拦截器
拦截器注解 mybatis自定义拦截器实现步骤: 实现org.apache.ibatis.plugin.Interceptor接口. 添加拦截器注解org.apache.ibatis.plugin.I ...
- 一步步教你mybatis分页,mybatis分页拦截器 使用,mybatis拦截器分页
mybatis 分页详解.mybatis分页查询,mybatis分页拦截器使用.struts2下mybatis分页 mybatis默认是支持分页的,内部通过创建可滚动的Result ...
- springbootjpa之hibernate sql拦截器
springbootjpa之hibernate sql拦截器 解决问题,数据查询权限问题: 原理:通过拦截sql语句,然后解析sql语句,加入自定义查询条件,做到数据权限拦截: hibernate 文 ...
- 如何使用Mybatis的拦截器实现数据加密与解密
点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 转载自公众号:日拱一兵 关注我,回复口令获取可获取独家整理的学习资料: - 001 :领取<Sp ...
最新文章
- 三层神经网络前向后向传播示意图
- linux gcc 显示/禁用 所有警告
- C/C++程序编译过程详解
- Python轻量级IDE推荐 -- Jupyter QTConosle
- html5 如何局部放大,【HTML5特效】挺简单的HTML5放大效果
- dojo还有人用吗_我的Dojo中有一个Mojo(如何编写Maven插件)
- 使用Spring Integration Java DSL与Rabbit MQ集成
- apache+mysql+php的环境配置
- linux线程的理解,linux线程与进程的理解
- win10 64位 Compaq Visual Fortran(CVF)安装教程
- 如何在css中将图片横向摆放,css如何将图片横向平铺?
- 火狐浏览器怎么打不开网页
- 如何将长截图转换成TXT呢?
- C语言实现简单的小游戏之三子棋
- 10 大C++ Web(HTTP)开发开源框架/库推荐
- Linux下查看CPU信息[/proc/cpuinfo]
- relative的使用
- excel怎么按颜色统计单元格个数
- python-onvif实现客户端控制相机云台
- JavaSEDemo33
热门文章
- java.util.function包
- rlm sql mysql.so_UBUUTU7.10上安装配置freeradius+mysql+rp-pppoe手记
- ad软件侵权律师函_Aspen Plus 9 软件安装教程
- Javascript设计模式之中介者模式
- C++用模板元编程进行循环展开的性能测试
- 【科普】Web(瓦片)地图的工作原理
- 远程桌面退出全屏/不能全屏/全屏切换的技巧
- python报错ordinal not in range(128)
- 侠客博客v1.0 正式版版本发布
- 你正在用左脑还是右脑思考,请测试下就清楚了。