对于实体中的created_on
和updated_on
来讲,它没有必要被开发人员去干预,由于它已经足够说明使用场景了,即在插入数据和更新数据时,记录当前时间,这对于mybatis来讲,经过拦截器是能够实现的,记得以前说过在jpa中实现的方法,主要经过jpa的注解实现的,由于今天的mybatis须要用到java的拦截器。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被自动赋上值了。sql
userinfo:UserInfo ( id=1085780948955959297, name=lind, email=test@sina.com, createdOn=2019-01-17T14:08:45.665, updatedOn=2019-01-17T14:08:45.665 )