mybatis-plus
mybatis-plus copied to clipboard
逻辑删除行为未对齐
当前使用版本(必填,否则不予处理)
3.5.2
该问题是如何引起的?(确定最新版也有问题再提!!!)
DeleteById 和其他的 Delete 方法在逻辑删除时行为不一致
下图是 DeleteById 的逻辑,在进行逻辑删除时,会获取当前实体类中其他需要 updateFill 的字段,一并更新掉
下图是 DeleteByMap 的逻辑,在进行逻辑删除时,未获取当前实体类中需要 updateFill 的字段,只更新了逻辑删除字段
下图是 DeleteBatchByIds 的逻辑,在进行逻辑删除时,也未获取当前实体类中需要 updateFill 的字段,只更新了逻辑删除字段
下图是 Delete 的逻辑,在进行逻辑删除时,也未获取当前实体类中需要 updateFill 的字段,只更新了逻辑删除字段
期望
希望在进行逻辑删除时,保持逻辑删除的行为一致,当前实现下,DeleteById 会更新其他 updateFill 的字段,其他的逻辑删除并不会更新其他 updateFill的字段,个人觉得,逻辑删除应当只改变逻辑删除字段的值,其他的updateFill 字段可以忽略
附上实体类
@Data
@EqualsAndHashCode(callSuper = true)
public class EntityWithLogicDelete extends Model<EntityWithLogicDelete> {
private static final long serialVersionUID = 8370785759786894056L;
@TableId
private Long id;
@TableField(fill = FieldFill.UPDATE)
private String name;
@TableLogic
private boolean deleted;
}
只识别入参是entity的
感谢及时回复 可是在我测试过程中,发现实际并不是单独只针对入参是 entity 的时候才会进行 fill
entity
@Data
@EqualsAndHashCode(callSuper = true)
public class EntityWithLogicDelete extends BaseEntityWithLogicDelete {
}
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class BaseEntityWithLogicDelete extends BaseEntity {
/**
* 逻辑删除
*/
@TableLogic
@TableField(value = "deleted", select = false)
protected boolean deleted;
/**
* 逻辑删除版本
*/
@TableField(value = "delete_version", select = false)
protected Long deleteVersion;
}
@Data
public class BaseEntity {
/**
* 主键 id
*/
@TableId(value = "id", type = IdType.AUTO)
protected Long id;
/**
* 创建时间
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
protected LocalDateTime createTime;
/**
* 修改时间
*/
@TableField(value = "modify_time", fill = FieldFill.INSERT_UPDATE)
protected LocalDateTime modifyTime;
}
测试类
@RestController
public class EntityController {
@Autowired
private EntityWithLogicDeleteService entityWithLogicDeleteService;
@GetMapping("/entity_with_logic_delete")
public void entityWithLogicDelete() {
EntityWithLogicDelete entity = new EntityWithLogicDelete();
entityWithLogicDeleteService.save(entity);
entityWithLogicDeleteService.removeById(entity.getId());
}
}
打印的日志
2022-08-28 16:11:44.989 DEBUG 2985 c.s.i.m.E.insert : ==> Preparing: INSERT INTO entity_with_logic_delete (deleted, create_time, modify_time ) VALUES ( ?, ?, ? )
2022-08-28 16:11:44.990 DEBUG 2985 c.s.i.m.E.insert : ==> Parameters: false(Boolean), 2022-08-28T16:11:44.976901(LocalDateTime), 2022-08-28T16:11:44.976901(LocalDateTime)
2022-08-28 16:11:44.993 DEBUG 2985 c.s.i.m.E.insert : <== Updates: 1
2022-08-28 16:11:44.998 DEBUG 2985 c.s.i.m.E.deleteById : ==> Preparing: UPDATE entity_with_logic_delete SET modify_time=?, deleted=1 WHERE id=? AND deleted=0
2022-08-28 16:11:44.999 DEBUG 2985 c.s.i.m.E.deleteById : ==> Parameters: 2022-08-28T16:11:44.995834(LocalDateTime), 34(Long)
2022-08-28 16:11:45.001 DEBUG 2985 c.s.i.m.E.deleteById : <== Updates: 1
附上截图

service的removeById做了特殊处理,只要看看源码就明白的事
难道是我描述的不够清楚吗? 我知道是DeteteById做了特殊处理,整个讨论的过程,我一直的疑问都是为什么DeteteById要做特殊处理,而且这个feature处理默认还是启用的。 我的第一次提问就是说行为不一致的问题,希望可以保持行为的一致 我的第二次提问也是针对你的回答进行的测试,并没有像你说的那样,只对入参为Entity的进行fill,无论传入的是否是Entity,只要开启了逻辑删除,并且有字段开启了fill,就都会转为Entity进行fill
你截图是mapper的,然后你测试又是service的,那你觉得怎么才能在mapper层行为一致?
我第一次截图是 mapper 的,确实按你这么说也没错,对于直接调用 mapper 层来说是一致的 可是现在的应用程序有多少是直接调用 mapper 的呢,一般都会对外提供一个 service 调用 mapper 问题就出在 service 层,在 removeById(id) 的时候多了一个判断(如果表开启了逻辑删除,并且有字段是需要 updateFill) 当条件满足时,会自动将 removeById(id)的调用改为removeById(entity) removeById(entity)经过 mapper时,发现传入的不是简单类型,就会进行填充,同时也印证了你的回复https://github.com/baomidou/mybatis-plus/issues/4781#issuecomment-1229400953 最终导致了在 service 层行为的不一致
我第一次截图是 mapper 的,确实按你这么说也没错,对于直接调用 mapper 层来说是一致的 可是现在的应用程序有多少是直接调用 mapper 的呢,一般都会对外提供一个 service 调用 mapper 问题就出在 service 层,在 removeById(id) 的时候多了一个判断(如果表开启了逻辑删除,并且有字段是需要 updateFill) 当条件满足时,会自动将 removeById(id)的调用改为removeById(entity) removeById(entity)经过 mapper时,发现传入的不是简单类型,就会进行填充,同时也印证了你的回复#4781 (comment) 最终导致了在 service 层行为的不一致
你想说的是,期望: 逻辑删除( 只更新逻辑删除字段 ),不需要更新你设置了 updateFill
的普通字段是吧 ??
我觉得你的描述太多了,反而偏离了主体 。
感谢反馈问题,后面会追踪解决
我记得就是这么改的, 很多用户要求删除的时候更新其他信息。
我也踩到这个坑了,改用IService下的removeXXX,但是这样没有affectedRow,蛋疼。