mybatis通过拦截器动态的修改sql

Mybatis 拦截器--动态修改SQL 表结构里面有两个固定字段,DATA_STATE 和 DELETE_MARKERchar(1) DATA_STATE 数据状态 (1正常 0逻辑删除)char(1) DELETE_MARKER 删除标记 (0: 未删除,null:删除)逻辑删除 DATA_STATE='0' 时,需要强制对对应的表字段(DELETE_MARKER)进行置空,设置DELETE_MARKER=null。 阅读详情

比如你的orderInfo有个版本号,你需要每次修改的时候版本号增加1,如果手工添加比较麻烦,容易遗漏,可以通过拦截器实现。

这里适合通过mybatis根据实体类更新的情况,如果是手工写的update 代码,则可以把

parameter instanceof OrderInfo更换为
sql.contains(" order_info ")



import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.plugin.*;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Properties;

//只拦截update请求
@Intercepts({@Signature(
        type = Executor.class,
        method = "update",
        args = {MappedStatement.class, Object.class}
)})
@Slf4j
public class MybatisUpdateInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 获取当前执行的SQL语句
        Object[] args = invocation.getArgs();
        MappedStatement mappedStatement = (MappedStatement) args[0];
        Object parameter = args[1];
        // 判断当前执行的SQL语句是否是修改orderInfo表的数据
        if (mappedStatement.getSqlCommandType().equals(SqlCommandType.UPDATE) && parameter instanceof OrderInfo) {
            //如果是修改order_info表,修改version
            PropertyUtils.setProperty(parameter, "version", null);
            BoundSql boundSql = mappedStatement.getBoundSql(parameter);
            String sql = boundSql.getSql();
            sql = sql.replace(" WHERE ", ",`version`=(version+1) WHERE ");
            BoundSql newBoundSql = new BoundSql(mappedStatement.getConfiguration(), sql, boundSql.getParameterMappings(), parameter);
            // 把新的查询放到statement里
            MappedStatement newMs = copyFromMappedStatement(mappedStatement, new BoundSqlSqlSource(newBoundSql));
            args[0] = newMs;
        }
        return invocation.proceed();
    }


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

    @Override
    public void setProperties(Properties properties) {
        // do nothing
    }

    private MappedStatement copyFromMappedStatement(MappedStatement ms, SqlSource newSqlSource) {
        MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType());
        builder.resource(ms.getResource());
        builder.fetchSize(ms.getFetchSize());
        builder.statementType(ms.getStatementType());
        builder.keyGenerator(ms.getKeyGenerator());
        if (ms.getKeyProperties() != null && ms.getKeyProperties().length > 0) {
            builder.keyProperty(ms.getKeyProperties()[0]);
        }
        builder.timeout(ms.getTimeout());
        builder.parameterMap(ms.getParameterMap());
        builder.resultMaps(ms.getResultMaps());
        builder.resultSetType(ms.getResultSetType());
        builder.cache(ms.getCache());
        builder.flushCacheRequired(ms.isFlushCacheRequired());
        builder.useCache(ms.isUseCache());
        return builder.build();
    }

    private static class BoundSqlSqlSource implements SqlSource {
        private BoundSql boundSql;

        public BoundSqlSqlSource(BoundSql boundSql) {
            this.boundSql = boundSql;
        }

        @Override
        public BoundSql getBoundSql(Object parameterObject) {
            return boundSql;
        }
    }
}

添加MybatisConfig,注入拦截器

/**
 * mybatis配置
 */
@Configuration
public class MybatisConfig {
    /**
     * 注册拦截器
     */
    @Bean
    public MybatisUpdateInterceptor mybatisInterceptor() {
        MybatisUpdateInterceptor interceptor = new MybatisUpdateInterceptor();
        return interceptor;
    }
}

Mybatis 动态修改 SQL 的两种方式 在Spring AOP中,你可以使用切面(Aspect)来拦截MyBatis执行期间的方法调用,包括修改BoundSql对象中的SQL语句。 阅读详情

