【无标题】mybatis 拦截器,保存mdl操作日志

mybatis详解(全) mybatis详解 阅读详情



import lombok.extern.slf4j.Slf4j;
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.mapping.ParameterMode;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.springframework.stereotype.Component;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;

@Intercepts(@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}))
@Slf4j
@Component
public class SqlTrackInterceptor implements Interceptor {


    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        Object parameterObject = null;
        if (invocation.getArgs().length > 1) {
            parameterObject = invocation.getArgs()[1];
        }
        Object result = invocation.proceed();
        BoundSql boundSql = mappedStatement.getBoundSql(parameterObject);
        Configuration configuration = mappedStatement.getConfiguration();
        String sql = getSql(boundSql, parameterObject, configuration);
        if (!sql.contains("sys_audit")) {
            AuditUtils.addAuditLog(Audit.AuditType.SQL, "DML", sql);
        }
        return result;
    }

    private String getSql(BoundSql boundSql, Object parameterObject, Configuration configuration) {
        String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
        if (parameterMappings != null) {
            for (int i = 0; i < parameterMappings.size(); i++) {
                ParameterMapping parameterMapping = parameterMappings.get(i);
                if (parameterMapping.getMode() != ParameterMode.OUT) {
                    Object value;
                    String propertyName = parameterMapping.getProperty();
                    if (boundSql.hasAdditionalParameter(propertyName)) {
                        value = boundSql.getAdditionalParameter(propertyName);
                    } else if (parameterObject == null) {
                        value = null;
                    } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                        value = parameterObject;
                    } else {
                        MetaObject metaObject = configuration.newMetaObject(parameterObject);
                        value = metaObject.getValue(propertyName);
                    }
                    sql = replacePlaceholder(sql, value);
                }
            }
        }
        return sql;
    }

    private String replacePlaceholder(String sql, Object propertyValue) {
        String result;
        if (propertyValue != null) {
            if (propertyValue instanceof String) {
                result = "'" + propertyValue + "'";
            } else if (propertyValue instanceof Date) {
                DateFormat  dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                result = "'" + dateFormat.format(propertyValue) + "'";
            } else {
                result = propertyValue.toString();
            }
        } else {
            result = "null";
        }
        return sql.replaceFirst("\\?", Matcher.quoteReplacement(result));
    }
}

public class AuditUtils {

    public static void addAuditLog(Audit.AuditType type, String name, String content, String remark) {
        AuditService auditService = ApplicationContextUtils.getBean(AuditService.class);
        auditService.save(type, name, content, remark);
    }

    public static void addAuditLog(Audit.AuditType type, String name, String content) {
        addAuditLog(type, name, content, null);
    }
}

3天干完6个月的活,Claude把模型搬上AMD 一条挺刺激的消息:Anthropic 给投资人的材料里有一张幻灯片,写着它的 Claude Mythos Preview 只花了大约​,就摸清了怎么让另一个 Claude 模型在 AMD 的 MI355X 上跑起来。同一处还写了个对照数字:过去给一块新芯片做推理适配,通常要几十名工程师、​。3 天对 6 个月,这个比值太扎眼,当天中文互联网上就冒出一堆「英伟达的护城河塌了」的说法。我把能翻到的材料都翻了一遍,越看越觉得,塌掉的那一小块是真的,可塌的位置和很多人想的不一样。 阅读详情

相关推荐

手把手教你用ET-BERT预训练模型搞定加密流量分类(附完整代码)

本文详细介绍了如何使用ET-BERT预训练模型实现加密流量分类,包括环境配置、数据预处理、模型微调及优化策略。通过实战代码示例,帮助开发者快速掌握这一技术,提升网络安全领域的加密流量分析能力。

weixin_29166013的博客 494

Mybatis拦截器实现操作日志记录

• 核 心 作 用 : – 保 证 一 个 类 只 有 一 个 实 例 , 并 且 提 供 一 个 访 问 该 实 例 的 全 局 访 问 点 。

人生就像一场戏 6431

从零到一:高通Memory QMVS测试环境搭建的避坑指南

本文详细介绍了高通Memory QMVS测试环境搭建的全流程避坑指南,涵盖硬件选择、软件配置、QMVS核心组件安装及测试执行技巧。重点解析了adb工具配置、QPST日志抓取等关键步骤,帮助工程师高效搭建稳定测试环境,避免常见兼容性和稳定性问题。

weixin_29251567的博客 557

spring boot 2.x 使用mybatis拦截器实现系统日志记录(将完整参数的SQL语句记录到数据库中)

