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


    TheadLocal

    客户端发送的每次http请求,在服务端都会分配新的线程。因此登录检查过滤器、controller、元数据对象处理器属于一个线程。

    TheadLocal是线程的局部变量:

    TheadLocal常用方法:

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

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

    代码实现:

    第一步,实体类注解:

       

    1. @TableField(fill = FieldFill.INSERT) //插入时填充字段
    2. private LocalDateTime createTime;
    3. @TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时填充字段
    4. private LocalDateTime updateTime;
    5. @TableField(fill = FieldFill.INSERT) //插入时填充字段
    6. private Long createUser;
    7. @TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时填充字段
    8. private Long updateUser;

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

    在common包下:

    1. /**
    2. * 基于ThreadLocal封装工具类,用户保存和获取当前登录用户id
    3. */
    4. public class BaseContext {
    5. private static ThreadLocal threadLocal = new ThreadLocal<>();
    6. /**
    7. * 设置值
    8. * @param id
    9. */
    10. public static void setCurrentId(Long id){
    11. threadLocal.set(id);
    12. }
    13. /**
    14. * 获取值
    15. * @return
    16. */
    17. public static Long getCurrentId(){
    18. return threadLocal.get();
    19. }
    20. }

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

     

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

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

    在common包下:

    1. /**
    2. * 自定义元数据对象处理器
    3. */
    4. @Component
    5. @Slf4j
    6. public class MyMetaObjectHandler implements MetaObjectHandler {
    7. /**
    8. * 插入操作,自动填充
    9. * @param metaObject
    10. */
    11. @Override
    12. public void insertFill(MetaObject metaObject) {
    13. log.info("公共字段自动填充[insert]...");
    14. log.info(metaObject.toString());
    15. //第一个参数属性名,第二个参数自动填充的值
    16. metaObject.setValue("createTime", LocalDateTime.now());
    17. metaObject.setValue("updateTime",LocalDateTime.now());
    18. metaObject.setValue("createUser",BaseContext.getCurrentId());
    19. metaObject.setValue("updateUser",BaseContext.getCurrentId());
    20. }
    21. /**
    22. * 更新操作,自动填充
    23. * @param metaObject
    24. */
    25. @Override
    26. public void updateFill(MetaObject metaObject) {
    27. log.info("公共字段自动填充[update]...");
    28. log.info(metaObject.toString());
    29. long id = Thread.currentThread().getId();
    30. log.info("线程id为:{}",id);
    31. metaObject.setValue("updateTime",LocalDateTime.now());
    32. metaObject.setValue("updateUser",BaseContext.getCurrentId());
    33. }
    34. }

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

  • 相关阅读:
    如何不替换驱动jar包解决旧版本mysql驱动引起的No columns to generate for ClassWriter问题
    复现文件上传四次绕过
    si9000 单端(线)&差分(动)线板层结构与阻抗计算
    《向量数据库指南》——Milvus Cloud向量数据库的优势
    idea创建springboot项+集成阿里连接池druid
    NPU架构与算力分析
    虚拟Mic Android 8.1 方案
    查找和排序算法
    python 重定向控制台stdout与stderr到loguru
    应用层协议——DNS、DHCP、HTTP、FTP
  • 原文地址:https://blog.csdn.net/qq_64948664/article/details/134489278