spring boot加mybatis puls实现,在新增/修改时,对某些字段进行处理,使用的@TableField()或者AOP @Before

news2024/10/6 6:01:26

1.先说场景,在对mysql数据库表数据插入或者更新时都得记录时间和用户id

传统实现有点繁琐,这里还可以封装一下公共方法。

2.解决方法:

    2.1:使用aop切面编程(记录一下,有时间再攻克)。

        2.1.1:成功实现进行补充,感谢网友顶力相助(进步·于辰)

         2.1.2:在启动器上加   @EnableAspectJAutoProxy

         2.1.3:切入主要代码

@Aspect
@Component
@Slf4j
public class EntityAttrAspect {

    @Before("execution(* com.zuodou..*.save*(..))"+
          " ||execution(* com.zuodou..*.update*(..))"
    )
    public void before(JoinPoint joinPoint) throws Exception {
        log.info("切入");
        String userId = BaseUtlis.getCurrentUser().getId();// 管理员id
        Object[] args = joinPoint.getArgs();

        for (Object arg : args) {
            if (arg != null) {
                   Class<?> clazz = arg.getClass();
                    // 获取实体所有属性,进而获取主键属性。一般情况下,主键属性是第一个
                    Class<?> entityClass = clazz; // 使用clazz获取实体类的类型
                    Field[] entityFieldArr = entityClass.getDeclaredFields();
                    Field idField = entityFieldArr[0];// 主键属性
                    idField.setAccessible(true);//设置为可以访问
                    Object id = idField.get(arg); // 使用arg获取实体对象的主键值
                    if (id == null) {// 无主键,插入
                        if (StringUtils.isNotBlank(userId)){
                            entityAttrIoc(arg, "createBy", userId);// 创建人
                        }

                        entityAttrIoc(arg, "createTime", new Date());// 创建时间
                    } else {// 有主键,更新
                        if (StringUtils.isNotBlank(userId)){
                            entityAttrIoc(arg, "updateBy", userId);// 修改人
                        }
                        entityAttrIoc(arg, "updateTime", new Date());// 更新时间
                    }

            }
        }

    }

    // entityAttrIoc方法的定义可以是类似于下面这样的形式:
    private void entityAttrIoc(Object entity, String attributeName, Object value) throws Exception {
        Field field = entity.getClass().getDeclaredField(attributeName);
        field.setAccessible(true);
        field.set(entity, value);
    }

}

    注:

@Before("execution(* com.zuodou..*.save*(..))"+ " ||execution(* com.zuodou..*.update*(..))" )

切入点的表达式,不懂了可以先去了解表达式配置

我只需要判断新增还是修改,

Field idField = entityFieldArr[0];// 主键属性
idField.setAccessible(true);//设置为可以访问

我主键是由  file  和  static  修饰的  所以得加setAccessible

    2.2:使用@TableField()注解。

3.我使用的@TableField  注解实现,因为没有很多的业务处理,单纯的记录一下,以下是具体实现

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        // 在插入时自动填充 create_time 和 update_time 字段
        this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
        this.strictInsertFill(metaObject, "createBy", String.class, BaseUtlis.getCurrentUser().getId());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        // 在更新时自动填充 update_time 字段
        this.strictUpdateFill(metaObject, "updateTime",Date.class, new Date());
        this.strictInsertFill(metaObject, "updateBy", String.class, BaseUtlis.getCurrentUser().getId());
    }
}

注: 字段需要跟实体类对应起来,我项目架构是使用了驼峰命名使用下划线后字母大写。BaseUtlis.getCurrentUser().getId(),这个是我封装的一个获取当前登录用户的方法。

参数解析:

this.strictUpdateFill(metaObject, "updateTime",Date.class, new Date());

metaObject:对象

updateTime:实体类目标字段

Date.class:数据类型

new Date():具体值

4.yml配置

mybatis-plus:
  global-config:
    db-config:
      meta-object-handler: com.zuodou.mymeta.MyMetaObjectHandler

5.在对应实体类的字段上加

@TableField(fill = FieldFill.UPDATE)

或者

@TableField(fill = FieldFill.INSERT)

6.补充缺陷

直接在controllerdi调用根据id修改方法   或者 update 批量根据id修改, 会不触发自动填充

解决使用update,条件传入id或者在service调用,而updateBatchById就需要手动传了。

至于为什么在service调用updateById就能触发

