对象变更记录objectlog工具(持续跟新)
文章目录
- 前言
- 演示代码
- 演示环境
- 引入项目
- 项目框架
- 操作步骤
- 设计介绍
- 参考仓库
前言
系统基于mybatis-plus, springboot环境
对于重要的一些数据,我们需要记录一条记录的所有版本变化过程,做到持续追踪,为后续问题追踪提供思路。下面展示预期效果(根据对象field渲染即可):

除了上面这种简单的记录外,还可以记录复合操作,下面举两个例子:
- 对于批量导入,除了记录对象a本身的变化过程,还维护了父操作id,父操作id我们可以直观了解这个对象a创建的源头,在源头记录中,我们可以获取源头操作所有操作内容(包含了对象a的操作),实现不同对象的联动。
- 对于单个对象a,若存在关联表字段b对象的修改,会自动将b对象的变更记录和对象a操作记录绑定(当然对象a本身也会产生操作记录)
源代码地址,感兴趣的朋友gitee上提issue单,后面持续补充。
演示代码
下面我们通过一段代码演示代码,展示如何自动将枚举字段,主键关联字段,多行文本串,富文本内容等字段自动进行转换和记录(对于其他类型的你可以按照系统规则,自己重写逻辑)。在此期间,你只需要配置两个注解(@LogEntity,@LogPoint)相关的属性即可实现对象日志的记录,非常方便。
工具采用spring切面和mybatis拦截器的方式编写了
api依赖包,以非侵入方式实现对标记的对象属性进行记录,仅需要导入依赖即可,几乎不需要对原系统代码改动
@LogEntity //开启标识
public class SysUserModel extends BaseEntity {@LogEntity(alias = "角色信息", associationValue = true, serviceImplClass = SysRoleServiceImpl.class, entityFieldName = "roleName")//角色表存在 (9830274072323 测试角色) 这一条数据@ApiModelProperty(name = "roleId",value = "角色表,角色id,逗号隔开")private String roleId;@LogEntity(alias = "用户昵称")@ApiModelProperty(name = "userName",value = "用户昵称")private String userName;@LogEntity(alias = "备注" ,attributeTypeEnum = AttributeTypeEnum.TEXT)@ApiModelProperty(name = "remark",value = "备注")private String remark;@LogEntity(alias = "富文本内容" , attributeTypeEnum = AttributeTypeEnum.RICHTEXT)@ApiModelProperty(name = "richText",value = "富文本内容")private String richText;@LogEntity(alias = "帐号状态",enumValue = true,enumClass = StatusEnum.class)@ApiModelProperty(name = "status",value = "帐号状态(0正常 1停用)")private Integer status;
}
public enum StatusEnum {NORMAL(0,"正常"),DEACTIVATE(1,"停用"),;//....
}
@RestController
@RequestMapping(value = "/test")
public class TestController {@Resourceprivate SysUserService userService;@Resourceprivate SysRoleService roleService;@Resourceprivate ObjectOperationService operationService;@GetMapping(value = "/add")@ResponseBodypublic Object testAdd(){SysUserModel userModel = new SysUserModel();userModel.setRoleId("9830274072323");userModel.setUserName("哈哈");userModel.setRemark("这是第一行\n" + "这是第二行");userModel.setStatus(0);userModel.setRichText("<p1>富文本<p1>");userService.add(userModel);}
}
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserModel> implements SysUserService {@Override@LogPoint( serviceHandler = SysUserServiceImpl.class, entityHandler = SysUserModel.class,moduleName = "sysUser", remark = "测试用户模块")public void add(SysUserModel insertModel) {this.insert(insertModel);}
}
结果如下图所示:

{"version":"1.0.0","content":[{"lineNumber":1,"partList":[{"partContent":"这是第一行","partType":"CHANGE_NEW"},{"partContent":"这是第二行","partType":"CHANGE_NEW"}]}]
}
可以看到操作很简单,标记两个注解就可以了。
演示环境
-
导入表 (mysql)

-
启动nacos(需要发现服务)
-
启动项目
引入项目
系统现在默认将日志记录api作为依赖
集成到某个具体的业务模块中,当然也可以直接将日志做为一个新的服务,下面我们按集成到某个具体的业务模块中进行介绍。
项目框架
演示系统将核心逻辑拆解为objectlog-api和objectlog-api-test,其中api是作为依赖引入到你的业务模块中,api-test则是演示系统中的业务模块。

