mybatis sql 改写_mybatis sql改写-程序员宅基地

技术标签: apache  JAVA高级  数据库  sql  

1mybatis sql 改写

package com.macro.mall.tiny.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;


@Intercepts({
     @Signature(
             type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}
     )
})
@Slf4j
@Component
public class SqlRewriteInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
            StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
            MetaObject metaObject = MetaObject.forObject(statementHandler,
                    SystemMetaObject.DEFAULT_OBJECT_FACTORY,
                    SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,
                    new DefaultReflectorFactory());

            //先拦截到RoutingStatementHandler,里面有个StatementHandler类型的delegate变量,其实现类是BaseStatementHandler,然后就到BaseStatementHandler的成员变量mappedStatement
            MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");

            //sql语句类型 select、delete、insert、update
            String sqlCommandType = mappedStatement.getSqlCommandType().toString();
            if (!"SELECT".equals(sqlCommandType)){
                //只是拦截:SELECT
                return invocation.proceed();
            }

            //id为执行的mapper方法的全路径名,如com.uv.dao.UserMapper.insertUser
            String id = mappedStatement.getId();
            log.info("拦截到当前请求方法的全路径名为--->:  " + id);

        //TODO 修改位置
        //注解逻辑判断  添加注解了才拦截
        Class<?> classType = Class.forName(mappedStatement.getId().substring(0, mappedStatement.getId().lastIndexOf(".")));
        //获取接口方法名
        String methodName = mappedStatement.getId().substring(mappedStatement.getId().lastIndexOf(".") + 1, mappedStatement.getId().length());
        boolean isPageCount = false;

        int j=0;

       
                //获取到原始sql语句
                BoundSql boundSql = statementHandler.getBoundSql();
                String sql = boundSql.getSql();

                //获取参数
                Object parameter = statementHandler.getParameterHandler().getParameterObject();
                log.info("拦截到当前请求SQL为--->: "  + sql);
                log.info("拦截到当前请求类型为--->: "  + sqlCommandType);
                log.info("拦截到当前请求参数为--->: "  + parameter);

          
                log.info("拦截到当前请求SQL改写之后为--->: "  + sql);
                sql=sql+" where 1=1";
                log.info("拦截后改写--->: "  + sql);
                //反射改写新的SQL
                Field field = boundSql.getClass().getDeclaredField("sql");
                field.setAccessible(true);
                field.set(boundSql, sql);
            
     


        // 执行完上面的任务后,不改变原有的sql执行过程
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {}
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lucksczhd/article/details/121805306

智能推荐

关于IRCUT切换的操作步骤_反向电流和正向电流控制ircut-程序员宅基地

文章浏览阅读7.6k次,点赞4次,收藏26次。目录0.IRCUT说明1.切换过程1.1海思GPIO读写工具1.2GPIO配置1.2.1 GPIO方向配置1.2.2GPIO数据写入1.2.3GPIO上下拉及引脚复用1.3控制时序2.切换代码参考0.IRCUT说明作为小白,上手海思开发板的时候,不清楚IRCUT是什么,更别说IRCUT如何切换了,在学习过程中遇到的问题以及所得在此记录。IRCUT双滤镜包括全透滤片和红外光过滤片,从结构上看,是一个长方形的镜片分成左右两个部分。使用IRCUT的原因是白天日光光照中含有大量的红外线,这些红外线使感光元件_反向电流和正向电流控制ircut

C语言计算结构体占用字节大小总数_struct student 占用内存字节数=?-程序员宅基地

文章浏览阅读1w次,点赞6次,收藏16次。在学习C语言的时候很多人可能遇到了和我同样的问题,就是无法正确计算出C语言结构体所占字节的总的大小。首先,在开始计算结构体占用字节大小之前,我们要先搞懂什么是结构体的对齐和补齐。为什么会有结构体的对齐与补齐。CPU的数据传输方式:CPU的数据传输方式是一次传输2个(32位)或者8个(64位)字节的方式进行传输(根据总线条数来确定),这里我们以64位系统来举例,如果你声明一个变量占用8个字节_struct student 占用内存字节数=?

反射机制--方法的反射m.invoke()-程序员宅基地

文章浏览阅读789次。方法的名称和参数列表才能唯一地决定某个方法方法反射操作:method.invoke(对象,参数列表)反射是框架底层的一些方法,比如以后看到的Spring的重要特性DI:控制反转就是这么一个原理,至于为什么使用反射,1.首先你能通过任意对象获取类类型即是所有的信息,这个作用以后才能体现;2.方法的反射的好处就是解耦,比如说a,b,c对象都要调用 print()方法,正常的想法就是要创建每个对象,..._m.invoke()

