MyBatis-Plus 自动填充的实现示例

 更新时间:2024年09月25日 09:02:39   作者:Flying_Fish_Xuan  
MyBatis-Plus 提供了自动填充功能,帮助开发者在插入或更新数据时,自动为某些字段赋值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在日常开发中,数据库表通常会包含一些系统自动维护的字段,例如:创建时间、更新时间、操作人等。为了减少手动维护这些字段的重复代码,MyBatis-Plus 提供了自动填充功能,帮助开发者在插入或更新数据时,自动为某些字段赋值。

1. MyBatis-Plus 自动填充简介

MyBatis-Plus 提供的自动填充功能,可以在数据库插入或更新时,自动为指定的字段设置值,而不需要每次手动传递。例如:

  • 在记录插入时自动填充创建时间 created_at
  • 在记录更新时自动填充更新时间 updated_at
  • 自动填充操作用户 ID 或者一些其他固定值。

MyBatis-Plus 通过 @TableField 注解中的 fill 属性和 MetaObjectHandler 接口来实现自动填充。fill 属性用于指定字段在插入或更新时是否自动填充,而 MetaObjectHandler 是用于实现自动填充逻辑的接口。

2. 自动填充的配置步骤

2.1 在实体类中标注需要自动填充的字段

MyBatis-Plus 通过 @TableField(fill = ...) 注解来标注需要自动填充的字段,并指定该字段的填充策略。常见的填充策略有:

  • FieldFill.INSERT:在插入时自动填充。
  • FieldFill.UPDATE:在更新时自动填充。
  • FieldFill.INSERT_UPDATE:在插入和更新时都自动填充。

示例:

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.time.LocalDateTime;

@Data
public class User {

    private Integer id;

    private String username;

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createdAt;  // 插入时自动填充

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updatedAt;  // 插入和更新时自动填充
}
  • createdAt:在插入记录时自动填充当前时间。
  • updatedAt:在插入和更新记录时自动填充当前时间。

2.2 创建自动填充处理器

MyBatis-Plus 提供了 MetaObjectHandler 接口,开发者可以实现该接口中的 insertFill 和 updateFill 方法来自定义填充逻辑。

示例:

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 MyMetaObjectHandler implements MetaObjectHandler {

    // 插入时自动填充
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createdAt", LocalDateTime::now, LocalDateTime.class);  // 创建时间
        this.strictInsertFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);  // 更新时间
    }

    // 更新时自动填充
    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);  // 更新时间
    }
}
  • strictInsertFill:用于在插入操作时自动填充指定字段。
  • strictUpdateFill:用于在更新操作时自动填充指定字段。

在 insertFill 方法中,createdAt 和 updatedAt 字段会在插入时自动填充当前时间。而在 updateFill 方法中,updatedAt 字段会在更新时自动填充当前时间。

2.3 完整示例

以下是一个完整的 MyBatis-Plus 自动填充示例,包含实体类、填充处理器和测试代码:

1. User 实体类

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

@Data
public class User {

    @TableId(type = IdType.AUTO)
    private Integer id;

    private String username;

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createdAt;  // 创建时自动填充

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updatedAt;  // 创建和更新时自动填充
}

2. 自动填充处理器

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 MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createdAt", LocalDateTime::now, LocalDateTime.class);
        this.strictInsertFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);
    }

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

3. UserMapper 接口

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.model.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

4. 测试代码

import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyTestRunner implements CommandLineRunner {

    @Autowired
    private UserMapper userMapper;

    @Override
    public void run(String... args) throws Exception {
        // 测试插入时自动填充
        User user = new User();
        user.setUsername("John Doe");
        userMapper.insert(user);
        System.out.println("Inserted user: " + user);

        // 测试更新时自动填充
        user.setUsername("Jane Doe");
        userMapper.updateById(user);
        System.out.println("Updated user: " + user);
    }
}

在上面的测试代码中:

  • 插入新用户时,createdAt 和 updatedAt 字段都会被自动填充。
  • 更新用户时,updatedAt 字段会被自动更新。

3. 自动填充策略详解

3.1 自动填充策略选项

@TableField 注解的 fill 属性支持以下自动填充策略:

  • FieldFill.INSERT:仅在插入时自动填充。
  • FieldFill.UPDATE:仅在更新时自动填充。
  • FieldFill.INSERT_UPDATE:在插入和更新时都自动填充。
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updatedAt;

3.2 MetaObjectHandler 方法详解

strictInsertFill:用于插入时自动填充字段,接受 4 个参数:MetaObject、字段名、填充值和字段类型。

this.strictInsertFill(metaObject, "createdAt", LocalDateTime::now, LocalDateTime.class);

strictUpdateFill:用于更新时自动填充字段。

this.strictUpdateFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);

如果不需要区分插入和更新,可以直接使用 setFieldValByName 方法:

