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

3.5.2

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

DeleteById 使用逻辑删除功能,导致删除某记录时执行updateById把逻辑删除字段更新为删除状态,如果其它字段有注解@TableField(fill = FieldFill.INSERT_UPDATE)或者@TableField(fill = FieldFill.UPDATE)则不论该字段是否为NULL或者EMPTY都会更新该字段

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

看DeleteById源码就知道问题所在,在injectMappedStatement之中扫描所有字段,只要TableFieldInfo::isWithUpdateFill返回true,则会对该字段进行更新,并且更新过程之中没有根据字段值动态生成sql,应该添加类似于 <if test="fieldValue != null"> </if> 的判断

public class DeleteById extends AbstractMethod {
    public DeleteById() {
        super("deleteById");
    }

    /**
     * @param name 方法名
     * @since 3.5.0
     */
    public DeleteById(String name) {
        super(name);
    }

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        String sql;
        SqlMethod sqlMethod = SqlMethod.LOGIC_DELETE_BY_ID;
        if (tableInfo.isWithLogicDelete()) {
            List<TableFieldInfo> fieldInfos = tableInfo.getFieldList().stream()
                .filter(TableFieldInfo::isWithUpdateFill) // 获取所有自动更新填充字段
                .filter(f -> !f.isLogicDelete())
                .collect(toList());
            if (CollectionUtils.isNotEmpty(fieldInfos)) {
                String sqlSet = "SET " + SqlScriptUtils.convertIf(fieldInfos.stream()
                    .map(i -> i.getSqlSet(EMPTY)).collect(joining(EMPTY)), "!@org.apache.ibatis.type.SimpleTypeRegistry@isSimpleType(_parameter.getClass())", true)
                    + tableInfo.getLogicDeleteSql(false, false);
                sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), sqlSet, tableInfo.getKeyColumn(),
                    tableInfo.getKeyProperty(), tableInfo.getLogicDeleteSql(true, true));
            } else {
                sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), sqlLogicSet(tableInfo),
                    tableInfo.getKeyColumn(), tableInfo.getKeyProperty(),
                    tableInfo.getLogicDeleteSql(true, true));
            }
            SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Object.class);
            return addUpdateMappedStatement(mapperClass, modelClass, getMethod(sqlMethod), sqlSource);
        } else {
            sqlMethod = SqlMethod.DELETE_BY_ID;
            sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), tableInfo.getKeyColumn(),
                tableInfo.getKeyProperty());
            SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Object.class);
            return this.addDeleteMappedStatement(mapperClass, getMethod(sqlMethod), sqlSource);
        }
    }
}

字段信息如下: MyBatis-Plus DeleteById 使用逻辑删除功能,会更新其它字段值

最后生成的SQL为 <script> UPDATE sys_role SET <if test="!@org.apache.ibatis.type.SimpleTypeRegistry@isSimpleType(_parameter.getClass())"> first_letter=#{firstLetter}, </if>del_flag=1 WHERE role_id=#{roleId} AND del_flag=0 </script> MyBatis-Plus DeleteById 使用逻辑删除功能,会更新其它字段值

报错信息

Comment From: miemieYaho

你DeleteById的入参是什么

Comment From: lucky-xin

你DeleteById的入参是什么

你说DeleteById除了id还有其它入参吗???

Comment From: miemieYaho

你的入参类型不在这里面? MyBatis-Plus DeleteById 使用逻辑删除功能,会更新其它字段值

Comment From: lucky-xin

你的入参类型不在这里面? MyBatis-Plus DeleteById 使用逻辑删除功能,会更新其它字段值

主键类型是Integer

Comment From: lucky-xin

你的入参类型不在这里面? MyBatis-Plus DeleteById 使用逻辑删除功能,会更新其它字段值

主键类型是Integer 这段代码 <if test="!@org.apache.ibatis.type.SimpleTypeRegistry@isSimpleType(_parameter.getClass())"> first_letter=#{firstLetter},</if> 会判断入参类型是否为

    SIMPLE_TYPE_SET.add(String.class);
    SIMPLE_TYPE_SET.add(Byte.class);
    SIMPLE_TYPE_SET.add(Short.class);
    SIMPLE_TYPE_SET.add(Character.class);
    SIMPLE_TYPE_SET.add(Integer.class);
    SIMPLE_TYPE_SET.add(Long.class);
    SIMPLE_TYPE_SET.add(Float.class);
    SIMPLE_TYPE_SET.add(Double.class);
    SIMPLE_TYPE_SET.add(Boolean.class);
    SIMPLE_TYPE_SET.add(Date.class);
    SIMPLE_TYPE_SET.add(Class.class);
    SIMPLE_TYPE_SET.add(BigInteger.class);
    SIMPLE_TYPE_SET.add(BigDecimal.class);

如果字段类型包含在SIMPLE_TYPE_SET之中,那么该字段就会出现在SET 语句之中,这里就没有根据该字段是否为null或者为空来动态判断了 @miemieYaho

Comment From: miemieYaho

  1. 那段代码是取反
  2. 指定了填充是不会进行判断为null的

Comment From: lucky-xin

  1. 那段代码是取反
  2. 指定了填充是不会进行判断为null的 逻辑删除只需要更新逻辑删除字段吧,最后把其它所有填充字段都更新了,而且不判断字段是否为null

Comment From: miemieYaho

有的人需要填充一些信息