mybatis统一处理entity创建日期和更新日期,并对时间做偏差

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);
                }
            }
        }
    }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值