Mybatis-Plus字段策略FieldStrategy实战:从配置到避坑指南

张开发
2026/4/22 15:36:43 15 分钟阅读
Mybatis-Plus字段策略FieldStrategy实战:从配置到避坑指南
1. Mybatis-Plus字段策略FieldStrategy入门指南第一次接触Mybatis-Plus的FieldStrategy时我完全被它搞晕了。明明设置了字段值更新时却莫名其妙被忽略想保留某些字段不更新结果全被覆盖了。后来才发现这都是因为没搞懂FieldStrategy的运作机制。FieldStrategy本质上就是控制字段在SQL操作中行为的规则集。它决定了新增记录时如何处理空值字段更新操作时哪些字段应该被包含构建查询条件时是否包含空值字段举个例子用户表有个备注字段业务上允许为空。如果使用默认的NOT_NULL策略当备注为空时这个字段既不会出现在INSERT语句中也不会作为查询条件。这往往就是新手容易踩的第一个坑。2. 五种字段策略深度解析2.1 IGNORED策略最宽容的模式我在用户信息补全功能中就吃过IGNORED的亏。当时有个需求是允许用户清空昵称代码是这样的TableField(updateStrategy FieldStrategy.IGNORED) private String nickname;测试时发现即使用户只修改了头像没有提交昵称字段数据库里的昵称也被更新为NULL了。这就是IGNORED的特点完全信任前端传值不管是不是null都会拼接到SQL中。适用场景需要显式设置字段为NULL的场合字段值可能被清空的业务场景第三方接口对接时字段可能缺失的情况2.2 NOT_NULL策略默认的保守派这是Mybatis-Plus的默认策略也是我推荐大部分字段使用的策略。它的行为很明确字段值为null时不参与SQL操作。// 等同于默认配置 TableField(updateStrategy FieldStrategy.NOT_NULL) private String mobile;最近在开发电商系统时商品价格字段就用了这个策略。这样当运营人员只更新商品描述时价格字段不会被意外覆盖为null。2.3 NOT_EMPTY策略字符串专属卫士这个策略专治各种空字符串问题。我们系统有个用户地址管理功能最初用的NOT_NULL策略结果发现用户输入 这样的空格也能通过验证。改成NOT_EMPTY后完美解决TableField(insertStrategy FieldStrategy.NOT_EMPTY) private String address;注意它只对String类型有效对Integer等类型无效。源码里其实有判断if (fieldStrategy NOT_EMPTY !CharSequence.class.isAssignableFrom(fieldType)) { fieldStrategy NOT_NULL; }2.4 NEVER策略字段保护神财务系统的金额字段最适合用这个策略。一旦设置TableField(updateStrategy FieldStrategy.NEVER) private BigDecimal amount;就算你给amount赋值执行update时也会被无视。我在权限系统里也常用它来保护createTime等系统字段。2.5 DEFAULT策略随大流的选择这个策略比较有意思它就像个墙头草完全跟着全局配置走。比如你在application.yml里配置了mybatis-plus: global-config: db-config: update-strategy: not_empty那么所有标注TableField(updateStrategy FieldStrategy.DEFAULT)的字段都会采用NOT_EMPTY策略。3. 全局配置与字段级配置的博弈3.1 全局配置一劳永逸的方案我习惯在项目启动时先设置全局策略mybatis-plus: global-config: db-config: insert-strategy: not_null update-strategy: not_null where-strategy: not_empty这样能确保整个项目有统一的行为模式。特别是where-strategy设为NOT_EMPTY后查询时空字符串会自动被过滤省去很多判空代码。3.2 字段级配置特殊情况特殊处理但总有例外情况。比如我们有个需求要支持按空字符串查询TableField(whereStrategy FieldStrategy.IGNORED) private String searchKey;这时候字段级配置就派上用场了。我的经验法则是80%的字段用全局策略20%的特殊字段单独配置。3.3 配置优先级陷阱这里有个大坑字段注解的优先级高于全局配置。有次我全局配了NOT_EMPTY但某个字段注解写了NOT_NULL调试了半天才发现问题。现在我的做法是在启动日志打印生效的字段策略对特殊配置的字段添加详细注释团队统一约定配置规范4. 实战中的经典坑位实录4.1 乐观锁字段的更新谜题我们在使用Version乐观锁时遇到过这样的问题Version TableField(updateStrategy FieldStrategy.NEVER) private Integer version;本意是防止手动修改version结果发现乐观锁完全失效了。原来Mybatis-Plus内部处理乐观锁时会依赖字段更新策略。解决方案是改用NOT_NULL策略配合权限控制。4.2 动态表名与字段策略的冲突在使用动态表名功能时发现字段策略有时不生效。原因是动态表名处理过程中会重建SQL这时需要确保TableNameHandler和FieldStrategy的配置顺序正确。我们的解决方案是先配置动态表名处理器再初始化字段策略最后添加自定义SQL注入器4.3 逻辑删除的特殊处理逻辑删除字段deleted比较特殊我们是这样配置的TableLogic TableField(whereStrategy FieldStrategy.NOT_NULL) private Integer deleted;必须确保whereStrategy不是IGNORED否则查询会包含已删除数据。但insertStrategy可以设为IGNORED方便初始化数据。5. 性能优化与最佳实践5.1 批量操作时的策略优化处理批量插入时发现NOT_NULL策略会导致大量判空逻辑。我们的优化方案是// 批量插入专用实体 public class UserBatchInsert { TableField(insertStrategy FieldStrategy.IGNORED) private String optionalField; TableField(insertStrategy FieldStrategy.NOT_NULL) private String requiredField; }5.2 查询条件构建技巧对于复杂的条件查询我们开发了策略组合模式Getter Setter public class UserQuery { TableField(whereStrategy FieldStrategy.NOT_EMPTY) private String name; TableField(whereStrategy FieldStrategy.IGNORED) private Integer ageRange; // 自定义条件处理器 public QueryWrapperUser toWrapper() { // 特殊处理逻辑 } }5.3 监控与调优建议我们在生产环境添加了策略使用监控记录各策略类型的调用频率监控策略导致的SQL差异对高频使用的策略进行缓存优化关键指标包括策略判断耗时条件构建成功率空值过滤比例经过这些优化后我们的用户服务接口响应时间降低了30%。特别是在高峰期字段策略的合理配置显著降低了数据库压力。

更多文章