欢迎支持笔者新作:《深入理解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拦截器实现相关推荐

  1. Mybatis自定义SQL拦截器

    本博客介绍的是继承Mybatis提供的Interface接口,自定义拦截器,然后将项目中的sql拦截一下,打印到控制台. 先自定义一个拦截器 package com.muses.taoshop.com ...

  2. mysql拦截器实现crud_Mybatis自定义SQL拦截器

    本博客介绍的是继承Mybatis提供的Interface接口,自定义拦截器,然后将项目中的sql拦截一下,打印到控制台. 先自定义一个拦截器 package com.muses.taoshop.com ...

  3. mybatis使用拦截器显示sql,使用druid配置连接信息

    mybatis使用拦截器显示sql,使用druid配置连接信息 mybatis sql Druid 1.显示出sql内容: 新建2个类: MybatisInterceptor :拦截sql,并获得输出 ...

  4. Mybatis 通过拦截器动态修改SQL

    01 使用场景 当我们在多租户的项目中,编写SQL语句都要带上tenant字段,用于区分不同的租户只能操作自己的数据. 比如,像下面的SQL select * from member where id ...

  5. Mybatis Interceptor 拦截器原理 源码分析

    Mybatis采用责任链模式,通过动态代理组织多个拦截器(插件),通过这些拦截器可以改变Mybatis的默认行为(诸如SQL重写之类的),由于插件会深入到Mybatis的核心,因此在编写自己的插件前最 ...

  6. mybatis 自定义拦截器

    拦截器注解 mybatis自定义拦截器实现步骤: 实现org.apache.ibatis.plugin.Interceptor接口. 添加拦截器注解org.apache.ibatis.plugin.I ...

  7. 一步步教你mybatis分页,mybatis分页拦截器 使用,mybatis拦截器分页

              mybatis 分页详解.mybatis分页查询,mybatis分页拦截器使用.struts2下mybatis分页 mybatis默认是支持分页的,内部通过创建可滚动的Result ...

  8. springbootjpa之hibernate sql拦截器

    springbootjpa之hibernate sql拦截器 解决问题,数据查询权限问题: 原理:通过拦截sql语句,然后解析sql语句,加入自定义查询条件,做到数据权限拦截: hibernate 文 ...

  9. 如何使用Mybatis的拦截器实现数据加密与解密

    点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 转载自公众号:日拱一兵 关注我,回复口令获取可获取独家整理的学习资料: - 001 :领取<Sp ...

最新文章

  1. 三层神经网络前向后向传播示意图
  2. linux gcc 显示/禁用 所有警告
  3. C/C++程序编译过程详解
  4. Python轻量级IDE推荐 -- Jupyter QTConosle
  5. html5 如何局部放大,【HTML5特效】挺简单的HTML5放大效果
  6. dojo还有人用吗_我的Dojo中有一个Mojo(如何编写Maven插件)
  7. 使用Spring Integration Java DSL与Rabbit MQ集成
  8. apache+mysql+php的环境配置
  9. linux线程的理解,linux线程与进程的理解
  10. win10 64位 Compaq Visual Fortran(CVF)安装教程
  11. 如何在css中将图片横向摆放,css如何将图片横向平铺?
  12. 火狐浏览器怎么打不开网页
  13. 如何将长截图转换成TXT呢?
  14. C语言实现简单的小游戏之三子棋
  15. 10 大C++ Web(HTTP)开发开源框架/库推荐
  16. Linux下查看CPU信息[/proc/cpuinfo]
  17. relative的使用
  18. excel怎么按颜色统计单元格个数
  19. python-onvif实现客户端控制相机云台
  20. JavaSEDemo33

热门文章

  1. java.util.function包
  2. rlm sql mysql.so_UBUUTU7.10上安装配置freeradius+mysql+rp-pppoe手记
  3. ad软件侵权律师函_Aspen Plus 9 软件安装教程
  4. Javascript设计模式之中介者模式
  5. C++用模板元编程进行循环展开的性能测试
  6. 【科普】Web(瓦片)地图的工作原理
  7. 远程桌面退出全屏/不能全屏/全屏切换的技巧
  8. python报错ordinal not in range(128)
  9. 侠客博客v1.0 正式版版本发布
  10. 你正在用左脑还是右脑思考,请测试下就清楚了。