一、前言 最近要求做系统的全局日志记录功能,要求把执行的完整SQL语句保存到数据库中,在实际开发中最终放弃了使用AOP的方法,改由使用mybatis的拦截器实现,这里简单记录一下实现过程。 系统数据库主要环境: 数据库:MySQL 数据源:DruidDataSource 二、创建数据库用表 这里只是简单演示一下实现过程,只用两张表模拟一下: 用户表(user) CREATE TABLE `user` ( `id` bigint(20) NOT NULL, `age` int(11) NUL

Coder-文小白的博客 3072

Ambari 3.0.0 + BigTop 3.3.0 源码编译与集群部署指南(Kylin V10 / aarch64)

仅仅是针对“应用商店目录(Applications Catalog)”的一个外围附属子模块(它不是 YARN 监控大盘,不影响 YARN UI 网页的主体使用),我们可以采用。自带的 Node 二进制是 x86_64 版本,在 ARM64(aarch64)容器上无法执行(Exit value: 126)。:Ambari Server/Agent 使用 JDK 17,BigTop 大数据组件(Hadoop/HBase/Spark 等)使用 JDK 8。,源码中包含 x86 特定的原生二进制文件。

amumu1992的博客 492

DETRs with Collaborative Hybrid Assignments Training论文阅读与代码

在这篇论文中,作者观察到在DETR中将过少的 Query 分配为正样本,采用一对一的集合匹配,会导致对编码器输出的监督稀疏,严重损害编码器的区分特征学习,反之亦然,也会影响解码器中的注意力学习。为了缓解这个问题,作者提出了一种新颖的协同混合分配训练方案,名为Co-DETR,以从多样的标签分配方式中学习更高效、更有效的基于DETR的检测器。这种新的训练方案可以通过训练多个并行辅助 Head ,以一对多的标签分配方式(如ATSS和Faster RCNN)进行监督,轻松增强端到端检测器中编码器的学习能力。

qingjing0413的博客 1156

MyBatis拦截器对update,insert拦截.

1.自定义拦截器类实现org.apache.ibatis.plugin.Interceptor接口. import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlCommandType; imp...

cookie151的博客 1万+

Tessent Atpg系列 第七章 Running ATPG Patterns -- 如何书写proc文件

本篇文章是记录Tessent scan ATPG系列 本文并非是对userguide的完全翻译,而是自己对userguide的理解,此外,有部分比较深入的内容可能需要后续实验验证。本系列并不对tessent scan做过多描述。 请勿随意转载: 优快云 博主: ciscomonkey一种是在使用tessent scan之后使用ATPG 另一种是使用第三方工具,如snps的DFTC之后使用tessent的ATPG。 这里我们仅仅介绍without tessent scan之后tessent ATPG:对于t

ciscomonkey的博客 7696

Mybatis拦截器结合ThreadLocal实现数据库updateTime等操作字段的更新

Mybatis拦截器 可拦截的目标对象有四个(前面是可被拦截的对象,后面括号中是对象中可被拦截的方法) Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) ParameterHandler (getParameterObject, setParameters) S...

薛定谔的雄猫 2355

评估篇| 大模型评测综述

1、基于人类的评测。与针对基础大语言模型的自动化评测不同,微调大语言模型的评测更加注重模型在实际应用场景中的表现,如与人类交互的自然度、对齐度等。2、基于模型的评测。例如,AlpacaEval 排行榜 基于由大语言模型合成的人类需求指令作为评测任务,然后收集待评估大模型的回应,并采用 GPT-4 等大语言模型作为评测员,将待评估大语言模型的输出与参考输出进行成对比较。1、大语言模型对评估设置极为敏感,包括问题的表述方式、提示样本的选择以及答案的解析策略等,这些细微的差别都可能导致评估结果的显著变化。

youbingchen的博客 638

详解AXI4-Lite接口(3)--AXI4-Lite接口IP源码仿真及分析(Master接口)

通过本文您会学到:1、了解AXI4-Lite_Master接口的逻辑实现;2、加深Xilinx IP、仿真工具的使用;3、提高阅读时序图的能力。

孤独的单刀 6447

Mybatis通过拦截器打印并保存执行SQL

Web项目 1.创建拦截器类 import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map;...

王绍桦 1634

YOLOv11 TensorRT极致加速:C++部署性能优化完全指南

购买即可解锁300+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,别人有的本专栏也有!

LXY_LOVE36的博客 118

Mybatis拦截器记录数据变更信息

Slf4j})@Override// 获取MappedStatement//获取类型// 获取SQL语句的ID,哪个方法执行// // 获取SQL语句try {if(param!// 变更信息入表@Override// 使用 Plugin.wrap 方法生成代理对象@Override// 获取配置文件中的属性值拦截器加入Mybatis configurationSpringboot-Mybatis-start可以直接使用@Component加入。

cyh0107的博客 1302

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

mybatis拦截器记录sql日志

