mybatis获取sql代码

package com.icourt.alpha.log.interceptor;

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.*;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.text.DateFormat;
import java.util.*;
import java.util.regex.Matcher; /**
* 用于记录mybatis中的sql中不包含officeId的sql
* Created by shiwen on 2017/9/12.
* <p>
*/ @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 static final Logger logger = LoggerFactory.getLogger(MybatisSqlInterceptor.class);
private static final Logger sqlLogger = LoggerFactory.getLogger("mybatisSql"); private static String [] officeIdNames = new String[]{"OFFICE_ID","OFFICEID","PK_OFFICE_ID"}; @Override
public Object intercept(Invocation invocation) throws Throwable {
try {
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; //0.sql参数获取
Object parameter = null;
if (invocation.getArgs().length > 1) {
parameter = invocation.getArgs()[1];
} //1.获取sqlId
String sqlId = mappedStatement.getId();
BoundSql boundSql = mappedStatement.getBoundSql(parameter); Configuration configuration = mappedStatement.getConfiguration(); //获取真实的sql语句
String sql = getSql(configuration, boundSql, sqlId, 0); //2.判断是否有officeId
if (hasOfficeId(sql,officeIdNames)) {
sqlLogger.warn("{}", sql);
} else {
sqlLogger.debug("{}", sql);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return invocation.proceed();
} /**
* 判断sql语句中是否包含officeId字段
*
* @param sql sql语句
* @return
*/
private boolean hasOfficeId(String sql,String[] officeIdNames) {
//office ID 的可能名称
if (sql == null || sql.trim().length() == 0) {
return false;
} String afterWhereStatement = sql.toUpperCase().substring(sql.indexOf("where")); for (String officeIdName : officeIdNames){
if(afterWhereStatement.indexOf(officeIdName) > 0){
return true;
}
} return false;
} @Override
public Object plugin(Object o) {
return Plugin.wrap(o, this);
} @Override
public void setProperties(Properties properties) { } private static String getSql(Configuration configuration, BoundSql boundSql,
String sqlId, long time) {
String sql = showSql(configuration, boundSql);
StringBuilder str = new StringBuilder(100);
str.append(sqlId);
str.append(":");
str.append(sql);
return str.toString();
} private static 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(new Date()) + "'";
} else {
if (obj != null) {
value = obj.toString();
} else {
value = "";
} }
return value;
} private static String showSql(Configuration configuration, BoundSql boundSql) {
Object parameterObject = boundSql.getParameterObject();
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
if (!parameterMappings.isEmpty() && parameterObject != null) {
TypeHandlerRegistry typeHandlerRegistry = configuration
.getTypeHandlerRegistry();
if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
sql = sql.replaceFirst("\\?",
Matcher.quoteReplacement(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("\\?", Matcher.quoteReplacement(getParameterValue(obj)));
} else if (boundSql.hasAdditionalParameter(propertyName)) {
Object obj = boundSql
.getAdditionalParameter(propertyName);
sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj)));
} else {
sql = sql.replaceFirst("\\?", "缺失");
}//打印出缺失,提醒该参数缺失并防止错位
}
}
}
return sql;
}
}

mybatis拦截器获取sql的更多相关文章

  1. Mybatis拦截器实现SQL性能监控

    Mybatis拦截器只能拦截四类对象,分别为:Executor.ParameterHandler.StatementHandler.ResultSetHandler,而SQL数据库的操作都是从Exec ...

  2. Mybatis拦截器介绍

    拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法.Mybatis拦截器设计的一个初 ...

  3. Mybatis拦截器实现分页

    本文介绍使用Mybatis拦截器,实现分页:并且在dao层,直接返回自定义的分页对象. 最终dao层结果: public interface ModelMapper { Page<Model&g ...

  4. 数据权限管理中心 - 基于mybatis拦截器实现

    数据权限管理中心 由于公司大部分项目都是使用mybatis,也是使用mybatis的拦截器进行分页处理,所以技术上也直接选择从拦截器入手 需求场景 第一种场景:行级数据处理 原sql: select ...

  5. 基于Spring和Mybatis拦截器实现数据库操作读写分离

    首先需要配置好数据库的主从同步: 上一篇文章中有写到:https://www.cnblogs.com/xuyiqing/p/10647133.html 为什么要进行读写分离呢? 通常的Web应用大多数 ...

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

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

  7. spring boot 实现mybatis拦截器

    spring boot 实现mybatis拦截器 项目是个报表系统,服务端是简单的Java web架构,直接在请求参数里面加了个query id参数,就是mybatis mapper的query id ...

  8. mybatis拦截器使用

    目录 mybatis 拦截器接口Interceptor spring boot + mybatis整合 创建自己的拦截器MyInterceptor @Intercepts注解 mybatis拦截器入门 ...

  9. Mybatis拦截器介绍及分页插件

    1.1    目录 1.1 目录 1.2 前言 1.3 Interceptor接口 1.4 注册拦截器 1.5 Mybatis可拦截的方法 1.6 利用拦截器进行分页 1.2     前言 拦截器的一 ...

随机推荐

  1. 1.配置OpenCV开发环境VS2010

  2. XCode9和10编译Cordova报错toLowerCase of undefined解决方案

    XCode升级到9或10后,cordova build时报错:toLowerCase of undefined... 解决方案: 修改platforms/ios/cordova/lib/list-em ...

  3. 1458 Common Subsequence

    最简单的LIS; 设字符串为 a = acc  b = cc 则dp数组为 0 0 1 1 1 2 b[0] = a[1], b[1] = a[1] 防止这里算两个 要清楚的是 怎么不重复计算 也就是 ...

  4. JSP 页面显示sql中数据。el

    存储数据库字段. package Bean; /** * Created by Administrator on 2017/5/24. */ public class info { private S ...

  5. 作用域&&闭包

    在了解闭包之前,先了解作用域一,作用域简单来说就是变量和函数可以访问的范围,在es5中变量作用域一般分为全局作用域和局部作用域,这个主要依据是全局变量还是局部变量 情景1: <script> ...

  6. RabbitMQ python模块pika生产者消费者轮询模型。

    完整代码如下: 生产者,producer import pika connection = pika.BlockingConnection( pika.ConnectionParameters('lo ...

  7. PythonStudy——第一阶段性测试

    1.Python解释器,在2.x和3.x上分别采用的是什么默认编码8 2.定义字符串变量时,单引号,双引号,三引号什么区别? 3.编程语言可以分为哪三类,特点都是什么 4.定义一个变量有三个特性, 5 ...

  8. 用turtle画图

    turtle是python自带一个寓教于乐的小乌龟,可以控制乌龟移动(机器人),可以留下足迹. turtledemo里有许多官方例子.刚才随性而发做,看了介绍随手画了一个,有点像自动原包机,通过简单的 ...

  9. windows server 2008 R2之取消多余的安全配置

    一:取消IE浏览器的安全配置(使IE浏览器可以正常上网) 管理员禁用即可 二.取消关机时强制输入关机备注 运行gpedit.msc,选择计算机配置->管理模板->系统->提示“关机时 ...

  10. windows server 修改远程桌面连接端口号

    1. [运行]输入 regedit 2.  在注册表编辑器中找到以下PortNamber键,改为要使用的远程端口,如10000. HKEY_LOCAL_MACHINE\SYSTEM\CurrentCo ...