后端开发中的实体实现公共字段自动填充

1、利用MyMateObjectHandler继承MataObjectHandler重写insertFill和updateFill方法,使用自定义的规则对相应的字段进行填充

package cn.pickle.reggle.common;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 公共字段自动填充
 * @author Pickle
 * @version V1.0
 * @date 2022/10/13 9:03
 */
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
     * 执行插入操作时执行
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {

        metaObject.setValue("createTime", LocalDateTime.now());

        metaObject.setValue("updateTime", LocalDateTime.now());

        metaObject.setValue("createUser",BaseContext.getCurrentId());

        metaObject.setValue("updateUser",BaseContext.getCurrentId());
    }

    /**
     * 执行更新操作时执行
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {

        metaObject.setValue("createTime", LocalDateTime.now());

        metaObject.setValue("updateTime", LocalDateTime.now());

        metaObject.setValue("createUser",BaseContext.getCurrentId());

        metaObject.setValue("updateUser",BaseContext.getCurrentId());
    }
}

2、在需要自动填充的实体字段上加入@TableField注解

 @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    @TableField(fill = FieldFill.INSERT)
    private Long createUser;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateUser;

3、对修改对象进行填写和修改的时候,当前修改人的id存在session中,但是在MyMateObjectHandler中获取不到Session对象这就需要使用ThreadLocal来实现线程独立变量的保存,使得可以在持久化层也可以获取到当前操作人的id。

所以可以在LoginCheckFilter中将Session中的当前登陆用户的Id保存到TreadLocal中,再从MyMetaObjectHandler中需要的时候取出来,并且填入实体对象中。
这里设计一个ThreadLocal工具

package cn.pickle.reggle.common;

/**
 * 基于ThreadLocal封装工具类,用于获取和保存当前登陆的ID
 * 保存的值作用域是一个线程之内
 * 之所以使用BaseContext是因为要获取当前登录用户的id只能在session中获取,但是数据库持久化的时候是无法获取
 * session的,所以使用一个BaseContext将session中的用户的id传递到持久化层中,主要起到传递数据的作用
 * @author Pickle
 * @version V1.0
 * @date 2022/10/13 9:49
 */
/*
而 ThreadLocal 的生命周期是与线程的生命周期相关联的。每个线程拥有自己独立的 ThreadLocal 实例,这些实例存储在线程的 ThreadLocalMap 中。
当线程结束时,ThreadLocalMap 中的 ThreadLocal 实例会被垃圾回收,但 ThreadLocal 实例本身不会被立即回收,直到没有任何对它的引用时才会被回收。
因此,尽管在一个HTTP请求的处理过程中可能涉及多个线程(例如线程池中的多个线程处理不同阶段的任务),但 ThreadLocal 实例通常是在线程开始时创建,
在线程结束时被垃圾回收。因此,ThreadLocal 的生命周期通常比一个HTTP请求的生命周期更长。
 */
public class BaseContext {

    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    public static void setCurrentId(Long id){
        threadLocal.set(id);
    }

    public static Long getCurrentId(){
        return threadLocal.get();
    }

}

先在LoginCheckFilter中添加id信息

 BaseContext.setCurrentId((Long)request.getSession().getAttribute("employee"));

在MyMetaObjectHandler中这样使用

posted @ 2024-02-12 14:54  破忒头头  阅读(107)  评论(0)    收藏  举报