Springboot +mybatis-plus 实现公共字段自动填充

2023-11-19

本文讲述了在SpringBoot 中使用Mybatis Plus如何实现一个自动填充功能。

一、应用场景

平时在建数据表的时候都会有创建时间、创建者、修改时间和修改者这四个字段,对于这些大部分表都有的字段,每次在新增和修改的时候都要考虑到这几个字段有没有传进去,很麻烦。mybatisPlus有一个很好的解决方案。也就是公共字段自动填充的功能。

一般满足下面条件的字段就可以使用此功能:
(1)这个字段是大部分表都会有的;
(2)这个字段的值是固定的,或则字段值是可以在后台动态获取的。

阿里巴巴开发手册中也有这样的提示,如果对于这些公共字段可以进行统一处理,不需要每次进行插入或者更新操作的时候 set 一下,就可以提高开发效率,解放双手

自动填充功能的主要使用步骤
(1)新建一个表t_user增加create_time(创建时间)、create_user(创建者)、update_time(修改时间)、update_user(修改者) 等字段。
(2)需要在填充的公共字段上面添加@TableField注解
(3)自定义实现类 MyMetaObjectHandler,重写insertFill、updateFill方法 方法中设置created_time、updated_time等的值

二、代码实现步骤

1.建数据库表 t_user

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `name` varchar(255) DEFAULT NULL COMMENT '名称',
  `age` int(10) DEFAULT NULL COMMENT '年龄',
  `remarks` varchar(255) DEFAULT NULL COMMENT '备注',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `create_user` varchar(255) DEFAULT NULL COMMENT '创建人',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `update_user` varchar(255) DEFAULT NULL COMMENT '更新人',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户信息表';

2.创建spring boot项目集成mybatis-plus实现字段自动填充

2.1 配置pom.xml 和 application.yml

pom.xml配置如下:

 <!--web-->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
 </dependency>

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-test</artifactId>
     <scope>test</scope>
 </dependency>

 <!--热部署-->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-devtools</artifactId>
     <scope>runtime</scope>
     <optional>true</optional>
 </dependency>
 <!--lombok-->
 <dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
     <optional>true</optional>
 </dependency>
 <!--mybatis-plus自动的维护了mybatis以及mybatis-spring的依赖,
 在springboot中这三者不能同时的出现,避免版本的冲突,表示:跳进过这个坑-->
 <!--mybatis-plus-->
 <dependency>
     <groupId>com.baomidou</groupId>
     <artifactId>mybatis-plus-boot-starter</artifactId>
     <version>3.4.3</version>
 </dependency>
 <!--mysql驱动-->
 <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <scope>runtime</scope>
 </dependency>
 <!-- alibaba的druid数据库连接池 -->
 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid</artifactId>
     <version>1.1.20</version>
 </dependency>

 <!-- alibaba的druid数据库连接池 -->
 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid-spring-boot-starter</artifactId>
     <version>1.1.20</version>
 </dependency>

application.yml(若没有,则在src/main/resources/下面新建此文件):


# 服务端口
server:
  port: 8083

# 数据源配置
spring:
  datasource:
    name: test
    url: jdbc:mysql://localhost:3306/db_user?&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSl=false
    username: root
    password:
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

    ## 配置连接池信息
    ## 初始化大小,最小,最大
    initialSize: 5
    minIdle: 5
    maxActive: 30
    ## 配置获取连接等待超时的时间
    maxWait: 60000
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

    # 超过时间限制是否回收
    removeAbandoned: true
    # 超时时间;单位为秒。180秒=3分钟
    removeAbandonedTimeout: 180
    # 关闭abanded连接时输出错误日志
    logAbandoned: true

# mybatis-plus 默认扫描mapper.xml的目录
mybatis-plus:
  mapper-locations: classpath*:/mapper/*.xml
  #配置sql打印日志
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


2.2 编写User实体,添加填充注解

创建一个实体类,然后在需要自动填充的属性上加注解 @TableField(fill = FieldFill.INSERT)@TableField(fill = FieldFill.INSERT_UPDATE) 等注解。

package com.example.autofilldemo.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;

/**
 * @author qzz
 */
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_user")
public class User implements Serializable {

    private  static final long serialVersionUID = 1L;

    /**
     * 用户id
     */
    @TableId(value="id", type = IdType.AUTO)
    private Integer id;
    /**
     * 名称
     */
    @TableField("name")
    private String name;

