entity表的创建日期和更新日期与业务无关,但又被高频次的用来查询和清洗数据,因此最好有一个地方统一设置值,不在业务中进行设置,此处用mybatis的拦截器和自定义注解来实现。
自定义一个注解CurrentTime,默认是创建时间, 设置值为SqlCommandType.UPDATE则表示更新时间
/**
* 自动设置当前时间
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface CurrentTime {
SqlCommandType value() default SqlCommandType.INSERT;
}
entity类的字段设置
//创建时间.
@CurrentTime
private Date createDate;
//最后修改时间.
@CurrentTime(SqlCommandType.UPDATE)
private Date lastModifyDate;
拦截器实现统一处理(批量处理时,对时间进行了10毫秒的偏差,避免同一批次的时间一致)
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import pengesoft.property.core.annotation.CurrentTime;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
import java.util.Properties;
/**
* mybatis统一处理entity创建日期和更新日期
*
* @Author
* @Date 2023/2/16 13:13
* @Description
*/
@Intercepts({@Signature(
type = Executor.class,
method = "update",
args = {MappedStatement.class, Object.class}
)})
public class MybatisDateTimeInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement) args[0];
//获取 SQL 命令
SqlCommandType sqlCommandType = ms.getSqlCommandType();
//只判断新增和修改
if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {
//获取参数
Object parameter = invocation.getArgs()[1];
//批量操作时
if (parameter instanceof MapperMethod.ParamMap) {
MapperMethod.ParamMap map = (MapperMethod.ParamMap) parameter;
Object obj = map.get("list");
List<?> list = (List<?>) obj;
if (list != null) {
LocalDateTime dealTime = LocalDateTime.now();
for (Object o : list) {
setParameter(o, Date.from((dealTime = dealTime.plus(10, ChronoUnit.MILLIS)).atZone(ZoneId.systemDefault()).toInstant()), sqlCommandType);
}
}
} else {
setParameter(parameter, Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()), sqlCommandType);
}
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
public void setParameter(Object parameter, Date dealTime, SqlCommandType sqlCommandType) throws Throwable {
Class<?> aClass = parameter.getClass();
// 获取私有成员变量
Field[] declaredFields = aClass.getDeclaredFields();
for (Field field : declaredFields) {
if (field.getAnnotation(CurrentTime.class) != null) {
CurrentTime annotation = field.getAnnotation(CurrentTime.class);
if (sqlCommandType.equals(annotation.value())) {
field.setAccessible(true);
field.set(parameter, dealTime);
}
}
}
}