一.公共字段自动填充
1.问题分析
业务表中有公共字段,create_time,create_user,update_time,update_user:

设置员工表中和菜品表中的这些字段需要大量的set方法,代码冗余,不便于后期维护。


2.实现思路
当修改create_time和create_user这两个字段是对应的Mapper层执行的操作类型是insert;
当修改update_time和update_user这两个字段是时对应的Mapper层执行的操作类型是insert或者是update。
这四个字段的操作时机是不一样的,我们目前明确了操作类型,对于这些公共的字段,我们的设计思路是统一来处理。即AOP,使用切面这种方式处理。假设我们需要执行对Mapper层的插入一条数据,那我们可以使用切面拦截这种操作,对所需要的公共字段进行赋值。但是我们不需要对持久层的所有方法都进行拦截和处理,比如查询和删除的方法就不需要。
所以我们需要一个字段或者标记来判断是否需要对方法进行拦截,对公共字段进行处理。这里我们引入注解自定义注解AutoFuil来进行标识。同时我们自定义一个切面类AutoFillAspect,统一拦截加入了AutoFill注解的方法,通过反射为公共字段赋值。因此我们在Mapper方法上加入AutoFill注解。
3.代码开发
(1)自定义注解AutoFill和枚举类


这里我们自定义注解@AutoFill,用于标识方法需要进行公共字段填充,@Target表明注解的应用范围是在方法上,@Retention表明注解会在运行时保留,方便切面读取。OperationType value()用来指定数据库操作类型,可以是insert 或 update,这个值将在切面中用来判断当前方法是插入操作还是更新操作。。
(2)自定义切面类AutoFillAspect



首先通过@pointcut注解定义了切入点,execution会拦截com.sky.mapper包下所有类的所有方法,@annotation(com.sky.annotation.AutoFill)会拦截@Autofill注解标识的所有方法。
这里我们使用前置通知的方式对公共字段进行处理,在执行数据库操作前自动填充公共字段,joinPoint是AOP提供的对象,用于访问正在执行的方法的相关信息。可以通过它获取方法签名、参数等。
我们使用joinPoint.getSignature()方法返回当前方法的签名信息,它包含方法的名字、返回类型、参数等信息,将其转换为MethodSignature类型。
getMethod()获取当前执行的方法对象,getAnnotation(AutoFill.class)获取方法上的 @AutoFill 注解对象,autoFill.value()获取注解中的操作类型,即数据库操作类型,INSERT 或 UPDATE。
joinPoint.getArgs()获取正在执行的方法的参数,假设方法的第一个参数是实体对象,那么就从arg[]数组中取出这个对象。
最后根据操作类型(INSERT 或 UPDATE)为字段赋值,以插入操作为例子,通过反射,首先使用 getDeclaredMethod 获取实体对象中的 setter 方法(根据字段名称),然后使用 invoke 方法调用这些方法,传入相应的值(当前时间和当前用户 ID)。
(3)在Mapper的方法上加入AutoFill注解


(4)在对应的实现类注释相关内容