    /**
     * 年龄
     */
    @TableField("age")
    private Integer age;

    /**
     * 备注
     */
    @TableField("remarks")
    private String remarks;

    /**
     * 创建者
     */
    @TableField(value = "create_user", fill = FieldFill.INSERT)
    private String create_user;

    /**
     * 创建时间
     */
    @TableField(value = "create_time", fill = FieldFill.INSERT)

    private Date create_time;

    /**
     * 修改时间
     */
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private Date update_time;

    /**
     * 修改者id
     */
    @TableField(value = "update_user", fill = FieldFill.INSERT_UPDATE)
    private String update_user;
}

其中 fill 属性为字段自动填充策略,可选的参数如下所示:
在这里插入图片描述

2.3 创建一个UserMapper

package com.example.autofilldemo.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.autofilldemo.entity.User;
import org.springframework.stereotype.Repository;

/**
 * @author qzz
 */
@Repository
public interface UserMapper extends BaseMapper<User> {
}

2.4 自定义公共字段填充处理器

创建自定义实现类MyMetaObjectHandler 实现 MetaObjectHandler 接口,重写insertFill和updateFill方法

注意:
MyBatis Plus 版本不同,实现方式可能会有些许不同,在 3.3.0以上版本是实现 MetaObjectHandler接口低版本可能是继承 MetaObjectHandler 抽象类,来实现对应的方法。

下面为实现插入和更新数据的字段填充逻辑,在插入对象时,对创建时间 create_time和修改时间 update_time自动填充为当前时间,创建者update_user、修改者update_user字段自动填充为当前用户id,在更新对象时,将修改时间 update_time修改为最新时间,修改者为当前用户id。

package com.example.autofilldemo.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;

/**
 * 配置mybatis-plus自动填充类
 * @author qzz
 */
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
     * 插入填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ......");

        this.fillStrategy(metaObject,"create_time", new Date());
        this.fillStrategy(metaObject,"update_time", new Date());

        this.setFieldValByName("create_user",getCurrentUserId(),metaObject);
        this.setFieldValByName("update_user",getCurrentUserId(),metaObject);

        log.info("end insert fill ......");
    }

    /**
     * 修改填充
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ......");
        this.fillStrategy(metaObject,"update_time", new Date());
        this.fillStrategy(metaObject,"update_user", getCurrentUserId());

        log.info("end update fill ......");
    }

    /**
     * 获取当前用户id
     * @return
     */
    private String getCurrentUserId() {
        return "1";
    }
}

其中,默认填充策略为默认有值不覆盖,如果提供的值为 null 也不填充。

2.5 创建UserController,编写方法测试字段自动填充

编写用户添加和编辑方法,检验是否在插入和更新操作时,是否会自动填充响应的字段。

package com.example.autofilldemo.controller;

import com.example.autofilldemo.dao.UserMapper;
import com.example.autofilldemo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;

/**
 * @author qzz
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserMapper userMapper;

    /**
     * 添加用户信息
     */
    @PostMapping("add")
    public Map<String,Object> addProduct(@RequestBody User user){
        Map<String,Object> result = new HashMap<>();
        int n = userMapper.insert(user);
        if(n>0){
            result.put("code","200");
            result.put("id",user.getId());
        }else{
            result.put("code","400");
            result.put("msg","添加用户失败");
        }
        return result;
    }

    /**
     * 编辑商品信息
     */
    @PostMapping("update")
    public Map<String,Object> updateProduct(@RequestBody User user){
        Map<String,Object> result = new HashMap<>();
        int n = userMapper.updateById(user);
        if(n>0){
            result.put("code","200");
        }else{
            result.put("code","400");
            result.put("msg","编辑用户失败");
        }
        return result;
    }
}

三、测试

启动项目,借助postman工具,测试:
(1)添加一个用户信息到数据库,可以看到并没有设置create_time、update_time、create_user和update_user,但程序会自动填充到数据库:

在这里插入图片描述
控制台打印信息:
在这里插入图片描述
数据库表数据结果:
在这里插入图片描述
在这里插入图片描述
说明用户新增时,创建时间、创建者、修改时间和修改者自动填充成功!

(2)编辑一个用户信息,同样可以看下update_time和update_user自动填充到数据库:

在这里插入图片描述
控制台打印信息如下:
在这里插入图片描述
查看数据库表数据信息:
在这里插入图片描述
用户更新时,修改时间和修改者自动填充成功!

四、扩展

1.编写BaseEntity公共字段封装类

另外,可以将公共字段封装到公共类中,比如BaseEntity,其他的实体类可以继承这个公共类,达到代码复用,减少冗余的效果:

package com.example.autofilldemo.entity;

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

import java.util.Date;

/**
 * 公共字段
 * @author qzz
 */
@Data
public class BaseEntity {

    /**
     * 创建者
     */
    @TableField(value = "create_user", fill = FieldFill.INSERT)
    private String create_user;

    /**
     * 创建时间
     */
    @TableField(value = "create_time", fill = FieldFill.INSERT)

    private Date create_time;

    /**
     * 修改时间
     */
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private Date update_time;

    /**
     * 修改者id
     */
    @TableField(value = "update_user", fill = FieldFill.INSERT_UPDATE)
    private String update_user;
}

2.修改User实体类

package com.example.autofilldemo.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;

/**
 * @author qzz
 */
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_user")
public class User extends BaseEntity implements Serializable{

    private  static final long serialVersionUID = 1L;

    /**
     * 用户id
     */
    @TableId(value="id", type = IdType.AUTO)
    private Integer id;
    /**
     * 名称
     */
    @TableField("name")
    private String name;

    /**
     * 年龄
     */
    @TableField("age")
    private Integer age;

    /**
     * 备注
     */
    @TableField("remarks")
    private String remarks;

}

3.测试

postman中请求编辑用户接口,结果如下:
在这里插入图片描述
控制台打印信息:
在这里插入图片描述
数据库表数据:
在这里插入图片描述
经过上面的测试,说明公共字段的自动填充是可以的。

五、总结

本文的完整代码可点击下载https://github.com/katie1221/mybatis-plus-demo目录下的auto-fill-demo

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Springboot +mybatis-plus 实现公共字段自动填充 的相关文章