在api依赖中分为core,domain,feign三个包,其中core是核心内容,另外两个根据自身业务可以进行删除和变更
- core包:核心逻辑的实现
- domain包:自身业务的基类BaseEntity,自动填充字段逻辑BaseMetaObjectHandler和操作记录查询封装类ObjectOperationDto.
- feignt包:查询操作记录相关的feign配置

操作步骤
-
导入表,
objectlog-api-test模块下的object_attribute.sql和object_operation.sql导入到业务模块中 -
改变基类对象,目前主流的mybatis-plug提供了自带curd操作类
ServiceImpl,IService,BaseMapper,在@LogPoint中ServiceImpl切换自身业务系统基于ServiceImpl进一步封装类,其次是BaseEntity.class,这个是你自身业务系统的基类。

设计介绍
首先是前文提到的两个注解@LogEntity,@LogPoint

- BASE : 单个的对象记录,不存在子对象的记录
- COMMENT: 一组对象的记录,不存在父子关系,如批量导入
- COMPLEX:单个对象的记录,存在子对象的记录

在核心包中有一个handler包,下面提供字段如何字段转换和解析。在包中提供了基础类型(NORMAL,RICHTEXT,TEXT)的类型处理器和值处理器,他们分别实现了AttributeTypeHandler,AttributeValueHandler中的方法,下面我们对其进行一些讲解。

在@LogEntity注解中如果没有指定类型处理器我们发现使用了默认处理器处理,如果你
当前系统实现不符合业务逻辑,你可以重写默认处理器中的逻辑即可,或者你创建一个类继承相关接口,重写逻辑,然后在把重写的类赋予注解中的值即可