Android 8.0 功能和 API-程序员宅基地

文章浏览阅读305次。Android 8.0 功能和 APIAndroid 8.0 为用户和开发者引入多种新功能。本文重点介绍面向开发者的新功能。请务必查阅 Android 8.0 行为变更以了解平台变更可能影响您的应用的领域。 用户体验通知在 Android 8.0 中,我们已重新设计通知,以便为管理通知行为和设置提供更轻松和更统一的方式。这些变更包括:图 1. 用户可以长按应用启动器图标以查看 Android 8._android.view.textclassifier.textclassifier api 23

技术博客第九周-程序员宅基地

文章浏览阅读82次。<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><center> ...

mybatis 的坑 超出连接数_mybatis 当连接数大于一定数量-程序员宅基地

文章浏览阅读1.6k次。连接数超出数据库最大连接数,too many connections重要参数1、2poolMaximumActiveConnections 最大活跃连接数,理解为 最大并发连接数poolMaximumIdleConnections 空闲连接数。问题出在这里,系统一直要保证有空闲连接,不管用不用,就额外多预留几个连接。即使超出了“最大连接数”也再创建,导致连接数超出,需要修改为0,即可。..._mybatis 当连接数大于一定数量

随便推点

[译]基于深度残差学习的图像识别-程序员宅基地

文章浏览阅读2.7k次。基于深度残差学习的图像识别_基于深度残差学习的图像识别

vscode运行helloworld.java程序_vscode java helloworld-程序员宅基地

文章浏览阅读3.1k次,点赞5次,收藏13次。摘要:常见的开发java程序的IDE有很多种,本文推荐vscode来运行一些简单的java程序,例如helloworld。只需要简单的几步,就可以使vscode运行helloworld.java。老生常谈,但是本文尽量带给您一些不一样的知识。版本Version: 1.45.1 OS: Windows_7 x64 。_vscode java helloworld

ubuntu14.04 nginx-rtmp-module 配置_./configure --with-http_ssl_module --add-module=/p-程序员宅基地

文章浏览阅读368次。http://blog.csdn.net/longji/article/details/5486535800 ubuntu14.04 ecs 配置nginx-rtmp-module参考:http://www.cnblogs.com/cocoajin/p/4353767.html01 安装 nginx 和 nginx-rtmp 编译依赖工具sudo_./configure --with-http_ssl_module --add-module=/path/to/nginx-rtmp-module找

Cesium相关3D数据简介_b3dm和3dtiles区别-程序员宅基地

文章浏览阅读8k次,点赞6次,收藏28次。Cesium的数据格式主要是3DTiles,3DTiles由tileset.json和tile组成,其中tale可以是.b3dm、.i3dm、.pnts、.vctr和.cmpt中的任一种格式文件。此外Cesium还支持其它3D格式,包括glTF、glb、Quantized-mesh(.terrain)等,支持其它数据向3DTiles格式的转换后加载,包括obj、BIM等。3DTiles3DT..._b3dm和3dtiles区别

(4.0.23.11)Viewpager与FragmentStatePagerAdapter重刷数据引发的源码分析和原生缺陷解决方案_fragmentstatepageradapter +recycleview-程序员宅基地

文章浏览阅读296次。文章目录一、问题二、源码分析2.1ViewPager#dataSetChanged2.1.1 ArrayList.ViewPager.ItemInfo. mItems2.1.2 Adapter.getItemPosition(ii.object)2.3 什么时候触发PagerAdapter#instantiateItem2.3.1 populate()2.4 FragmentStatePagerAdapter解决方案方案一:不可行方案二:可行方案三:可行参考文献一、问题public class Feed_fragmentstatepageradapter +recycleview

一周极客热文:3月,献给程序员们的技术书_计算机大师dijkstra谈haskell和java | 外刊it评论-程序员宅基地

文章浏览阅读585次。6一周极客热文:3月,献给程序员们的技术书文章由钱曙光于19小时前分享 评论(14)一周极客热文程序员  北京的雾霾刚刚过去,小编便开始埋头做三月书讯了。《算法谜题》 经典算法谜题的合集 Google、Facebook等一流IT公司算法面试必备《Hadoop实战手册》 快速解决诸多Hadoop相关技术问题的实用技术手册《趣学Python编程》_计算机大师dijkstra谈haskell和java | 外刊it评论