Java Spring Boot单体架构项目 实现公共字段自动填充

    当我们在进行写项目的时候,往往会遇到实现某一个接口的时候会遇到反复使用某些方法的时候,会进行代码复用,举个例子:比如我们实现update修改操作的时候,我们需要更新 修改时间update_timeupdate_user 当我们实现插入insert操作的时候,我们需要更新update_user   create_usercreate_userid 等操作。每次写这些的时候会造成代码冗余,如何解决呢?

一:自定义注解AutoFill,用于标识需要进行公共字段自动填充的方法。

我们需要自定义一个注解。

/**
 * 自定义注解,用于表示某个方法需要进行功能字段填充处理
 */
@Target(ElementType.METHOD)//指明注解只能加在方法上面
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
    //数据库操作类型; Update Insert
    OperationType value();
}

OperationType是一个枚举类,里面定义了我们需要进行操作的类型名称。

public enum OperationType {

    /**
     * 更新操作
     */
    UPDATE,

    /**
     * 插入操作
     */
    INSERT

}
二:自定义切面类AutoFillAspect,同意拦截加入了AutoFill注解的方法,通过反射为公共红字段赋值
**
 * 自定义切面类,实现公共字段自动填充处理逻辑
 */
@Aspect  //切面类的注解
@Component //交给spring容器管理
@Slf4j
public class AutoFillAspect {

    /**
     * 切入点
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..))&& @annotation(com.sky.annotation.AutoFill)")//该包下所有方法,并且加入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){
            //为4个公共字段赋值
            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){

            //为2个公共字段赋值
            try {  //获取到某个实体类的 这四个方法
              //  Method setCreateTime = entity.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);
             //   Method setCreateUser = entity.getClass().getDeclaredMethod("setCreateUser", 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);
            }



        }

    }
}

@Pointcut 这个注解的意思是切入点,意思是后面路径的类的方法都会进行处理。、

因为在用update和insert方法时,才会更新创建人和创建时间,更新时间等,所以我们要用前置通知。@Before注解。

注意:我们在定义方法时候,如果有多个参数的时候第一个参数必须是实体类!

如果大家在引入@Aspect 注解爆红的时候,引入AOP的依赖就好了,下面是AOP的依赖

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
三:在Mapper的方法上加入AutoFill注解

最后一步是在我们定义的Mapper的方法上加入AutoFill注解 例如:

 @AutoFill(value = OperationType.UPDATE)
    void update(Employee employee);

value值后面跟的是该方法的数据库操作类型。(是更新操作还是新增操作)

四:技术点

我们使用的技术点有:枚举注解AOP反射。

如果有不懂的或者有不足的欢迎在评论区或者私信留言,一定会第一时间回复、以后会多多更新的!!感谢大佬们的观看和关注!!

  • 15
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假删除是指将数据的状态标记为已删除,而不是真正地从数据库中删除。Spring Boot 和 Mybatis Plus 都提供了实现假删除的方式。 首先,在数据库表中添加一个表示删除状态的字段,比如 is_deleted。默认情况下,这个字段的值应该是 false。 然后,在 Mybatis Plus 中,可以使用注解 @TableLogic 和 @TableField 来标记这个字段。@TableLogic 表示逻辑删除,@TableField 表示数据表中的字段。 示例代码如下: ```java @Data @TableName("user") public class User { @TableId(type = IdType.AUTO) private Long id; private String name; private Integer age; @TableLogic @TableField(value = "is_deleted", fill = FieldFill.INSERT) private Boolean deleted; } ``` 在上面的代码中,@TableLogic 表示逻辑删除,@TableField(value = "is_deleted", fill = FieldFill.INSERT) 表示 is_deleted 字段在插入数据时自动填充为 false。 接下来,在进行查询时,需要将 is_deleted 字段的值设为 false,示例代码如下: ```java public interface UserDao extends BaseMapper<User> { @Override @Select("select * from user where is_deleted = false") List<User> selectList(Wrapper<User> queryWrapper); } ``` 在上面的代码中,使用了 Mybatis Plus 的 Wrapper 类来构建查询条件。is_deleted 字段的值被设为 false。 最后,在进行删除时,只需要将 is_deleted 字段的值设为 true 即可,示例代码如下: ```java public void deleteUser(Long id) { User user = new User(); user.setId(id); user.setDeleted(true); userDao.updateById(user); } ``` 在上面的代码中,将 id 对应的数据的 is_deleted 字段设为 true,达到假删除的目的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值