目录
- 问题背景
- 实现方式
- 1. MetaObjectHandler实现类创建
- 2. 实体类中公共字段添加注解
问题背景
在增加或修改记录时,常常需要对一些公共字段进行设置,如创建时间(createTime)、创建人(createUser)、修改时间(updateTime)、修改人(updateUser),这些信息一般不来自于网页请求。实际项目中可能有很多种Entity(实体类),对每一个Entity对应的业务代码中都要写这些针对公共字段的操作,造成了代码的大量重复。
因此,可以创建一个用于公共字段自动填充的类,使得公共字段实现自动填充。
实现方式
主要分为两大部分:
- 1. MetaObjectHandler实现类创建
- 2. 实体类中公共字段添加注解
1. MetaObjectHandler实现类创建
首先,建立一个MetaObjectHandler接口的实现类(MetaObjectHandler是MyBATisPlus提供的接口)
@Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler {
之后,重写相关方法 (insertFill(MetaObject metaObject) 和 updateFill(MetaObject metaObject) )
@Override public void insertFill(MetaObject metaObject) { log.info("公共字段自动填充[insert]..."); log.info("线程id:{}", Thread.currentThread().getId()); metaObject.setValue("createTime", LocalDateTime.now()); metaObject.setValue("updateTime", LocalDateTime.now()); metaObject.setValue("createUser", threadLocal.get()); // 动态填充 填充当前登录的用户的 ID metaObject.setValue("updateUser", threadLocal.get()); // 动态填充 填充当前登录的用户的 ID } @Override public void updawww.devze.comteFill(MetaObject metaObject) { log.info("公共字段自动填充[update]..."); log.info("线程id:{}", Thread.currentThread().getId()); metaObject.setValue("updateTime", LocalDateTime.now()); metaObject.setValue("updateUser", threadLocal.get()); }
注意:在对createUser和updateUser进行设置时(通常是设置id),无法拿到session,因此不能通过session的方式获取id。这里使用的是ThreadLocal。
需要知道的是,页面向服务器发送的每一个请求,在服务器端都会有一个独立的线程根据该请求进行一系列操作。例如,页面发来一个修改用户的请求,到了服务器端,拦截器的preHandle方法、controller层的update方法,以及公共字段填充类的updateFill方法都是由同一个线程执行的。
因此,可以在拦截器执行preHandle方法时,将session中的id数据保存到ThreadLocal对象中,在进行公共编程客栈字段填充时,再将id从ThreadLocal对象中取出即可。
我将ThreadLocal配置成了一个Bean来管理(也可以用一个工具类来封装ThreadLocal,定义一个类变量)
ThreadLocal的Bean配置:
@Configuration public class ThreadLocalConfig { @Bean public ThreadLocal<Long> threadLocal(){ ThreadLocal<Long> threadLocal = new ThreadLocal<>(); return threadLocal; } }
拦截器注入ThreadLocal,并将id存入ThreadLocal:
public class MyInterceptor implements HandlerInterceptor { @Autowired ThreadLocal<Long> threadLocal; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("线程id:{}", Thread.currentThread().getId()); threadLocal.set((Long) rehttp://www.devze.comquest.getSession().getAttribute("employeeId")); ... 对session进行判断的代码 ... } }
之后,在MetaObjectHandler实现类中也对ThreadLocal的Bean进行注入
2. 实体类中公共字段添加注解
@TableField(fill = FieldFill.INSERjsT) // 插入时填充字段 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;
如此,便实现了公共字段的自动填充
到此这篇关于SpringBoot基于MyBatisPlus实现公共字段自动填充的文章就介绍到这了,更多相关SpringBoot MyBatisPlus公共字段自动填充内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.cppcjavascriptns.com)!
精彩评论