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. iframe子页面控制父页面滚动高度,直接蹦到父页面开头

    zepto调用父页面窗口元素的scrollTop()方法会报错,貌似是scrollTop函数中有个scrollTo()方法用到this,指向错误. 经检查, 原生js控制父页面滚动,只能写数字,不能带 ...

  2. 安装软件碰见error2502 2503

    把鼠标放到Win8屏幕的最左下角,等待Win8 Metro界面的缩略图出现后点击鼠标右键,在弹出的菜单中选择“命令提示符(管理员)”   打开的“命令提示符(管理员)”   找到自己将要安装的程序路径 ...

  3. easyui,文件引用

  4. 使用元类 编写ORM

    元类 一句话: 元类定制类的创建行为 知识点 1.类的创建: python这种动态语言,函数和类的定义,不是编译时定义的,而是运行时动态创建的. Python解释器遇到class定义时,仅仅是扫描一下 ...

  5. 微信小程序传值以及获取值方法

    http://www.51xuediannao.com/xiaochengxu/xiaochengxu-chuanzhi.html

  6. python3配置 opencv

    python3配置 opencv 本文适用于windows 64位系统 下的Python3.5.python3.5.pip为必备前提. 配置过程: 第一步:打开cmd命令行窗口 第二步:输入pip指令 ...

  7. ESP8266EX资料

    https://github.com/esp8266/Arduino http://espressif.com/zh-hans/support/explore/faq 电路资料图如下: 介绍功能: 参 ...

  8. nginx添加一个站点

    server { listen ; server_name demo.abc.com ; root /Users/pa200318/demo.cp.com/trunk; index index.php ...

  9. Illegalmixofcollations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT)foroperation '= 连表查询排序规则问题

    两张 表 关联 ,如果 join的字段 排序规则 不一样就会出这个问题 . 解决办法 ,统一 排序规则. 在说说区别,utf8mb4_general_ci 更加快,但是在遇到某些特殊语言或者字符集,排 ...

  10. Spring Cloud(Dalston.SR5)--Zuul 网关-过滤器

    Spring Cloud 为 HTTP 请求的各个阶段提供了多个过滤器,这些过滤器的执行顺序由各自提供的一个 int 值决定,提供的值越小则优先级越高,默认的过滤器及优先级如下: 自定义过滤器 在默认 ...