在 MyBatis Plus 中,通常通过继承 ServiceImpl 类来实现 Service 层的操作。这个类提供了一些默认的 CRUD(增删改查)方法,并且默认情况下会使用 MyBatis Plus 的内置功能,比如自动填充。
当你在自己的 Service 类中继承了 ServiceImpl 并且指定了泛型类型,比如 YourService extends ServiceImpl&lt;YourMapper, YourEntity&gt;,这样就将 YourService 和 YourEntity 关联起来了。
MyBatis Plus 的 ServiceImpl 已经预先实现了一些常见的操作方法,其中包括了自动填充的支持。在这个类中,如果你调用了 updateById 方法,它内部会调用 MyBatis Plus 的自动填充逻辑,以便在更新数据时触发自动填充。
当然,前提是你需要做以下几件事情:

1.确保你的实体类中的字段有正确地标注了自动填充的注解,比如使用了 @TableField 注解并设置了相应的 fill 属性。
2.确保你已经正确配置了 MetaObjectHandler,并且这个配置被正确地注册到了 Spring 容器中。这样 MyBatis Plus 才能正确地使用自动填充功能。

因此,当你在自定义的 Service 类中继承了 ServiceImpl,就相当于在你的 Service 类中内置了 MyBatis Plus 提供的默认实现,包括自动填充的支持。这样,在调用 updateById 等方法时,会自动触发 MyBatis Plus 的自动填充逻辑。

(侵权联系删除)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1233497.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

盘点35个Python书籍Python爱好者不容错过

盘点35个Python书籍Python爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1uf-MXZc9aC7y3Qju6VnCYw?pwd8888 提取码&#xff1a;8888 书籍名称&#xff1a; Django教…

Servlet---API详解

文章目录 HttpServlet基础方法doXXX方法Servlet的生命周期 HttpServletRequest获取请求中的信息获取请求传递的参数获取 query string 里的数据获取form表单里的数据获取JSON里的数据如何解析JSON格式获取数据返回数据 HttpServletResponse设置响应的Header设置不同的状态码设置…

Linux入门必备指令

Linux学习之路起始篇——Linux基本指令 文章目录 Linux学习之路起始篇——Linux基本指令**一、ls指令****二、pwd命令****三、cd命令****四、touch指令****五、mkdir命令****六、rm命令****七、man 命令****八、cp命令****九、mv命令****10、cat 指令****十一、tac命令** 前言&…

基于蜜獾算法优化概率神经网络PNN的分类预测 - 附代码

基于蜜獾算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于蜜獾算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于蜜獾优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…

基于Spring Boot 框架的试卷自动生成系统的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。你想解决的问题&#xff0c;今天给大家介绍…

数据结构:lambda表达式

基本概念 语法 // 1. 不需要参数,返回值为 2 () -> 2 // 2. 接收一个参数(数字类型),返回其2倍的值 x -> 2 * x // 3. 接受2个参数(数字),并返回他们的和 (x, y) -> x y // 4. 接收2个int型整数,返回他们的乘积 (int x, int y) -> x * y // 5. 接受一个 string 对…

【外汇天眼】投资之道:成功背后的频繁交易陷阱

成功的投资需要超越人性的短板&#xff0c;其中之一就是频繁交易。巴菲特曾明言&#xff0c;如果商学院的毕业生在毕业后拿一张卡片&#xff0c;每买一支股票就打一个洞&#xff0c;那么这张卡片最终会被打得最少的人将成为巨富。“钱在这里从活跃的投资者流向有耐心的投资者。…

leetcode——设计循环队列

设计循环队列 这个题目在这里小编只分享一个解题思路&#xff0c;因为还有一个思路小编还在尝试&#xff0c;一直过不了&#xff0c;还在这里不断尝试&#xff0c;等我试出来的时候我在分享给大家&#xff0c;首先我们在这里给出的是数组的形式&#xff0c;后面在分享单链表的思…

Python loglog()函数

