公共字段自动填充,你了解吗

公共字段自动填充

  • 什么是公共字段

  • 前面我们在新增员工是,需要设置创建时间,修改时间,修改人等
    而我们在编辑员工时也需要设置创建时间,修改时间,修改人等这些相同的操作    
    
  • 这些字段就属于公共字段


  • 为了解决每次都要重复进行这些操作,那有没有一种快捷高效的方法来简化我们的开发呢?

  • 答案是肯定的
    我们可以使用MybatisPlus提供的公共字段自动填充功能    
    

  • 那如何理解MybatisPlus公共字段自动填充呢?

  • MybatisPlus公共字段自动填充就是在插入或者修改操作时,为指定字段赋予指定的值
    
  • 优点

    • 统一对公共字段处理
    • 避免了重复的代码

  • 了解到上面的知识那么我们该具体如何实现呢?

  • 1.在实体类的属性上面假如@TableField,指定自动填充策略
    2.编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口    
    

  • 第一步代码演示
    @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;

  • 第二部代码演示
/**
 * 自定义元数据对象处理器
 */
@Component  //让Spring来处理
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
    /**
     * 插入操作自动填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("公共字段自动填充[insert]");
        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime",LocalDateTime.now());
        metaObject.setValue("createUser",1L);
        metaObject.setValue("updateUser",1L);
    }

    /**
     * 更新操作自动填充
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("公共字段自动填充[update]");
        metaObject.setValue("updateTime",LocalDateTime.now());
        metaObject.setValue("updateUser",1L);
    }
}

  • 不知道大家发现一个问题没?
  • 我这个设置的ID是设的固定的,这肯定是不对的
  • 大家想一想,我们之前是怎么获取ID的?
  • 是不是通过Request.getSession.getAttritube(“employee”)通过键或者id值的
  • 但是这里没有办法得到Request
  • 所以之前的那个方法在这是失效的

  • **那么我们又该怎么解决呢?**

  • ThreadLocal
        客服端每次发送http请求,对应的服务器端都会分配一个新的线程来处理
        某些类中的方法获取到的线程是同一个线程
    

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sjmbM42j-1654173413602)(C:\Users\Cx_330\AppData\Roaming\Typora\typora-user-images\image-20220602194453002.png)]


  • 为解决上面的问题,我们可以分三步走,这个基于我写的reggie项目演示

    1. 创建一个类 里面创建ThreadLocal 并写出get/set方法
    2. 因为在每次修改或者更新都会经过我的过滤器,所以通过过滤器可以先获取当前用户登录的id
    3. 然后到 updateFill()方法中再通过get方法获取id就可以设置了

    /**
     * 基于ThreadLocal构建工具类 用于保存和获取当前登录用户的id
     */
    public class BaseContext {
        private static ThreadLocal<Long> threadLocal= new ThreadLocal<Long>();
        public static void setCurrnetId(Long id){
            threadLocal.set(id);
        }
        public static Long getCurrentId(){
            return threadLocal.get();
        }
    }
    

            //如果需要处理 先判断登陆状态 如果已登陆 则放行
            if(request.getSession().getAttribute("employee")!=null){
    
                Long empid = (Long) request.getSession().getAttribute("employee");
                BaseContext.setCurrnetId(empid);
    
                filterChain.doFilter(request,response);
                return;
            }
    

    public void updateFill(MetaObject metaObject) {
        log.info("公共字段自动填充[update]");
        Long empId = BaseContext.getCurrentId();
        metaObject.setValue("updateTime",LocalDateTime.now());
        metaObject.setValue("updateUser",empId);
    }

你可能感兴趣的:(后端开发,java,java-ee,spring)