For the created ﹣ on and updated ﹣ on entities, it is unnecessary for developers to intervene, because it is enough to explain the use scenario, that is, when inserting and updating data, record the current time. For mybatis, it can be realized through interceptors. Remember that the methods implemented in jpa are mainly realized through jpa annotations, because today Day mybatis needs to use the java interceptor.
Define two notes
@Retention(RetentionPolicy.RUNTIME) @Target( ) public @interface CreatedOnFuncation { String value() default ""; } @Retention(RetentionPolicy.RUNTIME) @Target( ) public @interface UpdatedOnFuncation { String value() default ""; }
Use these two notes
@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; }
Define interceptor and rewrite assignment statement
package com.lind.basic.mybatis; import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler; import java.lang.reflect.Field; import java.time.LocalDateTime; import java.util.Properties; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlCommandType; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; /** * Time interceptor */ @EqualsAndHashCode(callSuper = true) @Data @Accessors(chain = true) @Intercepts( { @Signature( type = org.apache.ibatis.executor.Executor.class, method = "update", args = )}) public class CreateUpdateTimeInterceptor extends AbstractSqlParserHandler implements Interceptor { private static final Log logger = LogFactory.getLog(com.baomidou.mybatisplus.extension.plugins.SqlExplainInterceptor.class); private Properties properties; @Override public Object intercept(Invocation invocation) throws Throwable { MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; // Get SQL command SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType(); // Get parameters Object parameter = invocation.getArgs()[1]; // Get private member variable Field[] declaredFields = parameter.getClass().getDeclaredFields(); for (Field field : declaredFields) { if (field.getAnnotation(CreatedOnFuncation.class) != null) { if (SqlCommandType.INSERT.equals(sqlCommandType)) { // Insert statement insert createTime field.setAccessible(true); field.set(parameter, LocalDateTime.now()); } } if (field.getAnnotation(UpdatedOnFuncation.class) != null) { // Insert or update statement insert updateTime if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) { field.setAccessible(true); field.set(parameter, LocalDateTime.now()); } } } 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; } }
Add test case
@Test public void insert() { UserInfo userInfo = UserInfo.builder() .name("lind") .email("[email protected]") .build(); userInfoMapper.insert(userInfo); System.out.println("userinfo:" + userInfo.toString()); }
The solution is what we expected. created_on and updated_on are automatically assigned values.
userinfo:UserInfo ( id=1085780948955959297, name=lind, [email protected], createdOn=2019-01-17T14:08:45.665, updatedOn=2019-01-17T14:08:45.665 )