news 2026/2/9 3:27:45

MyBatis-Plus 自动填充推荐使用 strictInsertFill 和 strictUpdateFill(fillStrategy、setFieldValByName)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MyBatis-Plus 自动填充推荐使用 strictInsertFill 和 strictUpdateFill(fillStrategy、setFieldValByName)

MyBatis-Plus 提供的不同填充策略,各有特点和适用场景:

方法对比表

特性strictInsertFill/strictUpdateFillfillStrategysetFieldValByName
版本3.3.0+3.0+3.0+
严格模式✅ 严格类型检查❌ 不检查类型❌ 不检查类型
空值覆盖❌ 已有值不覆盖✅ 空值才填充✅ 总是覆盖
推荐指数⭐⭐⭐⭐⭐ (推荐)⭐⭐⭐⭐⭐⭐

详细对比

1.strictInsertFill/strictUpdateFill(推荐使用)

特点

  • 严格类型检查,避免类型错误

  • 如果字段已有值,不会覆盖(安全)

  • 需要明确指定字段类型

java

@Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { // 严格模式 - 推荐使用 this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); this.strictInsertFill(metaObject, "createBy", String.class, getCurrentUser()); // 如果实体类中已经设置了 createTime,这里不会覆盖 } @Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); this.strictUpdateFill(metaObject, "updateBy", String.class, getCurrentUser()); } }

场景:适合大多数情况,特别是需要类型安全和避免意外覆盖的场景。

2.fillStrategy

特点

  • 宽松模式,不检查类型

  • 只有字段值为 null 时才填充

  • 更灵活但不够安全

java

@Override public void insertFill(MetaObject metaObject) { // 策略模式 - 字段为null时才填充 this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 相当于: // if (metaObject.getValue("createTime") == null) { // metaObject.setValue("createTime", LocalDateTime.now()); // } }

场景:当你确定不会出现类型错误,且希望空值才填充时使用。

3.setFieldValByName(不推荐)

特点

  • 最原始的方法

  • 强制设置,总是覆盖已有值

  • 没有类型检查,容易出错

java

@Override public void insertFill(MetaObject metaObject) { // 强制设置 - 总是覆盖 this.setFieldValByName("createTime", LocalDateTime.now(), metaObject); this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject); // 即使实体类已经设置了 createTime,也会被覆盖! }

场景:基本不需要使用,除非你有特殊需求需要强制覆盖。

实际示例对比

场景:实体类已经设置了值

java

User user = new User(); user.setCreateTime(LocalDateTime.of(2023, 1, 1, 0, 0)); // 手动设置 user.setName("test"); userMapper.insert(user);

不同方法的结果

java

// 1. strictInsertFill - 保护已有值 this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 结果:createTime = 2023-01-01T00:00 (不覆盖) // 2. fillStrategy - 空值才填充 this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 结果:createTime = 2023-01-01T00:00 (不覆盖,因为不是null) // 3. setFieldValByName - 强制覆盖 this.setFieldValByName("createTime", LocalDateTime.now(), metaObject); // 结果:createTime = 当前时间 (强制覆盖)

类型安全对比

java

// 1. strictInsertFill - 编译时检查 this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // ✅ 正确:类型匹配 this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); // ❌ 错误:类型不匹配,但编译可能通过,运行时报错或填充失败 // 2. fillStrategy - 运行时才可能发现错误 this.fillStrategy(metaObject, "createTime", new Date()); // ❌ 危险:类型不匹配,可能运行时出错或数据错误 // 3. setFieldValByName - 同样危险 this.setFieldValByName("createTime", new Date(), metaObject); // ❌ 危险:类型不匹配

性能对比

实际上性能差异很小,但:

  • strictInsertFill有额外的类型检查,略微增加开销

  • fillStrategysetFieldValByName更直接

但这点性能差异可以忽略不计。

最佳实践建议

推荐方案

java

@Component @Slf4j public class AutoFillHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { // 使用严格模式 - 安全第一 this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); this.strictInsertFill(metaObject, "createBy", String.class, getCurrentUser()); this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); this.strictInsertFill(metaObject, "updateBy", String.class, getCurrentUser()); } @Override public void updateFill(MetaObject metaObject) { // 使用严格模式 this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); this.strictUpdateFill(metaObject, "updateBy", String.class, getCurrentUser()); } }

特殊情况处理

java

@Override public void insertFill(MetaObject metaObject) { // 混合使用:严格模式 + 策略模式 // 1. 时间字段用严格模式(避免类型错误) this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 2. 业务字段用策略模式(更灵活) this.fillStrategy(metaObject, "department", getDefaultDepartment()); // 3. 确定需要覆盖的用setField(极少情况) // this.setFieldValByName("systemFlag", "Y", metaObject); }

debug 日志

java

@Override public void insertFill(MetaObject metaObject) { log.debug("开始自动填充插入字段"); try { this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); log.debug("填充 createTime 成功"); } catch (Exception e) { log.warn("填充 createTime 失败,使用策略模式", e); this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); } }

总结

选择说明
90% 场景使用strictInsertFill/strictUpdateFill
灵活场景使用fillStrategy
几乎不用setFieldValByName

简单记忆

  • 安全strictInsertFill

  • 灵活fillStrategy

  • 强制setFieldValByName

在 Spring Boot + MyBatis-Plus 项目中,推荐始终使用strictInsertFillstrictUpdateFill,这是最安全、最现代的做法。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/7 23:24:24

Langchain-Chatchat辅助撰写专利申请文件

基于 Langchain-Chatchat 的专利撰写智能辅助系统实践 在知识产权竞争日益激烈的今天,企业对高质量、高效率的专利申请文件撰写需求愈发迫切。一份优秀的专利说明书不仅需要准确描述技术方案,还要规避已有技术、语言规范严谨,并能经受住审查员…

作者头像 李华
网站建设 2026/2/7 12:46:19

Langchain-Chatchat构建多模态知识库的探索

Langchain-Chatchat构建多模态知识库的探索 在企业数字化转型不断深入的今天,一个普遍而棘手的问题浮出水面:如何让沉睡在成千上万个PDF、Word和TXT文件中的知识真正“活”起来? 这些文档可能是公司制度、技术手册、项目报告或客户合同&#…

作者头像 李华
网站建设 2026/2/7 12:50:26

Vue3 桑基图

效果图&#xff1a;<template><v-chart ref"vChartRef" :option"option"></v-chart></template><script setup lang"ts">import { ref, reactive } from "vue";import VChart from "vue-echarts&q…

作者头像 李华
网站建设 2026/2/6 15:04:10

Langchain-Chatchat连接数据库生成自然语言回答

Langchain-Chatchat连接数据库生成自然语言回答 在企业知识管理日益复杂的今天&#xff0c;一个新员工入职后常常面临这样的问题&#xff1a;“我们公司的年假政策到底是怎么规定的&#xff1f;”“报销流程需要哪些材料&#xff1f;”这些问题看似简单&#xff0c;但在文档分散…

作者头像 李华
网站建设 2026/2/7 1:14:21

玩转VT仿真:从三轴萌新到车铣复合老司机的实战指南

VT笔记&#xff0c;VT仿真笔记&#xff0c;VT教程&#xff0c;原版仿真实战笔记升级版&#xff0c;加入多轴及车铣复合仿真笔记啦加量不加价&#xff08;vericut&#xff09;原版仿真设置实战经验笔记 cimco edit仿真笔记分享&#xff1a;全网唯一超详解析&#xff0c;让你快速…

作者头像 李华