随机推荐

  • 电力行业数字孪生技术应用白皮书(2022)

    白皮书从产学研用多视角出发 结合电力行业的特性 分析阐述了数字孪生概念 核心技术 应用价值以及数字孪生电网标准体系 从数字感知 混合建模 高效仿真 可视化和虚实迭代等不同方面介绍了数字孪生的支撑技术以及应用现状 梳理了当前电力行业数字孪生技
  • C规范编辑笔记(四)

    往期文章 C规范编辑笔记 一 C规范编辑笔记 二 C规范编辑笔记 三 正文 大家好 今天来给大家分享一下C规范编辑笔记第四篇 距离我们C规范编辑笔记第三篇也快过去了一个月 这次继续分享一波 1 以大写形式声明常量 为避免误解 常量值必须根据
  • 信号完整性分析基础知识之传输线和反射(一):阻抗变化引起反射

    阻抗不连续引起的反射和失真可能会导致信号的误触发和误码 这是导致信号失真和质量下降的主要原因 在某些情况下 这看起来像振铃 当信号电平下降时 下冲会影响噪声预算并导致误触发 或者 在下降信号上 峰值可能会上升到低位阈值以上并导致误触发 下图
  • 基于遗传算法(GA)优化高斯过程回归(GA-GPR)的数据回归预测,matlab代码,多变量输入模型。评价指标包括:R2、MAE、MSE、RMSE和MAPE等,代码质量极高,方便学习和替换数据。

    清空环境变量 warning off 关闭报警信息 close all 关闭开启的图窗 clear 清空变量 clc 清空命令行 restoredefaultpath 导入数据 P train xlsread data training s
  • pymongo "ServerSelectionTimeoutError: No servers found yet" 错误的解决

    系统转移过程中 擅自把aptitude安装的mongoengine换成了pip安装 系统启动以后 报这个错误 报错提示 File usr local lib python2 7 dist packages pymongo mongo cli
  • 安装黑苹果双系统专辑贴(持续更新...)

    最近终于开始研究黑苹果 然后浏览了几篇文章贴收集一下 以便需要时随时阅览 和同学们互相学习 零基础篇 1 https blog csdn net a792396951 article details 80230946 2 https zhu
  • eNSP实验一(DHCP服务器)

    实验要求 四个电脑自动获取IP Client可以通过域名访问dhcp服务器 实验步骤及结果 第一步 1 打开eNSP软件 新建拓扑 搭建好所有设备 构建一个简单的局域网 第二步 启动所有设备 第三步 规划IP地址 第四步 点击路由器进入配置
  • 空指针异常:trim(),isEmpty()造成

    Trim 对空的再使用会报空指针异常 空字符串是 会创建一个对象 内容是 有内存空间 而null 不会创建对象 没有内存空间 长度为0 这时候再用isEmpty 的会报 空指针异常 尽量使用 null if role getId null
  • 性能测试知多少

    目录 1 性能测试基本理论 1 1 性能测试概念 1 1 1 什么是性能 1 1 2 什么是性能测试 1 2 性能测试基本内容 1 2 1 性能测试 1 2 2 负载测试 1 2 3 压力测试 1 2 4 稳定性测试 1 3 性能测试常用名
  • 二叉树的各种操作函数

    include source h 满与空的问题 计算个数时 判断rear和front的大小1 2 空一个 void InitQueue Queue u u front 0 u rear 0 int sizeQue Queue u int s
  • 测试中常说的持续集成是什么?有什么好处?

    一 持续集成流程 正式接收开发转过来的包之前 先从 svn 上下载代码 给它做次静态代码检查 然后编译打包 可以在开发的服务器或者自己的服务器运行单元测试文件 单元测试后 没用什么大的 bug 再部署到测试环境中 测试环境部署完成后先做冒烟
  • 15 个高级 Java 多线程面试题及回答

    在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分 如果你想获得任何股票投资银行的前台资讯职位 那么你应该准备很多关于多线程的问题 在投资银行业务中多线程和并发是一个非常受欢迎的话题 特别是电子交易发展方面相关的 他们会问面试
  • 【新手基础】-域内域信息搜集

    查看当前权限 Whomai 本地普通用户 win 2008 user 本地管理员用户 win7 x64 test administrator 域内用户 hacker administrator 获取域id sid 域id是唯一id Whoa
  • 数据仓库进阶 《阿里大数据之路》第二篇 数据模型篇 (完整版)

    第8章 大数据领域建模综述 此文章为学习笔记 有兴趣的小伙伴可以根据以下指引获取更多 学习内容链接如下 视频 一起啃书 阿里大数据之路数据仓库建模基础理论研读 已完结 哔哩哔哩 bilibili 书籍 阿里大数据之路 8 1 为什么需要数据
  • 【C/C++】浮点数的比较

    本文为 C C 学习总结 讲解浮点数的比较 浮点数经过大量运算后会损失精度 对比较操作带来较大困扰 因为 C 中的 操作需要完全相同时才能判定为 true 我们引入一个极小数 eps 修正误差 比较运算符 若一个数 a 落在 b eps b
  • 网络环境下促进有效学习发生的策略

    1 构建良好的网络学习环境 学习者在网络中的学习 必须在一定的 适合学习的环境中进行 构建和谐和 宽松的学习环境是激发学习者有效学习的前提 在这样的环境中 应该有学习者学 习所需要的一些网络资源 如各种教学网站 电子期刊等 也需要有一定的认
  • nginx之proxy_pass代理后端https请求

    本文转载自 https my oschina net foreverich blog 1517128 前言本文解释了怎么对nginx和后端服务器组或代理服务器进行加密http通信 内容提纲前提条件获取SSL服务端证书获取SSL客户端证书配置
  • MySQL Error Code: 2013. Lost connection to MySQL server during query解决

    如果你出现了这个问题 先尝试判断你是哪种情况 你的SQL语句需要执行很久 超过默认的时长 gt 方案1 你的SQL语句很简单 但就是执行不了 gt 方案2 解决方法1 尝试打开设置调整超时时间后重试 解决方法2 如果你在尝试修改空表都发生了
  • 2. Java枚举(enum)

    Java枚举是一个特殊的类 一般表示一组常量 使用enum关键字来定义 各个常量使用逗号 来分割 实例 public enum BizErrorInfo USER NOT FOUND codeValue 1004 message 用户不存在
  • Springboot +mybatis-plus 实现公共字段自动填充

    本文讲述了在SpringBoot 中使用Mybatis Plus如何实现一个自动填充功能 目录 一 应用场景 二 代码实现步骤 1 建数据库表 t user 2 创建spring boot项目集成mybatis plus实现字段自动填充 2