mybatis-plus icon indicating copy to clipboard operation
mybatis-plus copied to clipboard

逻辑删除注解@TableLogic,如何实现记录删除时间,删除人信息

Open kisshexuxia opened this issue 4 years ago • 9 comments
trafficstars

当前使用版本(必填,否则不予处理)

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.2</version>
    </dependency>

该问题是如何引起的?(确定最新版也有问题再提!!!)

实现逻辑删除注解@TableLogic,生产环境想记录删除时间,删除人信息。注解@TableField(fill = FieldFill.UPDATE)没有效果,我开始以为逻辑删除也是做的修改,但是实际MetaObjectHandler里面没进来。 搜索了Issues里,也看见了差不多的提问,其中有解答用BaseMapper中的: https://github.com/baomidou/mybatis-plus/issues/3754

int deleteById(Serializable id);
int deleteByMap(@Param("cm") Map<String, Object> columnMap);
int delete(@Param("ew") Wrapper<T> queryWrapper);
int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);

但是我试用的 IService 中的removeByIds方法 default boolean removeByIds(Collection<? extends Serializable> idList) { return CollectionUtils.isEmpty(idList) ? false : SqlHelper.retBool(this.getBaseMapper().deleteBatchIds(idList)); } 实际也是用的deleteBatchIds方法。

重现步骤(如果有就写完整)

报错信息

kisshexuxia avatar Oct 28 '21 05:10 kisshexuxia

最新版用 deleteById(your entity)

miemieYaho avatar Oct 28 '21 06:10 miemieYaho

最新版用 deleteById(your entity)

那批量删除呢?

reixuemin avatar Nov 02 '21 07:11 reixuemin

插个眼,有没有大佬解决的,这个东西很困扰哦,总不能每次remove之前都去update一下吧

syherry avatar Nov 04 '21 06:11 syherry

我认为逻辑删除的目的就是为了保留数据的变化,如果不走自动填充更新时间与人员信息,那岂不是最后一次的变化看不见了? 希望作者能尽快改善或者给我们一个方案实现,谢谢

For-Every avatar Nov 23 '21 06:11 For-Every

现在的逻辑是只有更具主键删除,和更新修改时间,想修改更新人似乎还是不可以,希望可以有这个功能

aptexd avatar Dec 02 '21 03:12 aptexd

#4179

nieqiurong avatar Dec 27 '21 08:12 nieqiurong

#4179

@nieqiurong

这个调整是完善逻辑删除触发 fill 功能,但是目前在 MetaObjectHandler 还是无法区分出是逻辑删除触发的 fill 还是普通更新触发的 fill

hocgin avatar Jan 01 '22 08:01 hocgin

#4179

@nieqiurong

这个调整是完善逻辑删除触发 fill 功能,但是目前在 MetaObjectHandler 还是无法区分出是逻辑删除触发的 fill 还是普通更新触发的 fill

逻辑删除因为是update操作,所以在mybatis层面是无法根据SqlCommandType来区分是普通更新还是逻辑删除的,如果需要记录删除人这种字段,只能自行扩展处理了,两个不合理的方案,改变逻辑删除注入的MappedStatement为SqlCommandType,等同于在xml的里面写update的更新语句,第二种就是根据MappedStatement的id来单独处理填充逻辑。 其次,看自身业务情况把,是否需要单独记录删除人这样,执行删除操作了,最后的更新人和更新时间也等于最终删除人和删除时间了。

nieqiurong avatar Jan 05 '22 07:01 nieqiurong

这个看了相关的源码SqlCommandType无法区分逻辑删除,在执行填充的时候是根据SqlCommandType的值来进行相关填充的调用都调用的是update填充

sea158246forset avatar Feb 28 '22 17:02 sea158246forset

#4179

@nieqiurong 这个调整是完善逻辑删除触发 fill 功能,但是目前在 MetaObjectHandler 还是无法区分出是逻辑删除触发的 fill 还是普通更新触发的 fill

逻辑删除因为是update操作,所以在mybatis层面是无法根据SqlCommandType来区分是普通更新还是逻辑删除的,如果需要记录删除人这种字段,只能自行扩展处理了,两个不合理的方案,改变逻辑删除注入的MappedStatement为SqlCommandType,等同于在xml的里面写update的更新语句,第二种就是根据MappedStatement的id来单独处理填充逻辑。 其次,看自身业务情况把,是否需要单独记录删除人这样,执行删除操作了,最后的更新人和更新时间也等于最终删除人和删除时间了。

当前逻辑删除 service 层做了部分填充回写支持,更多个性需求请自己实现

qmdx avatar Dec 29 '22 02:12 qmdx

我看了一下MybatisParameterHandler,我觉得加一个解析就可以判断是否逻辑删除 try { var deletedField = tableInfo.getLogicDeleteFieldInfo().getColumn(); var statement = (Update) CCJSqlParserUtil.parse(boundSql.getSql()); var sets = statement.getUpdateSets(); var logicDelete = sets.stream().anyMatch(m -> m.getColumns().stream().anyMatch(c -> c.getColumnName().equalsIgnoreCase(deletedField))); if (!logicDelete) { updateFill(metaObject, tableInfo); } else { removeFill(metaObject, tableInfo); } } catch (JSQLParserException e) { throw new RuntimeException(e); }

xcore-fun avatar Dec 26 '23 07:12 xcore-fun