记一次开发中遇到的坑...
在某次使用 mapper.update(entity, wrapper)
方法的时候,入参给了个 entity
进去,但是没有得到对应的查询结果。这个问题导致更新操作未能按照预期进行,影响了后续业务逻辑的正确执行。
在开发过程中,通常会使用 MyBatis Plus 提供的 CRUD 操作来简化数据访问层的代码。其中,mapper.update(entity, wrapper)
方法是常用的更新操作,entity
用于承载需要更新的数据,wrapper
用于构建查询条件。按照预期,传入 entity
和 wrapper
后,数据库应该根据 wrapper
的条件找到相应的记录,并用 entity
中的数据进行更新。
首先,检查了 entity
和 wrapper
的值是否正确。在调试过程中,发现 entity
中包含了需要更新的字段及其新值,wrapper
也构建了相应的查询条件。表面上看,一切正常。接着,怀疑是否是 wrapper
构建的问题。于是,单独对 wrapper
进行了测试,发现查询条件确实能匹配到数据库中的记录。这进一步排除了 wrapper
本身的问题。为了进一步确认问题,在 update
方法前后加了日志输出,确认 entity
和 wrapper
在进入 update
方法时的状态。日志显示,这两者在进入 update
方法时的数据都是正确的。进一步深入,发现问题的根源在于 MyBatis Plus 的 UpdateWrapper
的使用上。UpdateWrapper
是一个用于构建 SQL 更新语句的工具类,不仅可以用于条件查询,还可以用于设置更新的字段。这个问题出现的原因是 UpdateWrapper
在某些情况下会覆盖 entity
中的字段值,导致实际更新的字段与预期不符。在代码中,wrapper
的构建过程中包含了一些设置更新字段的操作,这些操作覆盖了 entity
中的字段值(实体类的优先级低于 wrapper.set),导致更新操作没有按照预期进行。
为了避免这个问题,需要明确区分查询条件和更新字段的设置。在使用 mapper.update(entity, wrapper)
方法时,应确保 wrapper
仅用于构建查询条件,而不包含任何更新字段的设置。具体修改如下:
// 构建查询条件 UpdateWrapper<Entity> wrapper = new UpdateWrapper<>(); wrapper.eq("id", entity.getId()); // 只构建查询条件,不设置更新字段 // 设置更新字段 Entity updateEntity = new Entity(); updateEntity.setField1(entity.getField1()); updateEntity.setField2(entity.getField2()); // 其他需要更新的字段 // 执行更新操作 mapper.update(updateEntity, wrapper);
通过上述修改,wrapper
仅用于构建查询条件,而 updateEntity
负责承载需要更新的字段值,确保更新操作能够按照预期进行。
明确职责:在使用 UpdateWrapper
时,应明确其职责,只用于构建查询条件或设置更新字段,避免混用。
详细调试:通过日志和调试工具,详细检查每一步的数据状态,确保问题定位准确。
深入研究:了解所使用框架和工具的底层实现原理,避免误用和滥用。