参考仓库
原仓库只是简单的实现,入侵业务严重,不过对于本系统中RICHTEXT,TEXT类型的字段提供了思路
github
相关文章:
对象变更记录objectlog工具(持续跟新)
文章目录 前言演示代码演示环境引入项目项目框架操作步骤 设计介绍参考仓库 前言 系统基于mybatis-plus, springboot环境 对于重要的一些数据,我们需要记录一条记录的所有版本变化过程,做到持续追踪,为后续问题追踪提供思路。下面展示预期效果…...
平衡二叉树,二叉树的路径,左叶子之和
第六章 二叉树part04 今日内容: 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和 110.平衡二叉树 (优先掌握递归) 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为&am…...
Sodinokibi勒索病毒最新变种,解密工具更新到2.0版本
Sodinokibi勒索病毒 Sodinokibi勒索病毒又称REvil,自从2019年6月1日,GandCrab勒索病毒运营团伙宣布停止运营之后,Sodinokibi勒索病毒马上接管了GandCrab的大部分传播渠道,同时它也被称为是GandCrab勒索病毒的“接班人”ÿ…...
css 鼠标移入放大的效果
效果 HTML <div class"img-wrap"><img class"img-item" src"../assets/1.png" alt"" srcset""></div> CSS <style lang"less" scoped> .img-wrap {/* 超出隐藏 */overflow: hidden;.img-…...
Transformer模型分布式并行通信量浅析
1.数据并行DP(朴素数据并行,Zero数据并行之后补充) O ( h 2 ∗ l ) O(h^2*l) O(h2∗l) 每台机器做完自己的梯度后需要做一次All reduce操作来累积梯度,故一个batch计算发送的数据量为每层梯度大小 h 2 h^2 h2乘以层数 l l l 优点…...
PMP考试之20240304
1.一家食品公司正在使用预测型方法开发一种新产品,该产品目前正处于测试阶段。鉴于测试反馈的性质,项目经理决定使用迭代方法。在其中一个迭代结束时,颁布了与该产品有关的新法规。项目经理接下来应该做什么? A.就项目的范围提出…...
智慧城市中的公共服务创新:让城市生活更便捷
目录 一、引言 二、智慧城市公共服务创新的实践 1、智慧交通系统 2、智慧医疗服务 3、智慧教育系统 4、智慧能源管理 三、智慧城市公共服务创新的挑战 四、智慧城市公共服务创新的前景 五、结论 一、引言 随着信息技术的迅猛发展,智慧城市已成为现代城市发…...
bert 相似度任务训练完整版
任务 之前写了一个相似度任务的版本:bert 相似度任务训练简单版本,faiss 寻找相似 topk-CSDN博客 相似度用的是 0,1,相当于分类任务,现在我们相似度有评分,不再是 0,1 了,分数为 0-5,数字越大…...
Ribbon实现Cloud负载均衡
安装Zookeeper要先安装JDK环境 解压 tar -zxvf /usr/local/develop/jdk-8u191-linux-x64.tar.gz -C /usr/local/develop 配置JAVA_HOME vim /etc/profile export JAVA_HOME/usr/local/develop/jdk1.8.0_191 export PATH$JAVA_HOME/bin:$PATH export CLASSPATH.:$JAVA_HOM…...
【UE 材质】制作加载图案(2)
在上一篇(【UE 材质】制作加载图案)基础上继续实现如下效果的加载图案 效果 步骤 1. 复制一份上一篇制作的材质并打开 2. 添加“Floor”节点向下取整 除相同的平铺数 此时的效果如下 删除如下节点 通过“Ceil”向上取整,参数“Tiling”默认…...
为啥要用C艹不用C?
在很多时候,有人会有这样的疑问 ——为什么要用C?C相对于C优势是什么? 最近两年一直在做Linux应用,能明显的感受到C带来到帮助以及快感 之前,我在文章里面提到环形队列 C语言,环形队列 环形队列到底是怎么回…...
Java:JVM基础
文章目录 参考JVM内存区域程序计数器虚拟机栈本地方法栈堆方法区符号引用与直接引用运行时常量池字符串常量池直接内存 参考 JavaGuide JVM内存区域 程序计数器 程序计数器是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器,各线程…...
JavaSec 基础之五大不安全组件
文章目录 不安全组件(框架)-Shiro&FastJson&Jackson&XStream&Log4jLog4jShiroJacksonFastJsonXStream 不安全组件(框架)-Shiro&FastJson&Jackson&XStream&Log4j Log4j Apache的一个开源项目,是一个基于Java的日志记录框架。 历史…...
python类的属性、方法、静态方法、静态方法类内部的调用、直接调用与实例化调用
设计者:ISDF工软未来 版本:v1.0 日期:2024/3/4 class Restaurant:餐馆类def __init__(self,restaurant_name,cuisine_type):#类的属性self.restaurant_name restaurant_nameself.cuisine_type cuisine_type# self.stregth_level 0def desc…...
haproxy集成国密ssl功能[下]
上接[haproxy集成国密ssl功能上 4. 源码修改解析 以下修改基本围绕haproxy的ssl_sock.c进行修改来展开的,为了将整个实现逻辑能够说明清楚,下述内容有部分可能就是直接摘抄haproxy的原有代码没有做任何修改,而大部分增加或者修改的内容则进行了特别的说明。 4.1 为bind指令…...
C++自学精简实践教程
一、介绍 1.1 教程特点 一篇文章从入门到就业有图有真相,有测试用例,有作业;提供框架代码,作业只需要代码填空规范开发习惯,培养设计能力 1.2 参考书 唯一参考书《C Primer 第5版》参考书下载: 蓝奏云…...
每日一题——LeetCode1572.矩阵对角线元素的和
方法一 遍历矩阵 如果矩阵中某个位置(x,y)处于对角线上,那么这个位置必定满足: xy 或 xy len-1 (len为矩阵长度) var diagonalSum function(mat) {let len mat.length;let sum 0;for (let i 0; i …...
mysql 常用命令练习
管理表格从表中查询数据从多个表查询修改数据sql变量类型 管理表格 创建一个包含三列的新表 CREATE TABLE products (id INT,name VARCHAR(255) NOT NULL,price INT DEFAULT 0,PRIMARY KEY(id) // 自增 ); 从数据库中删除表 DROP TABLE product; 向表中添加新列 ALTER TAB…...
QT6 libModbus 用于ModbusTcp客户端读写服务端
虽然在以前的文章中多次描述过,那么本文使用开源库libModbus,可得到更好的性能,也可移植到各种平台。 性能:读1次和写1次约各用时2ms。 分别创建了读和写各1个连接指针,用于读100个寄存器和写100个寄存器,读写分离。 客户端&am…...
飞桨(PaddlePaddle)Tensor使用教程
文章目录 飞桨(PaddlePaddle)Tensor使用教程1. 安装飞桨2. 创建Tensor3. Tensor的基本属性4. Tensor的操作5. Tensor的广播机制6. Tensor与Numpy数组的转换7. 结论 飞桨(PaddlePaddle)Tensor使用教程 1. 安装飞桨 首先ÿ…...
Python AOT编译不再依赖LLVM:2026插件如何实现纯Python源码→本地机器码直编?下载链接+SHA3-512校验值全公开
第一章:Python 原生 AOT 编译方案 2026 插件下载与安装Python 原生 AOT(Ahead-of-Time)编译方案 2026 是 CPython 官方实验性扩展项目,旨在为 Python 提供无需运行时解释器即可生成独立可执行文件的能力。该方案基于 PEP 712 和 L…...
AutoGLM-Phone-9B功能体验:实测语音指令控制与图像识别
AutoGLM-Phone-9B功能体验:实测语音指令控制与图像识别 1. 多模态能力初体验 AutoGLM-Phone-9B作为一款专为移动端优化的多模态大模型,其最吸引人的特点莫过于融合了视觉、语音与文本处理能力。在实际测试中,我发现这款模型在资源受限设备上…...
CppJieba中文分词架构深度解析与实战指南
CppJieba中文分词架构深度解析与实战指南 【免费下载链接】cppjieba "结巴"中文分词的C版本 项目地址: https://gitcode.com/gh_mirrors/cp/cppjieba CppJieba作为"结巴"中文分词的C高性能实现,为C开发者提供了工业级的中文分词解决方案…...
2026年重庆豆包排名GEO优化公司推荐与选型避坑指南(附5大服务商真实测评)
第一部分:引言与需求明确作为西部制造业核心、国际消费中心城市,重庆目前已形成汽车、电子信息、装备制造、先进材料、食品加工五大千亿级支柱产业,同时家装、文旅、大宗消费等赛道市场竞争逐年白热化。据2026年重庆本地数字营销行业调研数据…...
10个提升性能的技巧:msgpack Golang最佳实践
10个提升性能的技巧:msgpack Golang最佳实践 【免费下载链接】msgpack msgpack.org[Go] MessagePack encoding for Golang 项目地址: https://gitcode.com/gh_mirrors/msg/msgpack msgpack Golang是一款高效的MessagePack编码库,为Go语言开发者提…...
ATCODER ABC C题解饺
这,是一个采用C精灵库编写的程序,它画了一幅漂亮的图形: 复制代码 #include "sprites.h" //包含C精灵库 Sprite turtle; //建立角色叫turtle void draw(int d){for(int i0;i<5;i)turtle.fd(d).left(72); } int main(){ …...
避坑指南:SpyGlass常见三大链接设计错误(set_goal_option/get_goal_option/remove_goal_option)的修复方法
SpyGlass时序控制三大API调用陷阱与工程化解决方案 在数字芯片验证领域,SpyGlass作为RTL静态验证的事实标准工具,其强大的分析能力背后隐藏着诸多新手容易踩中的时序控制陷阱。特别是set_goal_option、get_goal_option和remove_goal_option这三个关键API…...
Profinet转MODBUS TCP在精细化工塔讯工业自动化中的应用方案
一、案例背景化工行业属于流程型工业,对生产过程中的压力、流量、液位等参数监控要求极高,安全生产是行业核心底线。某精细化工园区新建数字化生产车间,现场过程监测设备采用Profinet协议智能仪表,包括西门子SITRANS P系列压力仪表…...
实战指南:构建坚不可摧的vCenter HA高可用集群
1. 为什么你的企业需要vCenter HA高可用集群 记得去年有个客户半夜给我打电话,说他们的vCenter突然宕机,整个虚拟化平台瘫痪了。当时正是业务高峰期,损失惨重。这就是典型的单点故障问题——vCenter作为整个vSphere环境的大脑,一旦…...
[ 渗透实战篇 ] Kali Linux下ARP欺骗攻防全解析:从断网攻击到流量劫持
1. ARP欺骗技术基础与实战环境搭建 在局域网安全领域,ARP欺骗就像是一个隐形的"窃听者",它能悄无声息地让网络流量改道流向攻击者的机器。要理解这个技术,我们得先从ARP协议说起。ARP(Address Resolution Protocol&…...
