Mybatis SQL拦截器实现
生活随笔
收集整理的這篇文章主要介紹了
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/
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的Mybatis SQL拦截器实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 程序优化:字符串操作、基本运算
- 下一篇: linux cmake编译源码,linu