本文主要是介绍MyBatis Plus实现时间字段自动填充的完整方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,...
前言
在日常开发中,我们经常需要记录数据的创建时间和更新时间。传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏。本文将介绍如何使用 MyBATis Plus 的自动填充功能来优雅地解决这个问题。
解决目标
- 创建记录时自动设置
createTime
和updateTime
- 更新记录时自动更新
updateTime
,保持createTime
不变 - 无需手动编写时间设置代码
- 统一的时间管理机制
技术栈
- 框架: Spring Boot + MyBatis Plus
- 数据库: mysql
- 实体管理: JPA 注解 + MyBatis Plus 注解
实现步骤
1. 实体类注解配置
首先在实体类的时间字段上添加 MyBatis Plus 的自动填充注解:
/** * 邮箱服务器实体类 */ @Entity @Table(name = "tbl_email_server") public class EmailServer extends BaseEntity { // 其他字段... /** 创建时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @TableField(fill = FieldFill.INSERT) private Date createTime; /** 更新时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; // getter 和 setter 方法... }
注解说明:
@TableField(fill = FieldFill.INSERT)
: 仅在插入操作时自动填充@TableField(fill = FieldFill.INSERT_UPDATE)
: 在插入和更新操作时都自动填充@JsonFormat
: 指定 JSON 序列化时的日期格式
2. 创建元数据处理器
创建自定义的元数据处理器来实现具体的填充逻辑:
package com.ruoyi.framework.config; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import Java.util.Date; /** * MyBatis Plus 字段自动填充处理器 * * @author ruoyi */ @Component public class MyBatisMetaObjectHandler implements MetaObjectHandler { /** * 插入时的填充策略 */ @Override public void insertFill(MetaObject metaObject) { Date now = new Date(); // 插入时同时填充创建时间和更新时间 this.strictInsertFill(metaObject, "createTime", Date.class, now); this.strictInsertFill(metaObject, "updateTime", Date.class, now); } /** * 更新时的填充策略 */ @Override public void updateFill(MetaObject metaObject) { // 更新时仅填充更新时间 this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); } }
核心方法说明:
insertFill()
: 处理插入操作的字段填充updateFill()
: 处理更新操作的字段填充strictInsertFill()
: 严格插入填充,只有当字段值为 null 时才填充strictUpdateFill()
: 严格更新填充,只有当字段值为 null 时才填充
3. 服务层代码优化
移除原本手动设置时间的代码:
修改前:
@Override public int insertEmailServer(EmailServer emailServer) { // 手动设置时间字段 emailServer.setCreateBy(SecurityUtils.getUsername()); emailServer.setCreateTime(new Date()); // ❌ 需要移除 emailServer.setUpdateTime(new Date()); // ❌ 需要移除 return emailServerMapper.insertEmailServer(emailServer); } @Override public int updateEmailServer(EmailServer emailServer) { emailServer.setUpdateBy(SecurityUtils.getUsername()); emailServer.setUpdateTime(new Date()); // ❌ 需要移除 return emailServerMapper.updateEmailSChina编程erver(emailServer); }
修改后:
@Override public int insertEmailServer(EmailServer emailServer) { // 只设置创建者,时间字段由 MyBatis Plus 自动填充 emailServer.setCreateBy(SecurityUtils.getUsername()); return emailServerMapper.insertEmailServer(emailServer); } @Override public int updateEmailServer(EmailServer emailServer) { // 只设置更新者,更新时间由 MyBatis Plus 自动填充 emailServer.setUpdateBy(SecurityUtils.getUsername()); return emailServerMapper.updateEmailServer(emailServer); }
填充机制详解
创建记录时的填充过程
// 执行插入操作 EmailServer emailServer = new EmailServer(); emailServer.setServerName("SMTP服务器"); /js/ ... 设置其他业务字段 // 调用 insertEmailServer 时,MyBatis Plus 会: // 1. 触发 insertFill 方法 // 2. createTime = 2024-01-15 10:30:25 // 3. updateTime = 2024-01-15 10:30:25 (与创建时间相同)
更新记录时的填充过程
// 执行更新操作 EmailServer emailServer = new EmailServer(); emailServer.setServerId(1L); emailServer.setServerName("新的服务器名称"); // ... 修改其他业务字段 // 调用 updateEmailServer 时,MyBatis Plus 会: // 1. 触发 updateFill 方法 // 2. createTime = 保持原值不变 // 3. updateTime = 2024-01-15 14:25:30 (更新为当前时间)
数据库建议配置
虽然使用了注解自动填充,但建议在数据库层面也设置默认值作为双重保障:
-- 为时间字段添加默认值 ALTER TABLE tbl_email_server MODIFY COLUMN create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'; ALTER TABLE tbl_email_server MODIFY COLUMN update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间';
前后对比
对比项 | 手动设置方式 | 自动填充方式 |
---|---|---|
代码量 | 每个方法都需要设置 | 一次配置,全局生效 |
维护性 | 容易遗漏,难以统一 | 统一管理,不易出错 |
一致性 | 依赖开发者自觉性 | 自动保证一致性 |
性能 | 无额外性能消耗 | 微小的反射开销 |
进阶扩展
1. 支持更多字段类型
@Override public void insertFill(MetaObject metaObject) { Date now = new Date(); // 支持 Date 类型 this.strictInsertFill(metaObject, "createTime", Date.class, now); this.strictInsertFill(metaObject, "updateTime", Date.class, now); // 支持 LocalDateTime 类型 this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 支持时间戳 this.strictInsertFill(metaObject, "createTime", Long.class, System.currentTimeMillis()); }
2. 添加创建者和更新者自动填充
@Override public void insertFill(MetaObject metaObject) { Date now = new Date(); String currentUser = getCurrentUser(); // 获取当前用户 // 时间字段填充 this.strictInsertFill(metaObject, "createTime", Date.class, now); this.strictInsertFill(metaObject, "updateTime", Date.class, now); // 用户字段填充 this.strictInsertFill(metaObject, "createBy", String.class, currentUser); this.strijsctInsertFill(metaObject, "updateBy", String.class, currentUser); } @OverrXcgvqtcehide public void updateFill(MetaObject metaObject) { String currentUser = getCurrentUser(); this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); this.strictUpdateFill(metaObject, "updateBy", String.class, currentUser); } private String getCurrentUser() { try { return SecurityUtils.getUsername(); } catch (Exception e) { return "system"; // 默认用户 } }
常见问题与解决方案
1. 字段没有自动填充
可能原因:
- 实体类字段名与数据库列名不匹配
- 忘记添加
@TableField
注解 - MetaObjectHandler 没有被 Spring 管理
解决方案:
// 确保字段名正确映射 @TableField(value = "create_time", fill = FieldFill.INSERT) private Date createTime; // 确保处理器被 Spring 管理 @Component // 必须添加此注解 public class MyBatisMetaObjectHandler implements MetaObjectHandler { // ... }
2. 更新操作时创建时间被意外修改
解决方案:
// 使用 FieldFill.INSERT 而不是 INSERT_UPDATE @TableField(fill = FieldFill.INSERT) // ✅ 正确 private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) // ✅ 正确 private Date updateTime;
3. JSON 序列化时间格式问题
解决方案:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;
总结
MyBatis Plus 的自动填充功能为我们提供了一个优雅的解决方案来管理时间字段:
优势
- 自动化: 无需手动编写重复的时间设置代码
- 统一性: 全局统一的时间填充策略
- 可靠性: 避免了人为遗漏设置时间的问题
- 扩展性: 可以轻松扩展到其他字段的自动填充
核心实现
- 在实体类时间字段添加
@TableField
注解 - 创建实现
MetaObjectHandler
接口的处理器 - 在处理器中实现
insertFill
和updateFill
方法 - 移除服务层中的手动时间设置代码
这种方案不仅提升了开发效率,还增强了代码的可维护性和一致性。在实际项目中,建议结合数据库默认值设置,形成双重保障机制。
以上就是MyBatis Plus实现时间字段自动填充的完整方案的详细内容,更多关于MyBatis Plus时间字段自动填充的资料请关注China编程(www.chinasem.cn)其它相关文章!
这篇关于MyBatis Plus实现时间字段自动填充的完整方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!