当前位置: 首页 > news >正文

使用mybatis的statementHander拦截器监控表和字段并发送钉钉消息

新建mybatis的statementHander拦截器拦截器 类

面试题:

2.实现

解析Sql时引入JSqlParser

JSqlParser 是一个 SQL 语句解析器。 它将 SQL转换为可遍历的 Java 类层次结构。 

<dependency><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifactId><version>4.6</version></dependency>

 添加拦截器代码:

package com.yy.config;import cn.hutool.core.collection.CollUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.smart.model.LocalUser;
import cn.smart.util.ThreadlocalUtil;
import com.yy.entity.BaseEntity;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.update.UpdateSet;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
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.springframework.stereotype.Component;import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Component
@Intercepts({// 指定要拦截的方法签名,这里是拦截Executor的update方法@Signature(type = StatementHandler.class, method = "update", args = {Statement.class}),// 可以添加更多要拦截的方法签名...
})
public class StatementHanderInterceptor implements Interceptor {private static List<String> tables = CollUtil.newArrayList("product","category");private static Map<String,List<String>> tableColumns = new HashMap<>();static {tableColumns.put("product",CollUtil.newArrayList("name","price"));}@Overridepublic Object intercept(Invocation invocation) throws Throwable {StatementHandler statementHandler =(StatementHandler)invocation.getTarget();//要想监控表,首先要从拦截器中拿到sql语句,看sql语句干了什么,对那些表和那些字段做了什么BoundSql boundSql = statementHandler.getBoundSql();String sql = boundSql.getSql();
//        使用JSqlParser解析器解析sql语句net.sf.jsqlparser.statement.Statement statement = CCJSqlParserUtil.parse(sql);if(statement instanceof Update){Update update = (Update)statement;String name = update.getTable().getName();if(tables.contains(name)){List<String> updataSets = tableColumns.get(name);ArrayList<UpdateSet> updateSets = update.getUpdateSets();for (UpdateSet updateSet : updateSets) {String columnName = updateSet.getColumns().get(0).getColumnName();if(updataSets.contains(columnName)){sendMessage(   "修改了字段"+updateSet,name);}}}}else if(statement instanceof Insert){Table table = ((Insert) statement).getTable();String name = table.getName();if(tables.contains(name)){sendMessage("添加了数据",name);}}return invocation.proceed();}private void sendMessage(String option,String tableName){String url= "https://oapi.dingtalk.com/robot/send?access_token=1cfb9a7b20e849a26b572a8ff98f62ee2a220028cd1452901a486e131435621f";JSONArray array = new JSONArray();array.add("18236435312");JSONObject msg = new JSONObject();msg.set("msgtype","text");msg.set("text",new JSONObject().set("content","警告:"+ThreadlocalUtil.get().getNickName()+"-> "+option+" ,表名是:"+tableName));msg.set("at",new JSONObject().set("atMobiles",array));String json = JSONUtil.toJsonStr(msg);String body = HttpRequest.post(url).body(json).execute().body();}}

遇到的问题:

因为这个pagehelper是从stater中继承过来的,可以在stater中也加一个4.6版本的jsqlparser依赖

 

相关文章:

使用mybatis的statementHander拦截器监控表和字段并发送钉钉消息

新建mybatis的statementHander拦截器拦截器 类 面试题&#xff1a; 2.实现 解析Sql时引入JSqlParser JSqlParser 是一个 SQL 语句解析器。 它将 SQL转换为可遍历的 Java 类层次结构。 <dependency><groupId>com.github.jsqlparser</groupId><artifac…...

信贷系统——基础信贷概念

摘要 信贷是金融领域中的一个重要概念,指的是金融机构(如银行、信用合作社等)向个人、企业或政府提供资金的过程。在信贷过程中,金融机构向借款人提供资金,借款人则承诺在未来的某个时间点按照约定的条件和利率偿还借款。这种借款通常是在合同中明确约定的,包括贷款金额、…...

分页查询及其拓展应用案例

分页查询 分页查询是处理大量数据时常用的技术&#xff0c;通过分页可以将数据分成多个小部分&#xff0c;方便用户逐页查看。SQLAlchemy 提供了简单易用的方法来实现分页查询。 本篇我们也会在最终实现这样的分页效果&#xff1a; 1. 什么是分页查询 分页查询是将查询结果按照…...

【UE5.1】NPC人工智能——02 NPC移动到指定位置

效果 步骤 1. 新建一个蓝图&#xff0c;父类选择“AI控制器” 这里命名为“BP_NPC_AIController”&#xff0c;表示专门用于控制NPC的AI控制器 2. 找到我们之前创建的所有NPC的父类“BP_NPC” 打开“BP_NPC”&#xff0c;在类默认值中&#xff0c;将“AI控制器类”一项设置为“…...

有关电力电子技术的一些相关仿真和分析:⑤交-直-交全桥逆变+全波整流结构电路(MATLAB/Siumlink仿真)

全桥逆变+全波整流结构 参数:Vin=500V, Vo=200V, T=2:1:1, RL=10Ω, fs=100kHz, L=1mH, C=100uF (1)给定输入电压,输出电压和主电路参数,仿真研究电路工作原理,分析工作时序; (2)调节负载电阻,实现电流连续和断续,并仿真验证; (3)调节占空比,分析占空比与电…...

记录一次Android推流、录像踩坑过程

背景&#xff1a; 按照需求&#xff0c;需要支持APP在手机息屏时进行推流、录像。 技术要点&#xff1a; 1、手机在息屏时能够打开camera获取预览数据 2、获取预览数据时进行编码以及合成视频 一、息屏时获取camera预览数据&#xff1a; ①Camera.setPreviewDisplay(SurfaceH…...

VsCode 与远程服务器 ssh免密登录

首先配置信息 加入下列信息 Host qb-zn HostName 8.1xxx.2xx.3xx User root ForwardAgent yes Port 22 IdentityFile ~/.ssh/id_rsa 找到自己的公钥&#xff0c;不带pub是私钥&#xff0c;打死都不能给别人。复制公钥 拿到公钥后&#xff0c;来到远程服务器 vim ~/.ss…...

7/13 - 7/15

vo.setId(rs.getLong("id"))什么意思&#xff1f; vo.setId(rs.getLong("id")); 这行代码是在Java中使用ResultSet对象&#xff08;通常用于从数据库中检索数据&#xff09;获取一个名为"id"的列&#xff0c;并将其作为long类型设置为一个对象…...

烟雾监测与太阳能源:实验装置在其中的作用

太阳光在烟雾中的散射效应研究实验装置是一款模拟阳光透过烟雾环境的设备。此装置能帮助探究阳光在烟雾中的传播特性、散射特性及其对阳光的影响。 该装置主要包括光源单元、烟雾发生装置、光学组件、以及系统。光源单元负责产生类似于太阳光的光线&#xff0c;通常选用高亮度的…...

QT下,如何获取控制台输入

最近工作中为了测试某个模块&#xff0c;需要把原先输入模块部分&#xff0c;改成控制台输入来方便测试。在QT中&#xff0c;我们可以使用 QTextStream 类来读取用户的输入来达到目的。下面是一个简单的例子&#xff1a; #include <QCoreApplication> #include <QTex…...

mybatis动态传入参数 pgsql 日期 Interval ,day,minute

mybatis动态传入参数 pgsql 日期 Interval 在navicat中&#xff0c;标准写法 SELECT * FROM test WHERE time > (NOW() - INTERVAL 5 day)在mybatis中&#xff0c;错误写法 SELECT * FROM test WHERE time > (NOW() - INTERVAL#{numbers,jdbcTypeINTEGER} day)报错内…...

常见CSS属性

常见CSS属性。 1. display: 定义&#xff1a;display 属性控制元素如何渲染在文档流中&#xff0c;影响了元素是否占用空间、位置及盒子模型的行为。 使用说明&#xff1a;它可以设置为如block, inline, inline-block, flex, grid, none等值&#xff0c;用于决定元素显示模式…...

WSL-Ubuntu20.04训练环境配置

1.YOLOv8训练环境配置 训练环境配置的话就仍然以YOLOv8为例&#xff0c;来说明如何配置深度学习训练环境。这部分内容比较简单&#xff0c;主要是安装miniAnaconda以及安装torch和torchvision. 首先是miniAnaconda的安装(参考官网的教程Miniconda — Anaconda )&#xff0c;执行…...

运维检查:mysql表自增id是否快要用完

数据库表中最大自增ID用完会报错。判断是否接近或达到自增ID类型的最大值&#xff1a;‌ 对于MySQL中的自增ID&#xff0c;‌如果使用的是int类型&#xff0c;‌其无符号&#xff08;‌unsigned&#xff09;‌的最大值可以达到2^32 - 1&#xff0c;‌即4294967295。‌如果使用的…...

深入理解FFmpeg--libavformat接口使用(一)

libavformat&#xff08;lavf&#xff09;是一个用于处理各种媒体容器格式的库。它的主要两个目的是去复用&#xff08;即将媒体文件拆分为组件流&#xff09;和复用的反向过程&#xff08;以指定的容器格式写入提供的数据&#xff09;。它还有一个I/O模块&#xff0c;支持多种…...

坚持日更的意义何在?

概述 日更&#xff0c;就是每天更新一次或一篇文章。 坚持日更&#xff0c;就是坚持每天更新一次或一篇文章。 这里用了坚持&#xff0c;实际上不是恰当的表述&#xff0c;正确的感觉应该是让日更当作习惯&#xff0c;然后&#xff0c;让自己习惯每天去更新一篇文章。 日更…...

内容长度不同的div如何自动对齐展示

平时我们经常会遇到页面内容div结构相同页&#xff0c;这时为了美观我们会希望div会对齐展示&#xff0c;但当div里的文字长度不一时又不想写固定高度&#xff0c;就会出现div长度长长短短&#xff0c;此时实现样式可以这样写&#xff1a; .e-commerce-Wrap {display: flex;fle…...

Qt中https的使用,报错TLS initialization failed和不能打开ssl.lib问题解决

前言 在现代应用程序中&#xff0c;安全地传输数据变得越来越重要。Qt提供了一套完整的网络API来支持HTTP和HTTPS通信。然而&#xff0c;在实际开发过程中&#xff0c;开发者可能会遇到SSL相关的错误&#xff0c;例如“TLS initialization failed”&#xff0c;cantt open ssl…...

P2p网络性能测度及监测系统模型

P2p网络性能测度及监测系统模型 网络IP性能参数 IP包传输时延时延变化误差率丢失率虚假率吞吐量可用性连接性测度单向延迟测度单向分组丢失测度往返延迟测度 OSI中的位置-> 网络层 用途 面相业务的网络分布式计算网络游戏IP软件电话流媒体分发多媒体通信 业务质量 通过…...

zookeeper相关总结

1. ZooKeeper 的架构 ZooKeeper 采用主从架构&#xff08;Leader-Follower 模型&#xff09;&#xff0c;包括以下组件&#xff1a; Leader&#xff1a;负责处理所有写请求和协调事务一致性。Follower&#xff1a;处理读请求并转发写请求给 Leader。参与 Leader 选举和事务提…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...