Field filling of MyBatisPlus

Keywords: mybatis-plus

It will be the top of the mountain

| @Author: TTODS

MyBatisPlus framework series article directory:

preface

Mybatisplus provides a very useful field filling function, which can fill the specified value for the field according to the set rules when inserting or updating records. This article will demonstrate how to use the field filling function of mybatisplus to automatically fill the update time field and insertion time field recorded in the table.

Create a new test table record

Create a new record table in the database, which has four fields:

  1. id number
  2. record_name record name
  3. create_date insert date
  4. update_date modification date
CREATE TABLE `record`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `record_name` varchar(255) COMMENT 'Record name',
  `create_date` timestamp(0) COMMENT 'Creation time',
  `update_date` timestamp(0) COMMENT 'Update time',
  PRIMARY KEY (`id`)
);

The created table structure is as follows:

Write entity class Record

Create the entity class record corresponding to the record table in the com.example.pojo package

package com.example.pojo;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

import java.time.LocalDateTime;

@Data
public class Record {
    @TableId(type = IdType.AUTO)
    private Integer id;
    @TableField(value="record_name")
    private String name;
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createDate;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateDate;
}

In the entity class, we use some annotations:

  • @TableId annotation: the field corresponding to the marked attribute is the primary key of the table. The parameter type=IdType.AUTO indicates that the primary key is self incremented

  • @TableField annotation. The marked attribute is a field in the database, and the value attribute represents the field name in the corresponding database table. However, mybatis plus is configured with underline to hump naming by default, so the @ TableField corresponding to ceateDate and updateDate below does not need to write the value attribute.

    @The fill attribute of the TableField annotation indicates the field filling strategy. There are four filling strategies:

    1. DEFAULT is not processed by DEFAULT
    2. INSERT fill on INSERT
    3. Fill in when UPDATE
    4. INSERT_UPDATE is populated when inserting updates

In the above entity class, we set createDate to be filled when inserting and updateDate to be filled when inserting updates

For more information on annotations, please refer to Notes to official documents

Write RecordMapper

Create a RecordMapper interface in the com.example.mapper package and make it inherit the basemapper < T > interface provided by mybatos plus

package com.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.pojo.Record;

public interface RecordMapper extends BaseMapper<Record> {
}

Implement your own MetaObjectHandler

Although we have set the filling policy for the fields to be filled, mybatis plus does not know which values to fill. We also need to create a MyMetaObjectHandler class to implement the MetaObjectHandler interface and the insertFill and updateFill methods

When implementing these two methods, we can call the strictInsertFill and strictUpdateFill methods of the parent class for filling, or use the fillStrategy method for filling

The signatures of the strictInsertFill and strictInsertFill methods are as follows:

default <T, E extends T> MetaObjectHandler strictInsertFill(MetaObject metaObject, String fieldName, Class<T> fieldType, E fieldVal);

These two methods will decide whether to fill or not according to the filling policy, field name and field type set by the fill of @ TableField of the corresponding field

For example, if the strictUpdateFill method is called to fill the createDate field, but the annotation on the createDate field indicates that the filling strategy is TableFill.INSERT, it will not be filled. When the type of the field corresponding to the field name is not fieldType, it will not be filled

The fillStrategy method is implemented as follows:

 default MetaObjectHandler fillStrategy(MetaObject metaObject, String fieldName, Object fieldVal) {
        if (getFieldValByName(fieldName, metaObject) == null) {
            setFieldValByName(fieldName, fieldVal, metaObject);
        }
        return this;
    }

This method will not strictly judge the filling strategy and field type. As long as the value of the corresponding field is null, it will be filled. Exceptions will be caused when the types do not match

package com.example.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Component
public class MyMateObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        // strictInsertFill and strictUpdateFill will determine whether to fill according to the TableFill policy, field name and field type in the annotation
        this.strictInsertFill(metaObject,"createDate",LocalDateTime.class, LocalDateTime.now());
        this.strictInsertFill(metaObject,"updateDate",LocalDateTime.class, LocalDateTime.now());
        // The strictStrategy method will be filled as long as the filling policy is not DEFAULT and the field name can be aligned
        //this.fillStrategy(metaObject,"createDate",LocalDateTime.now());
        //this.fillStrategy(metaObject,"updateDate",LocalDateTime.now());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject,"updateDate",LocalDateTime.class, LocalDateTime.now());
    }
}

Writing test classes

package com.example;

import com.example.mapper.RecordMapper;
import com.example.pojo.Record;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@SpringBootTest
@RunWith(SpringRunner.class)
public class AutoFillTests {
    @Resource
    RecordMapper mapper;

    @Test
    public void testInsert(){
        Record record = new Record();
        record.setName("record_one");
        mapper.insert(record);
    }

    @Test
    public void testUpdate(){
        UpdateWrapper<Record> wrapper = new UpdateWrapper<>();
        wrapper.eq("id",1);
        Record record = new Record();
        record.setName("record1");
        mapper.update(record,wrapper);
    }
}

Test the insertion first, and the generated sql code is as follows:

==>  Preparing: INSERT INTO record ( record_name, create_date, update_date ) VALUES ( ?, ?, ? )
==> Parameters: record_one(String), 2021-10-25T11:16:30.834(LocalDateTime), 2021-10-25T11:16:30.837(LocalDateTime)
<==    Updates: 1

It can be seen that during insertion, mybatis plus performs create according to the rules_ date,update_ Date fields are populated

Then test the update and generate the sql code as follows:

==>  Preparing: UPDATE record SET record_name=?, update_date=? WHERE (id = ?)
==> Parameters: record1(String), 2021-10-25T12:12:59.954(LocalDateTime), 1(Integer)
<==    Updates: 1

It can be seen that during update, mybatis plus automatically fills in update_date field

Previous: Paging function provided by MyBatisPlus
Next: Logical deletion of MyBatisPlus

- THE END -

Posted by jpratt on Mon, 25 Oct 2021 01:29:19 -0700