1.最近公司一个需求让我把每次执行的sql都保存到数据库,然而我看了一些网上的资料没有适合我的例子,下面是我自己用mybatis拦截器写的一套管理sql日志的代码; 其中保存的sql 使用Druid数据库连接池配置的打印SQL的方式,其他方式我也不太了解感兴趣的可以自己了解一下; 1.Druid的包 <dependency> <groupId>...

qq_41988504的博客 3108

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

使用MDC进行日志打印

在项目中,我们会使用拦截器,aop或者过滤器来进行请求信息的提取,打印工作,当我们获取到需要的信息之后,就需要打印出来记录到日志中,这个时候我们会把日志记录到mdc中,然后给传递参数给log的自定义配置中使用,如下: public class LogInterceptor extends HandlerInterceptorAdapter { private static final S...

韩小文的博客 6840

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

mybatis针对各种CRUD 操作拦截处理,方便日志处理

核心思路就是添加一个mybatis的拦截器,由Invocation invocation 拿到需要的参数信息 注意导入的包 import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.*; import org.springframework.stereotype.Component; import..

没故事的码农的博客 625

MyBatis日常:MyBatis日志拦截,实现用户操作记录入库

该需求目标:以最小的变更实现用户操作日志,并记录操作之前数据值。 经分析得知,该需求的主要目的就是拦截用户操作日志,由于需要记录用户、操作记录,故拦截Mybatis的操作日志。 具体代码如下: 核心类(实现mybatis Interceptor接口) @Component @Intercepts({ @Signature(type = Executor.class, method = "updat...

qq_40714770的博客 6477

为什么使用MDC进行记录日志信息

一、MDC的优点 1.如果你的系统已经上线,突然有一天老板说我们增加一些用户数据到日志里分析一下。如果没有MDC我猜此时此刻你应该处于雪崩状态。MDC恰到好处的让你能够实现在日志上突如其来的一些需求。 2.如果你是个代码洁癖,封装了公司LOG的操作,并且将处理线程跟踪日志号也封装了进去,但只有使用了你封装日志工具的部分才能打印跟踪日志号,其他部分(比如hibernate、myb...

点点的博客 2万+

springboot通过mybatis-plus中的Interceptor自定义一个拦截器实现打印完整sql(包含值)日志的功能

1、实现功能结果如下图所示,用红框框住的就是实现的打印功能,而下边带?号的是原始的: 2、具体springboot+mybatis项目的搭建请看:spring-boot+mybatis搭建一个后端restfull服务:https://blog.youkuaiyun.com/sunxiaoju/article/details/109607322,此文就是在此基础上延伸出来的。 3、要实现此功能需要加入如下依赖: <dependency> <groupI

sxj的专栏 2万+

基于注解配置mybatis及如何解析mybatis的配置文件

本篇文章讲述的基于注解配置mybatis及如何解析mybatis的配置文件,下一章会讲解mybatis如何具体结合spring来生成对应的bean代理对象 @Configuration("dataSourceConfig")//定义bean配置 @MapperScan(basePackages = DataSourceConfig.DaoPackage, sqlSessionFactoryRe...

zhaoquanwei2018的博客 828

本地化部署 DeepSeek,构建单细胞与空间转录组 AI 分析平台

本地化部署 DeepSeek,构建单细胞与空间转录组 AI 分析平台

weixin_53637133的博客 181

【第 009 讲】全面掌握 Python 注释:注释的定义与作用 | 单行注释 | 三引号与多行注释 | 注释使用的最佳实践

本文系统讲解 Python 注释的完整知识体系:从注释的定义与作用讲起,梳理单行注释的书写位置、临时屏蔽用法与 PEP 8 排版规范,剖析注释被忽略的底层机制;进而说明三引号字符串的本质与嵌套问题;最后给出注释使用的三条实践原则,帮助读者写好可读性高的注释。

大模型全栈工程师 · Thanks_ks 574

AI全栈实战 | 3.9-01 爬虫入门:requests 加 BeautifulSoup 三分钟跑通,但 90% 的人栽在这 4 个“礼貌“问题上

⚠️:本文内容仅用于。请遵守目标站点的服务条款与相关法律法规,不得对目标服务造成负担,不得采集、传播个人隐私数据。技术是中性的,边界在你手里。爬虫的入门技术(requests 发请求 + BeautifulSoup 解析)三分钟就能学会。真正区分"会用爬虫"和"会做爬虫的人"的,是这篇我们跑通"请求→解析→存储"的最小闭环,然后重点把"合规与礼貌"这根弦给你绷上。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 432
上一篇: Kafka集群的安装与配置(二)
下一篇: TokenUtil
ole_triangle_java
博客等级 码龄10年 82粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值