在做一些项目时需要用到很多的数据表,但是这些数据表又有相同的字段,每次调用方法都要给这些字段不断地重复复制很麻烦,怎么才能更加简单,自动填充这些公共字段呢?
比如下面这个数据表,这是员工的数据表。
@Data
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private String name;
private String password;
private String phone;
private String sex;
private String idNumber;
private Integer status;
private LocalDateTime createTime;
private LocalDateTime updateTime;
@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;
}
但是无论是员工表还是菜单表,每次使用都需要填充谁创建的,什么时候创建的,因此可以把这些公共字段摘取出来。
加上@TableField注解,后面进行指定是插入还是更新。
然后需要自定义元数据对象处理器:
@Component
@Slf4j
public class MyMetaObjecthandler implements MetaObjectHandler {
/**
* 插入操作,自动填充
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
log.info("公共字段自动填充[insert]...");
log.info(metaObject.toString());
metaObject.setValue("createTime", LocalDateTime.now());
metaObject.setValue("updateTime",LocalDateTime.now());
metaObject.setValue("createUser",BaseContext.getCurrentId());
metaObject.setValue("updateUser",BaseContext.getCurrentId());
}
/**
* 更新操作,自动填充
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
log.info("公共字段自动填充[update]...");
log.info(metaObject.toString());
long id = Thread.currentThread().getId();
log.info("线程id为:{}",id);
metaObject.setValue("updateTime",LocalDateTime.now());
metaObject.setValue("updateUser",BaseContext.getCurrentId());
}
}
为了获得创建者的ID,需要从session中获取,但是这个里面没有注入缓存,因此需要再创建【基于ThreadLocal封装工具类,用户保存和获取当前登录用户id】
/**
* 基于ThreadLocal封装工具类,用户保存和获取当前登录用户id
*/
public class BaseContext {
private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
/**
* 设置值
* @param id
*/
public static void setCurrentId(Long id){
threadLocal.set(id);
}
/**
* 获取值
* @return
*/
public static Long getCurrentId(){
return threadLocal.get();
}
}
这个ID需要从其它类里面获取,比如我的这个是从登录状态获取的:
//4-2、判断登录状态,如果已登录,则直接放行
if(request.getSession().getAttribute("user") != null){
log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("user"));
Long userId = (Long) request.getSession().getAttribute("user");
//注意下面这行代码,用前面创造的 ThreadLocal封装工具类 来获取ID
BaseContext.setCurrentId(userId);
filterChain.doFilter(request,response);
return;
}