公共字段自动填充功能实现【springboot】

问题分析

很多业务表里面有相同的公共字段,导致每次插入都要写相同的代码,代码冗余,不便于后期维护

公共字段填充是解决​​重复性字段统一管理​​问题的技术方案,主要用于自动处理实体类中那些在多处重复出现且赋值逻辑相同的字段(如创建时间、创建人、更新时间等)。

解决思路

代码实现

1,自定义注解

指定添加注解的地方

2,自定义切面类。切面=切入点+通知

定义切入点,确定切入点位置

定义通知,确定通知类型,通知要执行的操作

3,先给需要自动装配的方法加上注解,测试一下,再写通知操作

通知要执行的操作

1,获取方法对数据库操作类型,确定要填充的字段

  • 利用方法签名对象和反射获取注解对象

2,获取当前拦截的方法的参数(实体对象)

  • 判断防止出现空指针,接收对象用object最好

3,准备要赋值的数据

  • 利用ThreadLocal和其他工具类

4,根据不同的数据库操作类型,利用反射进行赋值

  • 利用反射获取需要装配的字段的set方法。
  • 利用invoke方法进行赋值。invoke()反射核心方法,第一个参数是调用对象实例,后续是方法参数。
java 复制代码
//指定注解只能加在方法上
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
    //数据库操作类型;update insert
    //指定当前数据库操作类型是更新还是插入,只有在插入或者更新的时候才需要自动填充功能
    OperationType value();
}
java 复制代码
@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];
        //准备赋值的数据
        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();
        //根据不同的操作类型,为对应的属性赋值
        if (operationType == OperationType.INSERT) {
            //为四个公共字段赋值
            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) {
                throw new RuntimeException(e);
            }


        } else if (operationType == OperationType.UPDATE) {
            //为两个公共字段赋值
            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) {
                throw new RuntimeException(e);
            }

        }
    }
}
相关推荐
Codeking__2 分钟前
Redis——value的数据类型与单线程工作模型
java·数据库·redis
rchmin3 分钟前
MySQL主从复制原理详解
数据库·mysql
液态不合群23 分钟前
Java中线程安全问题的原因和解决方案
java·数据库
程序员柒叔25 分钟前
Dify 集成-数据库与缓存
数据库·缓存·dify
栗子叶25 分钟前
深入理解 MySQL 半同步复制:AFTER_SYNC 为何能避免主从同步数据丢失?
数据库·mysql·adb·高可用·主从同步
我科绝伦(Huanhuan Zhou)40 分钟前
MySQL主主复制管理器(MMM):技术原理与实践架构解析
数据库·mysql·架构
步步为营DotNet1 小时前
深度解析.NET 中IAsyncEnumerable:异步迭代的高效实现与应用】
服务器·数据库·.net
mpHH1 小时前
postgresql 执行器中readme的翻译
数据库·学习·postgresql
萧曵 丶1 小时前
覆盖索引与回表(MySQL 索引核心概念,性能优化关键)
数据库·mysql·性能优化·索引·聚簇索引