<返回更多

SpringBoot整合MybatisPlus数据自动填充

2022-03-18    死牛胖子
加入收藏

SpringBoot 集成 MyBatisPlus 系列

SpringBoot 版本:2.6.4
MybatisPlus 版本:3.5.1


SpringBoot整合MybatisPlus数据自动填充

 

在真实的项目里,表结构中一般会存在一些公司内部约定的公共字段,比如:创建时间,创建人,修改时间,修改人等,记录这些数据一方面可以出现问题时进行溯源,也可以提供给大数据收集。

不管怎样,这是目前大部分公司选择的方案。

通常公司的框架会有一个上下文对象,存储了当前登录人信息,每次新增或者修改数据库记录,可以从上下文中获取当前登录人信息,填充创建时间,创建人这些信息。但如果每次都需要手动去写这些业务无关的内容,重复且繁琐,而且还容易出错。

需求分析

假设增加 createTime、createUser、updateTime、updateUser 四个字段用来记录创建时间,创建人,修改时间,修改人信息。

准备工作

使用 MySQL 数据库,设计一张 user 表。

数据库脚本

CREATE TABLE user (
    `id` BIGINT(20) NOT NULL COMMENT '主键',
    `name` VARCHAR(32) NOT NULL COMMENT '姓名',
    `age` SMALLINT(4) NOT NULL DEFAULT '0' COMMENT '年龄',
    `email` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '邮箱',
    `create_time` DATETIME NOT NULL COMMENT '创建时间',
    `create_user` VARCHAR(32) NOT NULL COMMENT '创建人',
    `update_time` DATETIME NOT NULL COMMENT '最近更新时间',
    `update_user` VARCHAR(32) NOT NULL COMMENT '最近更新人',
    PRIMARY KEY (id)
)
SpringBoot整合MybatisPlus数据自动填充

 

整合 MybatisPlus 实现自动填充

第一步:设置 @TableField 注解的 FieldFill 属性

其实每个字段都默认设置了一个 @TableField,所以 MybatisPlus 实体类中的字段都必须与数据库表中的字段对应,可以少,但不能多,多出来的字段必须设置 @TableField(exist = false)。

@TableField 注解中还有一个属性 fill,就是用于支持自动填充功能,可选择的值有四个

根据本次的需求,为 createTime、createUser、updateTime、updateUser 四个字段分别添加自动填充策略

@Data
public class User {
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT)
    private String createUser;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String updateUser;
}

第二步:实现 MetaObjectHandler 接口

通过第一步,设置好的填充的时机,但具体该填充什么值,则需要实现 MetaObjectHandler 接口(为了简化,这里处理人姓名写死了,正常可以通过上下文进行获取)。

这个类需要注册到 Spring 容器中

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    // 新增时填充
    @Override
    public void insertFill(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now();
        this.strictInsertFill(metaObject, "createTime", () -> now, LocalDateTime.class);
        this.strictInsertFill(metaObject, "createUser", () -> "haha", String.class);
        this.strictInsertFill(metaObject, "updateTime", () -> now, LocalDateTime.class);
        this.strictInsertFill(metaObject, "updateUser", () -> "haha", String.class);
    }
    // 修改时填充
    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
        this.strictUpdateFill(metaObject, "updateUser", () -> "haha", String.class);
    }
}

MetaObjectHandler 中声明填充的字段,如果实体类中有,则会进行填充,如果没有,也可以正常运行,填充动作被忽略

测试

编写测试用例

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class MybatisPlusTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert() {
        User user = new User();
        user.setId(10);
        user.setUsername("test");
        userMapper.insert(user);
    }
}

查看日志输出如下,deleted 查询条件已自动加上

==>  Preparing: INSERT INTO user (id, name, create_time, create_user, update_time, update_user) VALUES ( ?, ?, ?, ?, ?, ? )
==>  Parameters: 10(Long), test(String), 2022-03-11T20:32:31.532(LocalDateTime), haha(String), 2022-03-11T20:32:31.532(LocalDateTime), haha(String)
<==  Updates: 1

修改的测试用例请自行编写

总结

自动填充主要用途还是将一些与业务无关的字段,使用公共代码进行填充,减少业务处理时还要兼顾非业务字段,让业务代码更纯粹。

MybatisPlus 支持的逻辑删除功能,新增时需要对逻辑删除标记字段填充一个默认值,也可以使用自动填充功能进行填充。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>