实现 公共字段自动填充【创建时间/创建人/修改id/修改id】
cnblogs 2024-08-23 15:39:05 阅读 89
实现 公共字段自动填充【创建时间/创建人/修改id/修改id】
技术栈
- <li>枚举
- 自定义注解
- AOP
- 反射
实现思路
- 编写枚举,用于标识数据库操作类型
- 自定义注解AutoFill,用于标识需要进行公共字段自动填充的方法
- 将Mapper的方法名写成常量类,提高代码规范
- 自定义切面类AutoFillAspect,统一拦截加入了AutoFill注解的方法,通过反射为公共字段赋值
- 在Mapper的方法上加入AutoFill注解
代码实现
编写枚举,用于标识数据库操作类型
<code>public enum OperationType {
//更新操作
UPDATE,
//插入操作
INSERT
}
自定义注解AutoFill,用于标识需要进行公共字段自动填充的方法
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
//数据库操作类型
OperationType value();
}
将Mapper的方法名写成常量类,提高代码规范
//公共字段自动填充相关常量
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";
}
自定义切面类AutoFillAspect
/**
* 自定义切面,实现公共字段自动填充
*/
@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){
log.info("开始进行公共字段自动填充...");
//获取到当前被拦截的方法上的数据库操作类型
MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法签名对象
AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象
OperationType operationType = autoFill.value();//获得数据库操作类型
//获取到被拦截的方法形参参数【实体对象】
Object[] args = joinPoint.getArgs();
//约定:如果需要实现自动填充功能 ,需要把实体参数 放在形参第一个参数
if (args == null || args.length == 0){
return;//防止空指针
}
Object entity = args[0];//拿到实体对象
//准备数据 实体对象的公共属性【时间和登录id】
LocalDateTime now = LocalDateTime.now();
Long currentId = BaseContext.getCurrentId();
//根据当前不同的操作类型 为对应的属性赋值【反射】
if (operationType == OperationType.INSERT){
//为4个公共字段赋值
try {
Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);//这里就是常量类,规范代码
Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
//通过反射为对象属性赋值
setCreateTime.invoke(entity,now);
setCreateUser.invoke(entity,currentId);
setUpdateTime.invoke(entity,now);
setUpdateUser.invoke(entity,currentId);
} catch (Exception e) {
e.printStackTrace();
}
}else if (operationType == OperationType.UPDATE){
//为2个公共字段赋值
try {
Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
//通过反射为对象属性赋值
setUpdateTime.invoke(entity,now);
setUpdateUser.invoke(entity,currentId);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
在Mapper的方法上加入AutoFill注解
@AutoFill(value = OperationType.INSERT)
@Insert("insert into category(type, name, sort, status, create_time, update_time, create_user, update_user)" +
" VALUES" +
" (#{type}, #{name}, #{sort}, #{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})")
void insert(Category category);
实现了表格公共字段自动填充后,在service层编写插入或者修改实体的时候就不需要重复设置 修改时间、修改id等
//设置修改时间、修改人
// category.setUpdateTime(LocalDateTime.now());
// category.setUpdateUser(BaseContext.getCurrentId());这些不再需要重复设置
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。