问题分析

实现思路
- 对mapper定义
注解
,使用切面
思想来判断是不是更新和新增操作 - 对于指定的操作来更新公共字段

自定义操作类型

package com.sky.enumeration;
public enum OperationType {UPDATE,INSERT}
自定义注解AutoFill

package com.sky.annotation;import com.sky.enumeration.OperationType;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {OperationType value();
}
自定义切面
- 定义切点
- 获取当前的mapper方法的具体操作类型
- 获取当前的mapper方法的参数 实体对象entity
- 获取要填充的数据
- 根据操作类型进行填充
package com.sky.aspect;import cn.hutool.core.util.ObjectUtil;
import com.sky.annotation.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import com.sky.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;import static com.sky.constant.AutoFillConstant.*;
import static com.sky.constant.MessageConstant.AUTO_FILL_FAILED;
@Aspect
@Component
@Slf4j
public class AutoFillAspect {@Pointcut("execution(* com.sky.mapper..*.*(..)) && @annotation(com.sky.annotation.AutoFill)")public void autoFillPointCut() {}@Before("autoFillPointCut()")public void before(JoinPoint joinPoint) {log.info("自动填充切面执行");MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();OperationType operationType = methodSignature.getMethod().getAnnotation(AutoFill.class).value();Object[] args = joinPoint.getArgs();if(ObjectUtil.isEmpty(args)) return;Object entity = args[0];Long currentUserId = BaseContext.getCurrentId();LocalDateTime now = LocalDateTime.now();switch (operationType) {case INSERT:try {entity.getClass().getMethod(SET_CREATE_USER, Long.class).invoke(entity, currentUserId);entity.getClass().getMethod(SET_UPDATE_USER, Long.class).invoke(entity, currentUserId);entity.getClass().getMethod(SET_CREATE_TIME, LocalDateTime.class).invoke(entity, now);entity.getClass().getMethod(SET_UPDATE_TIME, LocalDateTime.class).invoke(entity, now);} catch (Exception e) {log.error(AUTO_FILL_FAILED, e);throw new BaseException(AUTO_FILL_FAILED);}break;case UPDATE:try {entity.getClass().getMethod(SET_UPDATE_USER, Long.class).invoke(entity, currentUserId);entity.getClass().getMethod(SET_UPDATE_TIME, LocalDateTime.class).invoke(entity, now);} catch (Exception e) {log.error(AUTO_FILL_FAILED, e);throw new BaseException(AUTO_FILL_FAILED);}break;default:break;}}
}
使用
@AutoFill(OperationType.UPDATE)void update(Category category);
@AutoFill(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);