需求
使用 MyBatis 插入或修改某条记录时,能自动设置数据表里的 create_time 和 update_time 字段,即自动给实体类对象的 createTime 和 updateTime 属性赋值。(如果使用 MyBatis-Plus,该功能很容易实现,现在针对的场景是仅使用 MyBatis)
解决方案
使用AOP的原理,在执行新增或修改前,用反射获取方法的第一个参数,给它的 createTime 和 updateTime 属性赋值 。(约定:方法的第一个参数是要操作的实体类)
代码
1、自定义注解:
/**
* 标识 需要自动填充的方法
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
OperationType value();
}
2、枚举类:指定方法类型是 insert 还是 update,insert 操作需要 同时设置 createTime 和 updateTime,update操作只设置 updateTime 。
/**
* 操作类型
*/
public enum OperationType {
UPDATE,
INSERT
}
3、切面:
/**
* 自定义切面 自动填充公共字段
*/
@Aspect
@Component
public class AutoFillAspect {
/**
* 切入点
* * com.example.mapper.*.*(..) 需要能定位到mapper接口的位置
* com.example.autofill.AutoFill 是上面写的自定义注解的路径
*/
@Pointcut("execution(* com.example.mapper.*.*(..)) && @annotation(com.example.autofill.AutoFill)")
public void autoFillPointCut() {
}
/**
* 前置通知,insert update之前 填充时间
*/
@Before("autoFillPointCut()")
public void autoFill(JoinPoint joinPoint) throws Exception {
//获取到当前被拦截的方法上的数据库操作类型
MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法签名对象
AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象
OperationType operationType = autoFill.value();//获得数据库操作类型 insert update
// insert update 方法参数是实体类 需要放在第一个
// 获取实体参数对象
Object[] args = joinPoint.getArgs();
if (args == null || args.length == 0) {
return;
}
Object entity = args[0];
// 为 createTime 和 updateTime 属性赋值
LocalDateTime localDateTime = LocalDateTime.now();
if (operationType == OperationType.INSERT) {
// insert 操作 两个时间都赋值
Method setCreateTime = entity.getClass().getMethod(SET_CREATE_TIME, LocalDateTime.class);
Method setUpdateTime = entity.getClass().getMethod(SET_UPDATE_TIME, LocalDateTime.class);
setCreateTime.invoke(entity, localDateTime);
setUpdateTime.invoke(entity, localDateTime);
} else if (operationType == OperationType.UPDATE) {
// update 操作 只设置更新时间
Method setUpdateTime = entity.getClass().getMethod(SET_UPDATE_TIME, LocalDateTime.class);
setUpdateTime.invoke(entity, localDateTime);
}
}
}
测试案例
实体类:
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class User{
private Long id;
private String name;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
mapper接口:
/**
* 添加用户
*/
@AutoFill(value = OperationType.INSERT)
Integer addUser(User user);
xml文件:
<insert id="addUser" parameterType="user" useGeneratedKeys="true" keyProperty="id">
insert into user(name, create_time, update_time)
values (#{name}, #{createTime}, #{updateTime})
</insert>
测试方法:
@Resource
private UserMapper userMapper;
void test(){
User user = new User();
user.setName("张三"); // 无需手动设置 createTime 和 updateTime 属性
userMapper.addUser(user);
}
标签:insert,updateTime,update,entity,数据表,时间,LocalDateTime,MyBatis,createTime
From: https://www.cnblogs.com/codermario/p/18231284