当前位置: 首页 > article >正文

【实现案例】应用层面基于 MyBatis-Plus 实现数据表记录创建和修改时间自动同步

需求描述

实际开发过程中,很多时候数据表结构是不方便修改的。
任何良好的数据表设计都应包含 主键id 、创建时间gmt_create 以及 修改时间gmt_midofied 这三个字段。
其中,主键应当是自增的无符号大整型,而另外两个时间相关的字段,应当是基于实际的记录创建和修改时间自动同步的日期时间类型。
在系统中集成了 Mybatis-Plus 的情况下,我们可以通过设置主键的自增策略来完成主键的自动更新。
本文要介绍的是,如何实现创建时间gmt_create 以及 修改时间gmt_midofied 这两个字段,根据实际系统中的操作自动同步的功能。

技术选型

这里列举实现过程中用到的相关技术,及其对应的版本:

  • JDK 17
  • Spring Boot 3.4.1
  • Lombok 1.18.36(可选,用于简化实现)
  • Mybatis-Plus 3.5.9
  • MySQL 8.0
    以下给出相关配置的 XML 文件,要注意 MySQL 驱动与选用的数据库版本对应,Mybatis-Plus 要引入适应于 Spring Boot 版本的依赖。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.4.1</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.grobsr</groupId>
	<artifactId>learning</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>learning</name>
	<description>learning</description>
	<url/>
	<licenses>
		<license/>
	</licenses>
	<developers>
		<developer/>
	</developers>
	<scm>
		<connection/>
		<developerConnection/>
		<tag/>
		<url/>
	</scm>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>

		<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
		<dependency>
			<groupId>com.mysql</groupId>
			<artifactId>mysql-connector-j</artifactId>
			<version>8.0.33</version>
		</dependency>

		<!-- 注意这里的 artifactId 是 mybatis-plus-spring-boot3-starter -->
		<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-spring-boot3-starter -->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
			<version>3.5.9</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.36</version>
			<scope>provided</scope>
		</dependency>

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

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

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

相关配置

建议显式地指定应用名称,这样在作为微服务被调用时也许可以避免一些不必要的麻烦。
基本的数据库相关配置是必不可少的,还需要额外配置驼峰和下划线命名的自动映射。
开启 Mybatis-Plus 的日志功能,方便从框架所执行的数据库语句来排查问题。

spring.application.name=learning

spring.datasource.url=jdbc:mysql://[domain / ip]/[table name]?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.datasource.username=[username]
spring.datasource.password=[password]
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.log-impl= org.apache.ibatis.logging.stdout.StdOutImpl

具体实现

测试用数据表

为了简化场景,测试用数据表 entity 仅包含涉及到的三个字段,以下给出建表的脚本。

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for entity
-- ----------------------------
DROP TABLE IF EXISTS `entity`;
CREATE TABLE `entity`  (
  `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
  `gmt_create` datetime NULL DEFAULT NULL COMMENT '记录创建时间',
  `gmt_modified` datetime NULL DEFAULT NULL COMMENT '记录修改时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '实体类 Entity 对应的测试用表' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

测试用实体类

测试用实体类中的属性应与数据表中的字段一一对应,要添加 MyBatis-Plus 的相关注解。

/**
 * 测试用实体类
 * @since 1.0
 * @author Grobsr
 */
@Data
@NoArgsConstructor
@TableName("entity")
public class Entity {
    /**
     * 对应数据表中的主键 id,设置生成策略为自增
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * 对应数据表中的记录创建时间 gmt_create,设置创建时同步填充
     */
    @TableField(fill = FieldFill.INSERT)
    private Date gmtCreate;
    /**
     * 对应数据表中的记录修改时间 gmt_modified,设置更新时同步修改
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date gmtModified;

    public Entity(Long id) {
        this.id = id;
    }
}

测试用 Mapper 接口

@Mapper
public interface EntityMapper extends BaseMapper<Entity> {}

测试用处理类

/**
 * 应用层面基于 MyBatis-Plus 实现数据表记录创建和修改时间自动同步
 * @since 1.0
 * @author Grobsr
 */
@Component
public class TestMetaObjectHandler implements MetaObjectHandler {
    /**
     * 重写的 insertFill 方法,它会在 MyBatis-Plus 新增记录时被触发,填充新增和修改时间。
     * @param metaObject 管理实体类属性的元数据对象
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("gmtCreate", new Date(), metaObject);
        this.setFieldValByName("gmtModified", new Date(), metaObject);
    }

    /**
     * 重写的 updateFill 方法,它会在 MyBatis-Plus 修改记录时被触发,更新修改时间。
     * @param metaObject 管理实体类属性的元数据对象
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("gmtModified", new Date(), metaObject);
    }
}

测试类

@SpringBootTest
class LearningApplicationTests {
	@Autowired
	EntityMapper entityMapper;

	@Test
	void testInsert() {
		entityMapper.insert(new Entity());
	}

	@Test
	void testUpdate() {
		entityMapper.updateById(new Entity(1L));
	}
}

步骤总结

  1. 搭建 MyBatis-Plus 的整体框架,用注解 @TableName("[table name]") 做好实体映射,创建好对应的 Mapper 接口。
  2. 在实体类的主键字段上添加主键标记并设置生成策略 @TableId(type = IdType.AUTO),在需要自动填充的字段上设置同步时机 @TableField(fill = [FieldFill.INSERT / FieldFill.UPDATE / FieldFill.INSERT_UPDATE])
  3. 创建处理类并实现 MetaObjectHandler 接口,完成具体的更新操作。

http://www.kler.cn/a/503067.html

相关文章:

  • 初识JVM HotSopt 的发展历程
  • 欧拉路径算法
  • ffmpeg 编译遇到的坑
  • Python使用socket实现简易的http服务
  • Redis :redis的大Key问题
  • Apache Hop从入门到精通 第二课 Apache Hop 核心概念/术语
  • java项目之网上点餐系统源码(springboot+mysql+vue)
  • Git 的引用规格(refspec)语法
  • 调用Kimi的API接口使用,对话,json化,产品化
  • 3D扫描建模有哪些优势和劣势?
  • 开发指南090-使用python做微服务
  • centos systemd方式配置jar开机自启
  • 数据结构:栈(Stack)和队列(Queue)—面试题(二)
  • ssh2-sftp-client和ssh2配合使用js脚本快速部署项目到服务器
  • 力扣264. 丑数 II
  • 后端接口获取的对象包含图片,渲染后端图片,拼接地址渲染,循环列表,vue+uniapp
  • Visual Studio Code (VSCode)为当前项目设置保存时自动格式化
  • 禅道 ip 地址变换后的修改
  • 有限元分析学习——Anasys Workbanch第一阶段笔记(11)横梁中点挠度仿真结果与计算结果对比
  • 罗德与施瓦茨ZN-Z135,26.5G经济型网络分析仪校准套件
  • CSS语言的语法
  • iOS - runtime总结
  • Github 2025-01-13 开源项目周报 Top15
  • 【图像去噪】论文精读:High-Quality Self-Supervised Deep Image Denoising(HQ-SSL)
  • MyBatis 性能优化
  • c++自定义String