• mybatis自动填充时间字段


    对于实体中的created_onupdated_on来说,它没有必要被开发人员去干预,因为它已经足够说明使用场景了,即在插入数据和更新数据时,记录当前时间,这对于mybatis来说,通过拦截器是可以实现的,记得之前说过在jpa中实现的方法,主要通过jpa的注解实现的,因为今天的mybatis需要用到java的拦截器。

    定义两个注解

    @Retention(RetentionPolicy.RUNTIME)
    @Target( {ElementType.FIELD})
    public @interface CreatedOnFuncation {
    
      String value() default "";
    }
    @Retention(RetentionPolicy.RUNTIME)
    @Target( {ElementType.FIELD})
    public @interface UpdatedOnFuncation {
    
      String value() default "";
    }
    

    使用这两个注解

    @Getter
    @Builder(toBuilder = true)
    @ToString
    public class UserInfo {
      private Long id;
      private String name;
      private String email;
    
      @CreatedOnFuncation
      private LocalDateTime createdOn;
      @UpdatedOnFuncation
      private LocalDateTime updatedOn;
    }
    
    

    定义拦截器,重写赋值的语句

    /**
     * 时间拦截器.
     */
    @EqualsAndHashCode(callSuper = true)
    @Data
    @Accessors(chain = true)
    @Intercepts({@Signature(
        type = org.apache.ibatis.executor.Executor.class,
        method = "update",
        args = {MappedStatement.class, Object.class})})
    public class CreateUpdateTimeInterceptor extends AbstractSqlParserHandler implements Interceptor {
    
      private Properties properties;
    
      @Override
      public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
    
        // 获取 SQL 命令
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
    
        // 获取参数
        Object parameter = invocation.getArgs()[1];
    
        // 获取私有成员变量
        Field[] declaredFields = parameter.getClass().getDeclaredFields();
        if (parameter.getClass().getSuperclass() != null) {
          Field[] superField = parameter.getClass().getSuperclass().getDeclaredFields();
          declaredFields = ArrayUtils.addAll(declaredFields, superField);
        }
        // 是否为mybatis plug
        boolean isPlugUpdate = parameter.getClass().getDeclaredFields().length == 1
            && parameter.getClass().getDeclaredFields()[0].getName().equals("serialVersionUID");
    
        //兼容mybatis plus的update
        if (isPlugUpdate) {
          Map<String, Object> updateParam = (Map<String, Object>) parameter;
          Class<?> updateParamType = updateParam.get("param1").getClass();
          declaredFields = updateParamType.getDeclaredFields();
          if (updateParamType.getSuperclass() != null) {
            Field[] superField = updateParamType.getSuperclass().getDeclaredFields();
            declaredFields = ArrayUtils.addAll(declaredFields, superField);
          }
        }
        for (Field field : declaredFields) {
    
          // insert
          if (field.getAnnotation(CreatedOnFuncation.class) != null) {
            if (SqlCommandType.INSERT.equals(sqlCommandType)) {
              field.setAccessible(true);
              field.set(parameter, new Timestamp(System.currentTimeMillis()));
            }
          }
    
          // update
          if (field.getAnnotation(UpdatedOnFuncation.class) != null) {
            if (SqlCommandType.INSERT.equals(sqlCommandType)
                || SqlCommandType.UPDATE.equals(sqlCommandType)) {
              field.setAccessible(true);
    
              //兼容mybatis plus的update
              if (isPlugUpdate) {
                Map<String, Object> updateParam = (Map<String, Object>) parameter;
                field.set(updateParam.get("param1"), new Timestamp(System.currentTimeMillis()));
              } else {
                field.set(parameter, new Timestamp(System.currentTimeMillis()));
              }
            }
          }
        }
    
        return invocation.proceed();
      }
    
      @Override
      public Object plugin(Object target) {
        if (target instanceof org.apache.ibatis.executor.Executor) {
          return Plugin.wrap(target, this);
        }
        return target;
      }
    
      @Override
      public void setProperties(Properties prop) {
        this.properties = prop;
      }
    }
    

    添加测试用例

      @Test
      public void insert() {
        UserInfo userInfo = UserInfo.builder()
            .name("lind")
            .email("test@sina.com")
            .build();
        userInfoMapper.insert(userInfo);
        System.out.println("userinfo:" + userInfo.toString());
      }
    

    解决是我们所预想的,created_on和updated_on被自动赋上值了。

    userinfo:UserInfo
    (
    id=1085780948955959297, 
    name=lind, 
    email=test@sina.com, 
    createdOn=2019-01-17T14:08:45.665,
    updatedOn=2019-01-17T14:08:45.665
    )
    
    
  • 相关阅读:
    js数组根据对象中的元素(相同的属性值)去重
    nginx设置add_header 跨域依旧失败解决
    canvas前端压缩图片和视频首屏缩略图并上传到服务器
    纯前端下载文件的方法
    vue多文件上传进度条 进度不更新问题
    jquery中attr和prop的区别
    为什么我认为数据结构与算法对前端开发很重要?
    CSS2.0实现面包屑
    Vue是如何渲染页面的,渲染过程以及原理代码
    js 事件驱动原理
  • 原文地址:https://www.cnblogs.com/lori/p/10281976.html
Copyright © 2020-2023  润新知