mybatis automatically fills in the time field

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

@Target( {ElementType.FIELD})
public @interface CreatedOnFuncation {

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

  String value() default "";

Use these two notes

@Builder(toBuilder = true)
public class UserInfo {
  private Long id;
  private String name;
  private String email;

  private LocalDateTime createdOn;
  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)
@Accessors(chain = true)
@Intercepts( {
        type = org.apache.ibatis.executor.Executor.class,
        method = "update",
        args = {MappedStatement.class, Object.class})})
public class CreateUpdateTimeInterceptor extends AbstractSqlParserHandler implements Interceptor {

  private static final Log logger = LogFactory.getLog(com.baomidou.mybatisplus.extension.plugins.SqlExplainInterceptor.class);

  private Properties properties;

  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

      if (field.getAnnotation(UpdatedOnFuncation.class) != null) { // Insert or update statement insert updateTime
        if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {

    return invocation.proceed();

  public Object plugin(Object target) {
    if (target instanceof org.apache.ibatis.executor.Executor) {
      return Plugin.wrap(target, this);
    return target;

  public void setProperties(Properties prop) { = prop;

Add test case

  public void insert() {
    UserInfo userInfo = UserInfo.builder()
    System.out.println("userinfo:" + userInfo.toString());

The solution is what we expected. created_on and updated_on are automatically assigned values.


Tags: Java Apache Mybatis Lombok

Posted on Mon, 02 Dec 2019 03:07:49 -0500 by karenruth