常用坐标下的图像显示 import matplotlib.pyplot as plt import numpy as np import mathplt.figure() x_input np.linspace(1, 10, 50) y_input x_input**2plt.plot(x_input, y_input,r-,linewidth2) plt.show()在loglog函数尺度下的曲线 plt.loglog(x_input, y_input,r-,…

筒仓料位监测|敢不敢对“精度”下狠手!您家筒仓料位测得准吗?

您家是不是还在人工敲仓估算&#xff1f; 您能精确知道料位和库存吗&#xff1f; 您能实时看到库存盈亏吗&#xff1f; 筒仓里装了什么&#xff1f;用了多少&#xff1f; 什么时候进料最划算&#xff1f; 您家的筒仓管理方式可靠吗&#xff1f; 上海思伟筒仓料位监测方案 看…

Atlassian发布最新补贴政策,Jira/Confluence迁移上云最低可至零成本

到2024年2月15日&#xff0c;Atlassian将不再提供对Jira、Confluence、Jira Service Management等Server版产品的支持。 近期&#xff0c;Atlassian推出了一项针对云产品的特殊优惠。现在从Server版迁移到云版&#xff0c;您能享受到高额补贴&#xff0c;甚至成本低至零元。立…

计算机网络——数据链路层简解

1. 前言&#xff1a; 数据链路层&#xff0c;即在物理层之上网络层之下&#xff0c;数据链路层的数据交互可以通过mac来确实身份和发送数据。 说到数据链路层这里简单介绍下设备&#xff1a; 网桥&#xff08;Bridge&#xff09;&#xff1a; 网桥是一种数据链路层设备&#…

C语言——深入理解指针——函数指针

一、函数指针变量 1.1 函数指针变量的创建 什么是函数指针变量呢&#xff1f; 函数指针变量应该是用来存放函数地址的&#xff0c;未来通过地址能够调⽤函数的。 那么函数是否有地址呢&#xff1f; 我们做个测试&#xff1a; #include <stdio.h> void test() {print…

纽扣电池类产品上架亚马逊澳大利站认证标准要求AS/NZS 62368

纽扣电池一般来说常见的有充电的和不充电的两种&#xff0c; 充电的包括3.6V可充锂离子扣式电池(LIR系列)&#xff0c;3V可充锂离子扣式电池(ML或VL系列)&#xff1b;不充电的包括3V锂锰扣式电池(CR系列)及1.5V碱性锌锰扣式电池(LR及SR系列)。 澳大利亚*已经发布了经批准的《消…

重装系统后如何恢复以前的文件?详细教程大揭秘!

在日常生活中&#xff0c;我们可能会遇到各种计算机问题&#xff0c;其中最严重的问题之一就是需要重装系统。在重装系统之前&#xff0c;我们通常需要考虑一个问题&#xff1a;重装系统后还能恢复以前的文件吗&#xff1f; 首先&#xff0c;我们需要明确一点&#xff0c;重装…

为了摆脱 Android ,亚马逊开发基于Linux的操作系统

导读亚马逊一直在开发一种新的操作系统 —— 内部代号为 “Vega”&#xff0c;以便在 Fire TV、智能显示器和其他联网设备上取代 Android 系统。 亚马逊一直在开发一种新的操作系统 —— 内部代号为 “Vega”&#xff0c;以便在 Fire TV、智能显示器和其他联网设备上取代 Andr…

虹科干货丨TWAMP:什么是双向主动测量协议?

来源&#xff1a;虹科网络安全 虹科干货丨TWAMP&#xff1a;什么是双向主动测量协议&#xff1f; 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; 导语 TWAMP&#xff08;双向主动测量协议&#xff09;是什么&#xff1f;它在网络性能测量中有什么作用&#xff1f;如…

Java 多线程进阶

1 方法执行与进程执行 GetMapping("/demo1")public void demo1(){//方法调用new ThreadTest1("run1").run();//线程调用new ThreadTest1("run2").start();} 下断点调试信息&#xff0c;可以看到run()方法当前线程是“main1” 继续运行到run里面&…

练习六-使用Questasim来用verilog使用function函数

[TOC](使用Questasim来用verilog使用function函数 1&#xff0c;verilog中使用函数function2&#xff0c;RTL代码3&#xff0c;测试代码4&#xff0c;输出波形 1&#xff0c;verilog中使用函数function 目的&#xff1a; &#xff08;1&#xff09;了解函数的定义和在模块设计中…

问题解决:Ubuntu18.04下nvcc -V指令可用,/usr/local/下却没有cuda文件夹,原因分析及卸载方法

问题描述 今天要运行一个程序&#xff0c;需要CUDA版本高于10.0&#xff0c;我的电脑无法运行&#xff0c;于是开始检查 首先使用nvidia-smi与nvcc -V指令 能够看出来&#xff0c;当前显卡驱动适合的CUDA版本为12.1&#xff0c;而本机安装的版本是9.1.85&#xff0c;那么就需…