使用AOP操作数据库,填充公共字段(创建人、修改人、创建时间、修改时间)代码
1、首先导入依赖
<!--spring-事务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、自定义接口
@Target(ElementType.METHOD)//该注解作用在方法上
@Retention(RetentionPolicy.RUNTIME)//注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
public @interface AutoFill {
//数据库的操作类型:UPDATE INSERT
OperationType value();
}
3、公共字段相关常量
/**
* 公共字段自动填充相关常量
*/
public class AutoFillConstant {
/**
* 实体类中的方法名称
*/
public static final String SET_CREATE_TIME = "setCreateTime";
public static final String SET_UPDATE_TIME = "setUpdateTime";
public static final String SET_CREATE_USER = "setCreateUser";
public static final String SET_UPDATE_USER = "setUpdateUser";
public static final String SET_ID = "setId";
//微信服务接口地址
public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";
}
4、threadlocal用来获取当前操作人的id
/**
* ThreadLocal
*/
public class BaseContext {
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
public static void setCurrentId(Long id) {
threadLocal.set(id);
}
public static Long getCurrentId() {
return threadLocal.get();
}
public static void removeCurrentId() {
threadLocal.remove();
}
}
5、数据库操作类型枚举类
/**
* 数据库操作类型
*/
public enum OperationType {
/**
* 更新操作
*/
UPDATE,
/**
* 插入操作
*/
INSERT
}
6、自定义切面
/**
* 自定义切面(自动填充表格创建人、修改人、创建时间、修改时间)
*
* @Author 奕生呀♥
* @Date 2023/3/13 17:00
* @Description: 自定义切面(
*/
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
/**
* 切入点
*/
@Pointcut("execution(* com.sky.mapper.*.*(..))&&@annotation(com.sky.annotation.AutoFill)")
public void autoFillPointCut() {
}
@Before("autoFillPointCut()")
public void autoFill(JoinPoint joinPoint) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException, InstantiationException {
//1、获取切入点的方法的参数(Employee的对象)
Object[] args = joinPoint.getArgs();
Object arg = args[0];
//2、获取方法的签名
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//3、利用反射获取方法上的注解
AutoFill annotation = signature.getMethod().getAnnotation(AutoFill.class);
//4、获取数据库操作类型
OperationType operationType = annotation.value();
//5、获取要填充字段的值
LocalDateTime now = LocalDateTime.now();
Long currentId = BaseContext.getCurrentId();
Long snowId = IdUtil.getSnowflake().nextId();
//6、判断操作类型:如果是插入操作,插入操作更新四个字段
//6-1获取操作方法
if (operationType == OperationType.INSERT) {
Method setCreateTime = arg.getClass().getMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
Method setUpdateTime = arg.getClass().getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
Method setCreateUser = arg.getClass().getMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
Method setUpdateUser = arg.getClass().getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
//6-2给对象赋值
setCreateTime.invoke(arg, now);
setUpdateTime.invoke(arg, now);
setCreateUser.invoke(arg, currentId);
setUpdateUser.invoke(arg, currentId);
//6-3、暴力获取id值
Field idField = arg.getClass().getDeclaredField("id");
idField.setAccessible(true);
Long id = (Long) idField.get(arg);
//6-4、如果没有获取到id的值,则填充
if (id==null){
idField.set(arg,snowId);
}
} else if (operationType == OperationType.UPDATE) {
Method setUpdateTime = arg.getClass().getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
Method setUpdateUser = arg.getClass().getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
setUpdateTime.invoke(arg, now);
setUpdateUser.invoke(arg, currentId);
}
}
}