公共字段自动填充-@TableField的fill实现(2)

TheadLocal

公共字段自动填充-@TableField的fill实现(2)_第1张图片客户端发送的每次http请求,在服务端都会分配新的线程。因此登录检查过滤器、controller、元数据对象处理器属于一个线程。

TheadLocal是线程的局部变量:

TheadLocal常用方法:

如何在元数据对象处理器中获取当前登录用户的id?

因为登录检查过滤器、controller、元数据对象处理器属于一个线程,所以可以在filter中获取登录用户的id,set到ThreadLocal中,在元数据处理器中get到线程局部变量ThreadLocal的值。

代码实现:

第一步,实体类注解:

   

    @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;

第二步,封装基于ThreadLocal的工具类

在common包下:

/**
 * 基于ThreadLocal封装工具类,用户保存和获取当前登录用户id
 */
public class BaseContext {
    private static ThreadLocal threadLocal = new ThreadLocal<>();
 
    /**
     * 设置值
     * @param id
     */
    public static void setCurrentId(Long id){
        threadLocal.set(id);
    }
 
    /**
     * 获取值
     * @return
     */
    public static Long getCurrentId(){
        return threadLocal.get();
    }
}

第三步,登录检查过滤器把id加到ThreadLocal

 

        //4、判断登录状态,如果已登录,则直接放行
        if(request.getSession().getAttribute("employee") != null){
            log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));
            //这里要强转,虽然request.getSession().getAttribute("employee")类型确实是Long
            Long empId = (Long) request.getSession().getAttribute("employee");
            BaseContext.setCurrentId(empId);
 
            filterChain.doFilter(request,response);
            return;
        }

第四步,自定义元数据对象处理器,获取ThreadLocal的id

在common包下:

/**
 * 自定义元数据对象处理器
 */
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
    /**
     * 插入操作,自动填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("公共字段自动填充[insert]...");
        log.info(metaObject.toString());
        //第一个参数属性名,第二个参数自动填充的值
        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) {
        log.info("公共字段自动填充[update]...");
        log.info(metaObject.toString());
 
        long id = Thread.currentThread().getId();
        log.info("线程id为:{}",id);
 
        metaObject.setValue("updateTime",LocalDateTime.now());
        metaObject.setValue("updateUser",BaseContext.getCurrentId());
    }
}

第五步,删除之前写的创建、更新时间等相关代码,让其自动填充

你可能感兴趣的:(项目2(外卖),java,开发语言)