问题背景
在Insert和Update中,存在一些用同样方法处理的字段(公共字段),而每次对公共字段进行相同的处理方式会显得代码臃肿。
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
employee.setCreateUser((Long) httpSession.getAttribute("employee"));
employee.setUpdateUser((Long) httpSession.getAttribute("employee"));
mybatis plus正好能解决对公共字段的自动填充
实现方法
1:在要进行自动填充的属性上加入@TableField注解
@TableField(fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-mm-dd HH:mm:ss")
@
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;
其中fill属性表示在哪个方法下进行自动填充,FieldFill.INSERT为插入语句,UPDATE为更新语句,INSERT_UPDATE为插入和更新语句。
区分一下@JsonFormat和@DateTimeFormat
@JsonFormat: pattern:与前端交换数据时,将数据在Json(前端)和Date(后端)类型中以约束的格式进行转换
timezone:设置时区,将自动把系统时间增减时区
@DateTimeFormat:将前端传入的String转换为Date时以约束的格式进行转换,但后端的数据为不会被该格式约束。若前端传回来的为Json格式,则需要用@RequestBody将Json转换为Date类型,此时需要Json的时间格式和DateTimeFormat所约束的格式相同
2:实现MetaObjectHandler
@Component
public class MetaObjectHandlerImpl implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
metaObject.setValue("createTime", LocalDateTime.now());
metaObject.setValue("updateTime", LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
metaObject.setValue("updateTime", LocalDateTime.now());
}
}
由于无法获得session,因此通过ThreadLocal对id进行临时的存储
3:ThreadLocal存储数据
使用条件
Threadlocal只能用在同一线程内。每一个请求为同一个线程,因此可以将用户id在过滤器中存储,并在MetaObjetHandlerImol中取出。
Threadlocal是以对象为key值,因此一次只能存储一个数据,使用时必须保障为同一个Threadlocal对象。
public class ThreadLocalId {
private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
public static void setId(Long id) {
threadLocal.set(id);
}
public static Long getId(){
return threadLocal.get();
}
}
使用static修饰能保证为同一个Threadlocal对象
Long employeeId = (Long) httpServletRequest.getSession().getAttribute("employee");
if (employeeId != null) {
ThreadLocalId.setId(employeeId);
filterChain.doFilter(servletRequest,servletResponse);
return;
}
并在过滤器中将id存入Threadlocal
@Component
public class MetaObjectHandlerImpl implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
metaObject.setValue("createTime", LocalDateTime.now());
metaObject.setValue("updateTime", LocalDateTime.now());
metaObject.setValue("createUser", ThreadLocalId.getId());
metaObject.setValue("updateUser", ThreadLocalId.getId());
}
@Override
public void updateFill(MetaObject metaObject) {
metaObject.setValue("updateTime", LocalDateTime.now());
metaObject.setValue("updateUser", ThreadLocalId.getId());
}
}
4:总结
1: @TableField标记需要自动填充的属性
2:实现MetaObjectHandler并实现insertFill和updateFill
3:可以通过Threadlocal在同一线程中存取数据