相关推荐

老年人教程:MyBatis拦截器动态修改SQL(更新与插入)语句

注:本文编写与 2019年12月17日, 内容可能存在时效性问题。 数据库使用MySQL5.7 集成于SpringBoot 2.0.X , 引用国产的开源工具类Hutool 本教程建议显示大纲视图 配合食用 一 、简介 设定使用场景 任意 insert 、update 语句,都需要记录下语句的操作用户(CREATOR), 但由于系统早期设计不规范,大量SQL语句中,部分有写入CREAT...

波特多的博客 4530

MyBatis的动态拦截sql并修改

动态拦截sql以注解实现

ewcc_ycl的博客 6012

Windows Server 搭建ftp服务

Windows Server 搭建ftp服务

ch258563的博客 1010

mybatis拦截器修改SQL

平常我们写项目时应该都会遇到这么一个问题,一些接口需要根据账号权限的不同而展示不同的数据,又或者是SaaS化产品的租户,一般遇到这种情况,我们在写查询语句的时候,会加上相应的SQL来过滤掉不符合的数据,这样当然是可行的,但是基本上SQL都是相同的,所以就会造成会有很多重复的SQL片段,这样看起来也不太雅观,那有什么方法可以不写这么多重复的SQL吗?这一步就比较自由了,主要看大家的需求是怎样的,我这里就稍微弄个简单点的,注解里有一个参数,这个参数会拼接到原来的SQL上。

weixin_50117915的博客 3104

Autosar结合simulink的汽车应用层软件开发实例

本文基于汽车应用开发案例,并结合Autosar相关知识,生成具有Autosar标准的汽车应用层开发代码,以供学习和参考。以上就是本篇内容,主要是利用Simulink创建Autosar接口并进行端口映射的方法。

m0_64899535的博客 2152

视频动作识别、行为识别、时空动作检测数据集整理(持续更新)

动作、行为、事件 在计算机视觉的相关研究中,人体的动作、行为识别是一个基础研究问题。但目前识别、检测人类的动作/行为仍然是一个巨大的挑战。这里整理下当前相关的细分任务、数据集和开源代码(持续更新中)。

人工智能算法与工程实践 3万+

MyBatis拦截器实现sql查询权限动态修改

动机和具体情景 最近考虑怎么在Mybatis自动创建sql执行过程中进行介入,来不对原有代码耦合的情况下,实现对sql的修改。 考虑情景,比如多部门管理系统,员工工资和账户信息敏感,每个部门只能查到对应权限的员工信息。为了实现sql的鉴权,本来是需要将原始的sql语句加上某个权限字段的判断。 为了不耦合,现在的方案是在需要鉴权的Mybatis Mapper方法上增加一个注解,在运行过程中判断该注解存在即对sql进行修改,形成新的带权限字段判断的sql,这样对原始代码的修改就少很多(加个注解就行)。 基本原理

回炉重造P的博客 4177

构建多节点AI代理网络:OpenClaw协同框架与实战部署指南

在分布式系统与AI代理技术领域,多节点协同是提升智能体能力与扩展性的核心挑战。其原理在于通过设计清晰的通信协议与数据同步机制,使分散的智能体能够共享状态、知识与技能,从而实现1+1>2的群体智能。这一技术价值在于突破了单点AI的能力上限,为构建复杂、鲁棒且可扩展的自动化系统提供了基础。典型的应用场景包括跨设备任务编排、企业级工作流自动化以及大规模AI代理集群的管理。本文聚焦于OpenClaw这一开源AI代理框架,深入探讨如何利用模块化设计(如网状网络与任务控制中心)实现记忆共享与统一调度,解决多网关协同中的

weixin_42521032的博客 298

mybatis使用拦截器动态修改sql脚本(更新、插入、查询)