this.setFieldValByName("updatedAt", LocalDateTime.now(), metaObject);

3.3 手动触发填充

在某些场景下,可能希望在代码中手动触发自动填充逻辑,可以使用 fillStrategy 方法。

MetaObject metaObject = SystemMetaObject.forObject(user);
this.fillStrategy(metaObject, "updatedAt", LocalDateTime.now());

4. 自动填充的注意事项

4.1 数据库默认值冲突

如果数据库字段设置了默认值,且实体类同时使用了自动填充,可能会导致冲突。解决办法是在数据库中移除默认值,完全依赖 MyBatis-Plus 进行自动填充。

4.2 MetaObjectHandler 必须注册为 Spring Bean

自动填充处理器类 MetaObjectHandler 必须由 Spring 容器管理(即使用 @Component 注解),否则自动填充不会生效。

4.3 覆盖已有值

在插入或更新时,MyBatis-Plus 会自动为标注了 fill 的字段赋值,但如果这些字段已经有值,则 MyBatis-Plus 默认不会覆盖已有值

。要覆盖已有值,可以使用 strictInsertFill 或 strictUpdateFill

5. 常见使用场景

5.1 创建时间和更新时间自动填充

在大多数数据库表中,都会有 created_at 和 updated_at 字段,用于记录数据的创建时间和最后更新时间。通过自动填充功能,MyBatis-Plus 可以轻松实现这两个字段的自动维护。

5.2 操作人自动填充

在操作日志、审计系统等场景下,通常需要记录操作人 ID。可以通过自动填充机制,在插入和更新记录时,自动获取当前用户 ID 并填充到表中。

@Override
public void insertFill(MetaObject metaObject) {
    this.strictInsertFill(metaObject, "operatorId", () -> getCurrentUserId(), Long.class);
}

6. 总结

MyBatis-Plus 的自动填充功能能够极大地简化开发工作,通过简单的注解和配置即可实现插入、更新时的字段自动填充,减少了手动维护重复字段的代码量。

  • @TableField(fill = ...):用于指定字段的自动填充策略,支持插入、更新和插入更新。
  • MetaObjectHandler:自定义自动填充逻辑的接口,开发者可以通过实现 insertFill 和 updateFill 方法控制填充行为。

到此这篇关于MyBatis-Plus 自动填充的实现示例的文章就介绍到这了,更多相关MyBatis-Plus 自动填充内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • Mybatis复杂查询的实现

    Mybatis复杂查询的实现

    本文主要介绍了Mybatis复杂查询的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-09-09
  • 使用java生成激活码和密钥的方法

    使用java生成激活码和密钥的方法

    本文主要介绍了java生成激活码和密钥的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • Java经典面试题汇总--多线程

    Java经典面试题汇总--多线程

    本篇总结的是Java多线程相关的面试题,后续会持续更新,希望我的分享可以帮助到正在备战面试的实习生或者已经工作的同行,如果发现错误还望大家多多包涵,不吝赐教,谢谢
    2021-06-06
  • Java获取控制台输入的两种方法小结

    Java获取控制台输入的两种方法小结

    这篇文章主要介绍了Java获取控制台输入的两种方法小结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Springboot 接口对接文件及对象的操作方法

    Springboot 接口对接文件及对象的操作方法

    这篇文章主要介绍了Springboot 接口对接文件及对象的操作,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • Java中如何使用正则表达式提取各种类型括号中的内容

    Java中如何使用正则表达式提取各种类型括号中的内容

    最近在工作中遇到一个问题,就是需要一个字符串中每一个中括号里的内容,下面这篇文章主要给大家介绍了关于Java中如何使用正则表达式提取各种类型括号中的内容,需要的朋友可以参考下
    2023-06-06
  • jfinal中stateless模式嵌入shiro验证的实现方式

    jfinal中stateless模式嵌入shiro验证的实现方式

    这篇文章主要介绍了jfinal中stateless模式嵌入shiro验证,今天,我们就来尝试一种通过拦截器来实现的Stateless Jfinal嵌入方式,需要的朋友可以参考下
    2022-06-06
  • 基于Springboot的漫画网站平台设计与实现

    基于Springboot的漫画网站平台设计与实现

    本文将基于Springboot实现开发一个漫画主题的网站,实现一个比漂亮的动漫连载的网站系统,界面设计优雅大方,比较适合做毕业设计和课程设计使用,需要的可以参考一下
    2022-08-08
  • 解决jackson反序列化失败InvalidFormatException:Can not deserialize value of type java.util.Date

    解决jackson反序列化失败InvalidFormatException:Can not dese

    这篇文章主要介绍了解决jackson反序列化失败InvalidFormatException:Can not deserialize value of type java.util.Date问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • java线程的中断和同步问题的实现

    java线程的中断和同步问题的实现

    本文主要介绍了java线程的中断和同步问题的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07

最新评论