实现 公共字段主动填充【创建时间/创建人/修改id/修改id】 ...

打印 上一主题 下一主题

主题 900|帖子 900|积分 2700

实现 公共字段主动填充【创建时间/创建人/修改id/修改id】

技术栈


  • 枚举
  • 自定义注解
  • AOP
  • 反射
实现思路


  • 编写枚举,用于标识数据库操作类型
  • 自定义注解AutoFill,用于标识须要进行公共字段主动填充的方法
  • 将Mapper的方法名写成常量类,提高代码规范
  • 自定义切面类AutoFillAspect,同一拦截加入了AutoFill注解的方法,通过反射为公共字段赋值
  • 在Mapper的方法上加入AutoFill注解
代码实现


  • 编写枚举,用于标识数据库操作类型
    1. public enum OperationType {
    2.     //更新操作
    3.     UPDATE,
    4.     //插入操作
    5.     INSERT
    6. }
    复制代码
  • 自定义注解AutoFill,用于标识须要进行公共字段主动填充的方法
    1. @Target(ElementType.METHOD)
    2. @Retention(RetentionPolicy.RUNTIME)
    3. public @interface AutoFill {
    4.     //数据库操作类型
    5.     OperationType value();
    6. }
    复制代码
  • 将Mapper的方法名写成常量类,提高代码规范
    1. //公共字段自动填充相关常量
    2. public class AutoFillConstant {
    3.     //实体类中的方法名称
    4.     public static final String SET_CREATE_TIME = "setCreateTime";
    5.     public static final String SET_UPDATE_TIME = "setUpdateTime";
    6.     public static final String SET_CREATE_USER = "setCreateUser";
    7.     public static final String SET_UPDATE_USER = "setUpdateUser";
    8. }
    复制代码
  • 自定义切面类AutoFillAspect
    1. /**
    2. * 自定义切面,实现公共字段自动填充
    3. */
    4. @Aspect
    5. @Component
    6. @Slf4j
    7. public class AutoFillAspect {
    8.     /**
    9.      * 切入点
    10.      */
    11.     @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    12.     public void autoFillPointCut(){}
    13.     /**
    14.      * 前置通知,在通知中进行公共字段的赋值
    15.      */
    16.     @Before("autoFillPointCut()")
    17.     public void autoFill(JoinPoint joinPoint){
    18.         log.info("开始进行公共字段自动填充...");
    19.         //获取到当前被拦截的方法上的数据库操作类型
    20.         MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法签名对象
    21.         AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象
    22.         OperationType operationType = autoFill.value();//获得数据库操作类型
    23.         //获取到被拦截的方法形参参数【实体对象】
    24.         Object[] args = joinPoint.getArgs();
    25.         //约定:如果需要实现自动填充功能 ,需要把实体参数 放在形参第一个参数
    26.         if (args == null || args.length == 0){
    27.             return;//防止空指针
    28.         }
    29.         Object entity = args[0];//拿到实体对象
    30.         //准备数据 实体对象的公共属性【时间和登录id】
    31.         LocalDateTime now = LocalDateTime.now();
    32.         Long currentId = BaseContext.getCurrentId();
    33.         //根据当前不同的操作类型 为对应的属性赋值【反射】
    34.         if (operationType == OperationType.INSERT){
    35.             //为4个公共字段赋值
    36.             try {
    37.                 Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);//这里就是常量类,规范代码
    38.                 Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
    39.                 Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
    40.                 Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
    41.                 //通过反射为对象属性赋值
    42.                 setCreateTime.invoke(entity,now);
    43.                 setCreateUser.invoke(entity,currentId);
    44.                 setUpdateTime.invoke(entity,now);
    45.                 setUpdateUser.invoke(entity,currentId);
    46.             } catch (Exception e) {
    47.                e.printStackTrace();
    48.             }
    49.         }else if (operationType == OperationType.UPDATE){
    50.             //为2个公共字段赋值
    51.             try {
    52.                 Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
    53.                 Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
    54.                 //通过反射为对象属性赋值
    55.                 setUpdateTime.invoke(entity,now);
    56.                 setUpdateUser.invoke(entity,currentId);
    57.             } catch (Exception e) {
    58.                 e.printStackTrace();
    59.             }
    60.         }
    61.     }
    62. }
    复制代码
  • 在Mapper的方法上加入AutoFill注解
    1. @AutoFill(value = OperationType.INSERT)
    2.     @Insert("insert into category(type, name, sort, status, create_time, update_time, create_user, update_user)" +
    3.             " VALUES" +
    4.             " (#{type}, #{name}, #{sort}, #{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})")
    5.     void insert(Category category);
    复制代码
实现了表格公共字段主动填充后,在service层编写插入大概修改实体的时间就不须要重复设置 修改时间、修改id等
  1.   //设置修改时间、修改人
  2. //        category.setUpdateTime(LocalDateTime.now());
  3. //        category.setUpdateUser(BaseContext.getCurrentId());这些不再需要重复设置
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

络腮胡菲菲

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表