在 Mybatis_Plus中可以通过对实体类属性添加@TableField(fill=FieldFill.INSERT)进行自动填充, 但在mybatis中通常需要自定义注解,然后通过切面拦截用反射的方式进行赋值

第一步: 创建自定义注解 AutoFill, 用于标识需要进行公共字段自动填充的方法

1
2
3
4
5
6
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
// 数据库操作类型: UPDATE INSERT
OperationType value();
}

第二步: 自定义切面类 AutoFillAspect, 统一拦截加入了 AutoFill注解的方法, 通过反射为公共字段赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
@Aspect
@Component
@Slf4j
public class AutoFillAspect {

/**
* 切入点 设置拦截的类及方法路径 拦截的注解
*/
@Pointcut("execution(* com.work.mapper.*.*(..)) && @annotation(com.work.annotation.AutoFill)")
public void autoFillPointCut() {}

/**
* 前置通知. 在通知中进行公共字段的赋值
*/
@Before("autoFillPointCut()")
public void autoFill(JoinPoint joinPoint) {
log.info("开始进行公共字段的填充");

// 获取到当前被拦截的方法上的数据库操作类型
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名对象 通过向下转型
AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class); // 获得方法的注解对象
OperationType operationType = autoFill.value(); // 获取数据库操作类型 INSERT UPDATE

//获取到当前被拦截的方法的参数-实体对象
Object[] args = joinPoint.getArgs();
if (args == null || args.length == 0){
return;
}
Object entity = args[0];

//准备赋值的数据
LocalDateTime now = LocalDateTime.now();
Long currentId = BaseContext.getCurrentId();

//过呢据当前不同的操作类型,为对应的属性通过反射来赋值
if (operationType == OperationType.INSERT){
try {
// 为4个公共字段赋值
// 用反射进行赋值
entity.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class).invoke(entity, now);
entity.getClass().getDeclaredMethod("setCreateUser", Long.class).invoke(entity,currentId);
entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class).invoke(entity, now);
entity.getClass().getDeclaredMethod("setUpdateUser", Long.class).invoke(entity,currentId);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}

}else if(operationType == OperationType.UPDATE){
try {
// 为2个公共字段赋值
// 使用反射进行赋值
entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class).invoke(entity, now);
entity.getClass().getDeclaredMethod("setUpdateUser", Long.class).invoke(entity,currentId);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}

}

第三步: 在 Mapper对应的方法上加入 AutoFill注解

1
2
@AutoFill(OperationType.UPDATE)
void update(Employee employee);

到此为止公共字段自动填充完成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Component
@ConfigurationProperties(prefix = "sky.jwt")
@Data
public class JwtProperties {

/**
* 管理端员工生成jwt令牌相关配置
*/
private String adminSecretKey;
private long adminTtl;
private String adminTokenName;

/**
* 用户端微信用户生成jwt令牌相关配置
*/
private String userSecretKey;
private long userTtl;
private String userTokenName;

}