MP 公共字段填充
MybatisPlus
公共字段填充
统一为公共字段进行处理,在插入或更新时为指定字段赋予指定的值,减少了重复代码。公共字段一般为创建/更新时间,创建/更新人。可以通过LocalDateTime.now()
来对创建/更新时间进行赋值,而创建/更新人可以通过 ThreadLocal 来赋值。ThreadLocal 是 JDK 中提供的一个类。
实现步骤:
- 实体类属性加入
@TableFiled
注解,指定自动填充策略 - 框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,该类需要实现
MetaObjectHandler接口
。
@Data public class Employee implements Serializable { private static final long serialVersionUID = 1L; @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; } @Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { log.info("元数据处理[insert]"); metaObject.setValue("createTime", LocalDateTime.now()); metaObject.setValue("updateTime", LocalDateTime.now()); metaObject.setValue("createUser", new Long("1L")); metaObject.setValue("updateUser", new Long("1L")); } @Override public void updateFill(MetaObject metaObject) { log.info("元数据处理[update]"); long id = Thread.currentThread().getId(); log.info("元数据处理的线程id:{}", id); metaObject.setValue("updateTime", LocalDateTime.now()); metaObject.setValue("updateUser", new Long("1L")); } }
如何获取用户id?
MyMetaObjectHandle
'类中是不能获得HttpSession
对象,因此不能在MyMetaObjectHandler
通过HttpSession
来获取用户id
。可以通过ThreadLocal
类来获取用户id
。
什么是ThreadLocal?
- ThreadLocal 类用来提供线程内部的局部变量,不同的线程之间的局部变量不会相互干扰
- 在多线程环境下访问(通过 get 和 set 方法访问)时能保证各个线程的变量相对独立于其他线程内的变量 ThreadLocal 为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。
常用方法 | 作用 |
---|---|
public T get() | 获取当前线程绑定的局部变量 |
public void set( T value) | 设置当前线程绑定的局部变量 |
为什么可以使用ThreadLocal?
客户端每次发送请求
,对应的服务端都会分配一个新的线程
来处理。同一个请求响应链中涉及的方法都属于同一个线程。可以在调用链中使用如下方法来确认此事:
long id = Thread.currendThread().getId; log.info("线程id:{}",id);
设置公共字段填充中的用户id字段
将设置 id,获取 id 的方法封装为一个工具类
public class UserIdContext { private static ThreadLocal<Long> threadLocal = new ThreadLocal<>(); /** * 为当前线程设置id * @param id */ public static void setCurrentId(Long id){ threadLocal.set(id); } /** * 获取当前线程中的id * @return */ public static Long getCurrentId(){ return threadLocal.get(); } }
通过 ThreadLocal 的 set 方法设置当前线程的线程局部变量的值,在元数据对象处理类中的方法调用 Thread 的 get 方法来获取当前线程所对应的线程局部变量的值。
@Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { log.info("元数据处理[insert]"); metaObject.setValue("createTime", LocalDateTime.now()); metaObject.setValue("updateTime", LocalDateTime.now()); metaObject.setValue("createUser", UserIdContext.getCurrentId()); metaObject.setValue("updateUser", UserIdContext.getCurrentId()); } @Override public void updateFill(MetaObject metaObject) { log.info("元数据处理[update]"); long id = Thread.currentThread().getId(); log.info("元数据处理的线程id:{}", id); metaObject.setValue("updateTime", LocalDateTime.now()); metaObject.setValue("updateUser", UserIdContext.getCurrentId()); } }
问:户登录成功后我们将用户 id 存入了 HttpSession 中,MyMetaObjectHandler 类中是不能获得 HttpSession 对象,为什么?
本文作者:九落
本文链接:https://www.cnblogs.com/9fall/p/17055737.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步