实现 公共字段主动填充【创建时间/创建人/修改id/修改id】
技术栈
实现思路
- 编写枚举,用于标识数据库操作类型
- 自定义注解AutoFill,用于标识须要进行公共字段主动填充的方法
- 将Mapper的方法名写成常量类,提高代码规范
- 自定义切面类AutoFillAspect,同一拦截加入了AutoFill注解的方法,通过反射为公共字段赋值
- 在Mapper的方法上加入AutoFill注解
代码实现
- 编写枚举,用于标识数据库操作类型
- 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());这些不再需要重复设置
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |