所有分类
  • 所有分类
  • 未分类

MyBatis-Plus–自动填充的用法

简介

说明

本文介绍MybatisPlus的自动填充的用法。

官网网址

自动填充功能 | MyBatis-Plus

使用场景

在数据入库的时候,不管新增或者修改数据,都要手动来设置添加时间和修改时间。每个插入都需要设置,而且数据库还设置不能为空,就很烦恼。

虽然可以在数据库设置默认值,但若没有数据库表修改权限,那就从技术上来解决这个问题吧。(如果有数据库表修改权限,可直接设置相应字段属性)。

失效的情况

  1. 使用自定义sql(Mapper的方法上边用@Update()等编写的语句)
    1. 解决方法:在自定义sql对应的方法里,多传一个时间参数。
  2. remove()等删除方法
    1. 解决方法1:用新版本的MyBatis-Plus。(自测成功的版本:mybatis-plus-boot-starter:3.4.1、3.4.2、3.5.1)
    2. 解决方法2:使用removeById()、deleteById()、手动调用set语句等。见:官方网站
    3. 解决方法3:写一个全局的MyBatis拦截器,填充相应字段。

entity

在实体类字段上,通过注解方式设置需要在执行什么操作填充,一共有三种:新增、更新、删除操作。

当然

@Data
@TableName("t_user")
public class User {
 
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    /**
     * 插入与更新都写此字段。
	 * 若使用FieldFill.UPDATE,则只更新时写此字段。
	 */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}

handler(推荐的写法)

如果有些数据库的表没有创建时间和修改时间字段,如果执行这些操作有点浪费,可以判断是否有setter。

在3.3.2及之后的版本中,已经有了这样的功能,而之前的版本需要手动判断。 

mybatis-plus3.3.2及之后

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDateTime;

@Slf4j
@Configuration
//@MapperScan("com.example.**.mapper")
public class MyBatisPlusConfig {
    /**
	 * 自动填充插件
	 */
    @Bean
    public MetaObjectHandler metaObjectHandler() {
        return new MybatisPlusAutoFillConfig();
    }
}
package com.example.demo.config.mybatisplus.inner;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;

import java.time.LocalDateTime;

@Slf4j
public class MybatisPlusAutoFillConfig implements MetaObjectHandler {
    /**
     * 新增时填充
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("新增:自动填充createTime:" + LocalDateTime.now());

        // 起始版本 3.3.0(推荐使用)
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
        // 更新时间最好也填充一下
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());

        // 或者(起始版本 3.3.3(推荐))
        // this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class);

        // 或者(3.3.0 该方法有bug)
        // this.fillStrategy(metaObject, "createTime", LocalDateTime.now());

        // 或者(不推荐)
        // setFieldValByName("createTime", LocalDateTime.now(), metaObject);
        // setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
    }

    /**
     * 修改时填充
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("更新:自动填充updateTime:" + LocalDateTime.now());

        // 起始版本 3.3.0(推荐使用)
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());

        // 或者(起始版本 3.3.3(推荐))
        // this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class);

        // 或者(3.3.0 该方法有bug)
        // this.fillStrategy(metaObject, "updateTime", LocalDateTime.now());

        // 或者(不推荐)
        // setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
    }
}

配置文件另一种写法

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

import java.time.LocalDateTime;

@Component
public class MybatisPlusAutoFillConfig implements MetaObjectHandler {
    private static final Logger logger= LoggerFactory.getLogger(MybatisPlusAutoInjectConfig.class);

    // 新增时填充
    @Override
    public void insertFill(MetaObject metaObject) {
        logger.info("插入:自动填充createTime和updateTime:"+ LocalDateTime.now());

        boolean hasCreateTimeSetter = metaObject.hasSetter("createTime");
        Object createTime = getFieldValByName("createTime", metaObject);
        if (hasCreateTimeSetter) {
            // 第一个参数对应实体属性名, 第二个参数需要填充的值
            setInsertFieldValByName("createTime", LocalDateTime.now(), metaObject);
        }

        boolean hasupdateTimeSetter = metaObject.hasSetter("updateTime");
        Object updateTime = getFieldValByName("updateTime", metaObject);
        if (hasupdateTimeSetter) {
            // 第一个参数对应实体属性名, 第二个参数需要填充的值
            setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        }
    }

    // 修改时填充
    @Override
    public void updateFill(MetaObject metaObject) {
        logger.info("更新:自动填充updateTime:" + LocalDateTime.now());

        boolean hasSetter = metaObject.hasSetter("updateTime");
        Object updateTime = getFieldValByName("updateTime", metaObject);
        if (hasSetter) {
            // 第一个参数对应实体属性名, 第二个参数需要填充的值
            setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        }
    }
}

mybatis-plus3.3.2之前

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDateTime;

@Configuration
//@MapperScan("com.example.**.mapper")
public class MyBatisPlusConfig {
    private static final Logger logger = LoggerFactory.getLogger(MyBatisPlusConfig.class);

    //自动填充插件
    @Bean
    public MetaObjectHandler metaObjectHandler() {
        return new MybatisPlusAutoFillConfig();
    }

    public static class MybatisPlusAutoFillConfig implements MetaObjectHandler {
        // 新增时填充
        @Override
        public void insertFill(MetaObject metaObject) {
            logger.info("插入:自动填充createTime和updateTime:"+ LocalDateTime.now());
            setFieldValByName("createTime", LocalDateTime.now(), metaObject);
            setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        }

        // 修改时填充
        @Override
        public void updateFill(MetaObject metaObject) {
            logger.info("更新:自动填充updateTime:" + LocalDateTime.now());
            setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        }
    }
}

也可以这样写配置文件 

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

import java.time.LocalDateTime;

@Component
public class MybatisPlusAutoFillConfig implements MetaObjectHandler {
    private static final Logger logger= LoggerFactory.getLogger(MybatisPlusAutoInjectConfig.class);

    // 新增时填充
    @Override
    public void insertFill(MetaObject metaObject) {
        logger.info("插入:自动填充createTime和updateTime:"+ LocalDateTime.now());
        boolean hasCreateTimeSetter = metaObject.hasSetter("createTime");
        Object createTime = getFieldValByName("createTime", metaObject);
        if (hasCreateTimeSetter) {
            // 第一个参数对应实体属性名, 第二个参数需要填充的值
            setInsertFieldValByName("createTime", LocalDateTime.now(), metaObject);
        }

        boolean hasupdateTimeSetter = metaObject.hasSetter("updateTime");
        Object updateTime = getFieldValByName("updateTime", metaObject);
        if (hasupdateTimeSetter) {
            // 第一个参数对应实体属性名, 第二个参数需要填充的值
            setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        }
    }

    // 修改时填充
    @Override
    public void updateFill(MetaObject metaObject) {
        logger.info("更新:自动填充updateTime:" + LocalDateTime.now());
        boolean hasSetter = metaObject.hasSetter("updateTime");
        Object updateTime = getFieldValByName("updateTime", metaObject);
        if (hasSetter) {
            // 第一个参数对应实体属性名, 第二个参数需要填充的值
            setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        }
    }
}

handler(不推荐的写法)

因为如果updateTime不是null,则不会更新updateTime,不适用于先查出数据修改后再写入的情况

package com.example.base.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDateTime;
 
@Configuration
//@MapperScan("com.example.**.mapper")
public class MyBatisPlusConfig {
    private static final Logger logger = LoggerFactory.getLogger(MyBatisPlusConfig.class);
 
    //自动填充插件
    @Bean
    public MetaObjectHandler metaObjectHandler() {
        return new MybatisPlusAutoFillConfig();
    }
 
    public static class MybatisPlusAutoFillConfig implements MetaObjectHandler {
        // 新增时填充
        @Override
        public void insertFill(MetaObject metaObject) {
            logger.info("插入:自动填充createTime和updateTime:"+ LocalDateTime.now());

            this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
            this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
            // 或者
            // this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
            // this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        }
 
        // 修改时填充
        @Override
        public void updateFill(MetaObject metaObject) {
            logger.info("更新:自动填充updateTime:" + LocalDateTime.now());
            this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
            // 或者
            // this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)        
        }
    }
}

性能分析

性能损耗可以忽略不计。

0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录