1.1 Problem Analysis
Each table has fields such as creation time, creator, modification time, and modification person.
Serial number | Field name | Meaning | Data type | |
---|---|---|---|---|
1 | create_time | Creation time | datetime | |
2 | create_user | Creator id | bigint | |
3 | update_time | Modification time | datetime | |
4 | update_user | Modify person id | bigint |
Serial number | Field name | Meaning | Data type | Operation type |
---|---|---|---|---|
1 | create_time | Creation time | datetime | insert |
2 | create_user | Creator id | bigint | insert |
3 | update_time | Modification time | datetime | insert, update |
4 | update_user | Modifier id | bigint | insert, update |
Implementation steps:
1). Custom annotation AutoFill, used to identify methods that require automatic filling of public fields
2). Customize the aspect class AutoFillAspect to uniformly intercept methods with AutoFill annotations and assign values to public fields through reflection.
3). Add AutoFill annotation to the Mapper method
1.3 Code Development
Public dependencies
Create the AutoFillConstant class under the common constant package
package com.sky.constant; /** * Public fields automatically fill in relevant constants */ public class AutoFillConstant { /** *Method name in entity class */ 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"; }
Create the OperationType class under the common enumeration package
package com.sky.enumeration; /** * Database operation type */ public enum OperationType { /** * Update operation */ UPDATE, /** * Insert operation */ INSERT }
1.3.1 Step 1
Custom annotation AutoFill
Enter the server module, create annotation package, and create AutoFill annotation
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; /** * Custom annotations used to identify a method that requires automatic filling of function fields */ @Target(ElementType.METHOD)//Specify that this annotation can only be added to the method @Retention(RetentionPolicy.RUNTIME)//JVM retains this annotation at runtime and allows access through reflection public @interface AutoFill { //Specify the database operation mode through enumeration: update insert OperationType value(); }
1.3.2 Step 2
Custom aspect AutoFillAspect
In the server module, create the aspect package and AutoFillAspect class
package com.sky.aspect; import com.sky.annotation.AutoFill; import com.sky.constant.AutoFillConstant; import com.sky.context.BaseContext; import com.sky.enumeration.OperationType; 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.lang.reflect.Method; import java.time.LocalDateTime; /** * Customize aspects to implement automatic filling processing logic of public fields */ @Aspect//The statement is an aspect @Component//bean is handed over to spring container management @Slf4j public class AutoFillAspect { /** * Define entry point */ //point-cut expression @Pointcut("execution(* com.sky.mapper.*.*(..)) & amp; & amp; @annotation(com.sky.annotation.AutoFill)")//Intercept the method below mapper and add AutoFill annotation public void autoFillPointCut(){} /** * Define pre-notifications and assign values to public fields in the notifications */ //Pre-notification, before performing the operation @Before("autoFillPointCut()")//When matching the upper point cut expression, execute the notification method public void autoFill(JoinPoint joinPoint){//Join point, which method was intercepted, and the intercepted method parameter value and type log.info("Start automatic filling of public fields..."); /** *Notification content */ //1. Obtain the database operation type on the currently intercepted method MethodSignature signature = (MethodSignature) joinPoint.getSignature();//Method signature object, Signature is the interface converted to MethodSignature sub-interface AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//Get the annotation object on the method OperationType operationType = autoFill.value();//Get the database operation type written on the mapper method //2. Get the parameters of the currently intercepted method, which is the entity object Object[] args = joinPoint.getArgs();//Get the parameters of the connection point. There are multiple parameters. It is agreed that the first parameter is the entity. if(args == null || args.length == 0){ return; } Object entity = args[0];//In the database operation method, it is agreed that the entity class must be the first parameter to obtain the entity //3. Prepare data for assignment LocalDateTime now = LocalDateTime.now(); Long currentId = BaseContext.getCurrentId(); //4. According to the current different operation types, assign values to the corresponding attributes through reflection. if(operationType == OperationType.INSERT){ //Assign values to 4 public fields try { //Get set method // Standardize to prevent writing errors and write method names as constant classes 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); //Assign values to object properties through reflection 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){ //Assign values to 2 public fields try { //Get set method Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class); Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class); //Assign values to object properties through reflection setUpdateTime.invoke(entity,now); setUpdateUser.invoke(entity,currentId); } catch (Exception e) { e.printStackTrace(); } } } }
1.3.3 Step 3
Add AutoFill annotation to the method of Mapper interface
Example:
@AutoFill(value = OperationType.INSERT)
void insert(Category category);
@AutoFill(value = OperationType.UPDATE)
void update(Category category);