在数据库中有些字段是所有表都有的,可以交给MyBatisPlus来自动填充,而不用每次都自己手动填充。
如实体类中的创建时间,修改时间,创建用户,修改用户等
在需要自动填充的字段上添加@TableField注解,如下所示
@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
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", 1);
metaObject.setValue("updateUser", 1);
}
/**
* 更新操作,自动填充
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
log.info("公共字段自动填充[update]...");
metaObject.setValue("updateTime", LocalDateTime.now());
metaObject.setValue("updateUser", 1);
}
}
但有些填充字段,需要获取当前用户信息,如创建用户的id和修改用户的id,我们无法获取。
我们需要知道,每次前端向后端发送的请求都会创建一个线程进行处理,处理这个请求的都是同一个线程,如SpringMVC的过滤器、controller、service等层以及上面的MyMetaObjectHandler 都是同一个线程,因此我们可以把用户数据存储到ThreadLocal当中,这样MyMetaObjectHandler 就可以得到用户数据。
我们首先把ThreadLocal包装一下
/**
* 基于ThreadLocal封装工具类,用户保存和获取当前登录用户id
*/
public class BaseContext {
private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
public static void setCurrentId(Long id){
threadLocal.set(id);
}
public static Long getCurrentId(){
return threadLocal.get();
}
}
然后在过滤器中将session中的用户数据存到ThreadLocal中
//判断登录状态,如果已登录则直接放行
if (request.getSession().getAttribute("employee") != null) {
log.info("用户已登录,用户id:{}",request.getSession().getAttribute("employee"));
Long empId = (Long) request.getSession().getAttribute("employee");//获取用户id
BaseContext.setCurrentId(empId);//将用户id存到ThreadLocal中
filterChain.doFilter(request, response);
return;
}
在元数据处理器中取出ThreadLocal中的数据
```java
@Component
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", BaseContext.getCurrentId());//从ThreadLocal中取出数据,实现自动填充
metaObject.setValue("updateUser", BaseContext.getCurrentId());
}
/**
* 更新操作,自动填充
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
log.info("公共字段自动填充[update]...");
metaObject.setValue("updateTime", LocalDateTime.now());
metaObject.setValue("updateUser", BaseContext.getCurrentId());
}
}