MyBatis拦截器修改SQL语句 背景 最近公司项目想要做成一个云SaaS平台,需要不同用户能看到不同数据,需要做到数据的物理隔离。目前的方案就是在每张业务表中增加一个platform_id字段,来区分不同的租户,这就意味着在原来系统层面需要再增删改查都需要带上platform_id字段作为标识。如果在每个脚本上都手动加上这个字段的话那就太麻烦,太复杂了。所以就想使用mybatis 的拦截器Interceptor来实现。 准备 自定义注解@PlatformTag @PlatformTagIngore

简单简单小白 1万+

【RT-DETR涨点改进】独家创新改进篇 | AAAI2024 | RT-DETR引入CFBlock增强对长程依赖和全局语义信息的建模能力,有助于提升复杂场景下小目标、遮挡目标的检测精度

本文给大家介绍在RT-DETR中引入CFBlock模块,能够有效提升模型对长程依赖和全局语义信息的建模能力,在保持轻量化和高效推理的基础上增强特征表达力,特别有助于提升复杂场景下小目标、遮挡目标的检测精度,从而实现更优的精度与速度平衡。

Ai缝合怪、助力小伙伴高效发论文 259

Microsemi Libero使用技巧11——CoreUARTAPB RX管脚分配时不显示

调用串口IP核CoreUARTAPB,并例化到顶层设计,发现UART_RX管脚在进行管脚分配时没有显示出来,最后发现是CoreAPB3总线IP核配置不对导致,改为如下配置后正常。

whik1194的博客 756

mybatis拦截器修改sql_springboot使用mybatis插件动态修改sql

作者 | bkmemory来源 | urlify.cn/3mMf6r一、关于mybatis的定位mybatis很大的一个功能就是解析mapper.xml文件,按照规则解析sql,并交由数据库驱动最终执行sql,然后对结果集进行处理二、先说一下我们要做的事情:在sql执行前对sql进行动态修改,接收到结果后,对结果再次进行修改于是有了如上图设计那拦截器到底要如何设计才能做到修改sql呢,就要说到sq...

weixin_39663602的博客 858

看完就会!手把手教您如何正确开启飞牛Nas 虚拟机的 IOMMU 硬件直通,让虚拟机的性能飙升!

看完就会!手把手教您如何正确开启飞牛Nas 虚拟机的 IOMMU 硬件直通,让虚拟机的性能飙升!

XiaoqiangClub的博客 1万+

基于Mybatis拦截器实现动态修改sql语句

业务背景 由于新业务需要,数据库名称要更换,代码中存在许多数据库名.表明的SQL语句,如:db.user,更换db名称后原代码执行报错,需将SQL语句db名字换为新的数据库名称. 使用Mybatis拦截器实现动态修改sql语句 @Component @Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class, Integer.class })}) public class Mybati

hale_hale的博客 1480

42页Claude 3技术报告解读(Opus, Sonnet, Haiku)

在Claude 3模型中,增加了一个额外的原则到Claude的宪法中,以鼓励尊重残疾人权利,这一原则源自对集体宪法AI的研究。Claude 3模型的训练基于专有的混合数据集,包括截至2023年8月互联网上公开可用的信息,以及第三方提供的非公开数据、数据标注服务和付费承包商提供的数据,还有内部生成的数据。这些初始响应通常包含有害和有毒的内容。Claude 3模型家族在推理、编码和问答任务上展现出卓越的性能,特别是在行业标准基准测试中取得了显著的提升,证明了其在处理复杂问题和提供准确答案方面的能力。

具身机器人和通用AI 2432

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

【动态修改SQL语句】Mybatis拦截器修改sql语句

MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能。MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:我们看到了可以拦截Executor接口的部分方法,比如update,query,commit,rollback等方法,还有其他接口的一些方法等。1、拦截执行器的方法2、拦截参数的处理3、拦截结果集的处理4、拦截Sql语法构建的处理/*** sql增强注解。...

祁_z 1013

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

关于Mybatis自定义拦截器如何动态修改sql及执行结果(上)

最近一直在研究mybatis的拦截器,也算小有收获,和大家一起分享。 一、关于mybatis的定位 mybatis很大的一个功能就是解析mapper.xml文件,按照规则解析sql,并交由数据库驱动最终执行sql,然后对结果集进行处理 二、先说一下我们要做的事情:在sql执行前对sql进行动态修改,接收到结果后,对结果再次进行修改 于是有了如上图设计 三、那拦截器到底要如何设计才...

ruoyi5268的博客 2万+

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

mybatis自定义拦截器实现统一过滤动态修改sql

需求:给原来的sql都加上一个条件过滤,实现多租户数据隔离。 一个是sql语句散布在xml里,dao注解里,量非常大,再一个是租户字段定义在实体基类中,接口参数是对象只需修改sql即可,倒是不麻烦,机械性复制粘贴,如果是非对象例如get(id),那就有的你改了,所以第一时间排除掉一个个修改sql。用mybatis自定义拦截器来对sql进行后期动态修改,原理和分页插件类似。 建一个mybatis拦截...

bbq烤鸡的后宫 7524

Mybatis 通过拦截器动态修改SQL

01 使用场景 当我们在多租户的项目中,编写SQL语句都要带上tenant字段,用于区分不同的租户只能操作自己的数据。 比如,像下面的SQL select * from member where id = #{id} and tenant = #{tenant} 但是,我们的tenant属性一般是放在一个ThreadLocal的变量中的,便于我们随时获取该属性进行一些业务处理。 public class TenantContext { private static final ThreadLoca

qq_37170583的博客 4436

Mybatis拦截器实现SAAS平台(动态修改SQL)随笔

首先,自定义拦截器 import com.swzx.risktech.model.User; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.plugin.*; import or...

一个有梦想的混子 1518

分库分表 MyBatis的拦截器(Interceptor)在 SQL 执行前动态修改表名

分库分表 MyBatis的拦截器(Interceptor)在 SQL 执行前动态修改表名

2301_77615930的博客 919

mybatis拦截器,动态修改sql语句

1、拦截器代码 package com.ps.uzkefu.common; /** * Author:ZhuShangJin * Date:2018/8/23 */ import java.sql.SQLException; import java.util.Properties; import org.apache.commons.lang3.StringUtils; import...

zsj777的专栏 3万+

MySQL拦截器获取xml id_MyBatis拦截器动态修改SQL语句及参数值(场景:查询中字段值中特殊字符自动转义)...

解决问题的场景:执行人名字中含有_ 的,在查询中用_或含有_ 的字段,列表中查不到信息解决问题的思路:获取从MyBatis的mapper Xml文件中,找到原始的Sql语句(条件判断处理已好的SQL),在含有Like的查询字段值里若包含特殊字符,则转义 ,并在查询条件后面添加" ESCAPE '/'。处理后的Sql语句类似:select * fromfrom syslog where t l...

weixin_29212429的博客 988

Mybatis-plus 自定义拦截器动态修改sql

【代码】

只为成功找方法 不为失败找借口 2536

Mybatis拦截器动态追加sql语句

拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能。 MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括: Executor (update, query, flushStatements, commit, rollback, getTransaction, close,...

一个有梦想的混子 7258

mybatisplus使用拦截器动态修改SQL语句

在 MyBatis Plus 中,你可以使用自定义的拦截器来动态修改 SQL 语句。MyBatis Plus 提供了一个 InnerInterceptor 接口,你可以实现这个接口来创建自己的拦截器。这样,你就可以在 MyBatis Plus 中使用自定义拦截器来动态修改 SQL 语句了。创建好拦截器之后,你需要在 MyBatis Plus 的配置中注册这个拦截器。在 Spring Boot 应用中,确保拦截器被正确注册并且在 MyBatis Plus 的生命周期内可用。

qq_36608622的博客 2188
上一篇: 设计模式六大原则
下一篇: 根据项目名称查询github,判断项目代码是否被传上了github
bxp1321
博客等级 码龄17年 146粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值