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

mybatis-plus-boot-starter:3.4.1 druid-spring-boot-starter:1.2.5 spring-boot-starter-parent:2.4.4

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

实体有几个一次性字段,如code,updateBy等字段,此字段一旦写入后,后面就不再更新。目前根据文档以及源码都未找到合适的设置,注解@TableField虽然有updateStrategy()策略,但判断依据还是有没有值,从而导致要实现此需求要么在更新前手动设置为NULL,要么自己写SQL。

如果手动设置为NULL肯定比较麻烦,而且容易忘记。同样的道理,如果是自己写SQL语句,那就完全失去使用mybatis-plus初衷了。

还请大神指点一二,谢谢!

Comment From: cngdlcl

改写Update和UpdateById方法如下: protected String sqlSet(boolean logic, boolean ew, TableInfo table, boolean judgeAliasNull, final String alias, final String prefix) { String sqlScript = getAllSqlSet(table, logic, prefix); if (judgeAliasNull) { sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", alias), true); } if (ew) { sqlScript += NEWLINE; sqlScript += SqlScriptUtils.convertIf(SqlScriptUtils.unSafeParam(U_WRAPPER_SQL_SET), String.format("%s != null and %s != null", WRAPPER, U_WRAPPER_SQL_SET), false); } sqlScript = SqlScriptUtils.convertSet(sqlScript); return sqlScript; }

protected String getAllSqlSet(TableInfo table, boolean ignoreLogicDelFiled, final String prefix) { final String newPrefix = prefix == null ? EMPTY : prefix; return table.getFieldList().stream() .filter(i -> { //此次增加更新条件判断 final boolean ignoreUpdateField = i.getUpdateStrategy().equals(FieldStrategy.IGNORED) || i .getUpdateStrategy().equals(FieldStrategy.NEVER); if(ignoreUpdateField){ return false; } if (ignoreLogicDelFiled) { return !(table.isWithLogicDelete() && i.isLogicDelete()); } return true; }).map(i -> i.getSqlSet(newPrefix)).filter(Objects::nonNull).collect(joining(NEWLINE)); } }

Comment From: cngdlcl

修复TableInfo判断逻辑如下: /* * 获取所有的 sql set 片段 * * @param ignoreLogicDelFiled 是否过滤掉逻辑删除字段 * @param prefix 前缀 * @return sql 脚本片段 / public String getAllSqlSet(boolean ignoreLogicDelFiled, final String prefix) { final String newPrefix = prefix == null ? EMPTY : prefix; return fieldList.stream() .filter(i -> { //此次增加更新条件判断 final boolean ignoreUpdateField = i.getUpdateStrategy().equals(FieldStrategy.IGNORED) || i .getUpdateStrategy().equals(FieldStrategy.NEVER); if(ignoreUpdateField){ return false; } if (ignoreLogicDelFiled) { return !(isWithLogicDelete() && i.isLogicDelete()); } return true; }).map(i -> i.getSqlSet(newPrefix)).filter(Objects::nonNull).collect(joining(NEWLINE)); }

Comment From: zoujun8666

改写Update和UpdateById方法如下: protected String sqlSet(boolean logic, boolean ew, TableInfo table, boolean judgeAliasNull, final String alias, final String prefix) { String sqlScript = getAllSqlSet(table, logic, prefix); if (judgeAliasNull) { sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", alias), true); } if (ew) { sqlScript += NEWLINE; sqlScript += SqlScriptUtils.convertIf(SqlScriptUtils.unSafeParam(U_WRAPPER_SQL_SET), String.format("%s != null and %s != null", WRAPPER, U_WRAPPER_SQL_SET), false); } sqlScript = SqlScriptUtils.convertSet(sqlScript); return sqlScript; }

protected String getAllSqlSet(TableInfo table, boolean ignoreLogicDelFiled, final String prefix) { final String newPrefix = prefix == null ? EMPTY : prefix; return table.getFieldList().stream() .filter(i -> { //此次增加更新条件判断 final boolean ignoreUpdateField = i.getUpdateStrategy().equals(FieldStrategy.IGNORED) || i .getUpdateStrategy().equals(FieldStrategy.NEVER); if(ignoreUpdateField){ return false; } if (ignoreLogicDelFiled) { return !(table.isWithLogicDelete() && i.isLogicDelete()); } return true; }).map(i -> i.getSqlSet(newPrefix)).filter(Objects::nonNull).collect(joining(NEWLINE)); } }

必须得改源码?那以后就不能升级了?

Comment From: cngdlcl

不然你等社区给你修复啰,你不急是可以慢慢等。

Comment From: 986510453

给字段加上@TableFiled(updateStrategy = FieldStrategy.NEVER)即可。 MyBatis-Plus 更新时无法指定忽略的列

Comment From: huayanYu

@zoujun8666 请问设置Never是否能解决你问题

Comment From: zoujun8666

@zoujun8666 请问设置Never是否能解决你问题

参考@986510453的方式:

给字段加上@TableFiled(updateStrategy = FieldStrategy.NEVER)即可。

简单的测试了,目前是可以的。

Comment From: zoujun8666

给字段加上@TableFiled(updateStrategy = FieldStrategy.NEVER)即可。 MyBatis-Plus 更新时无法指定忽略的列

3QU,测试符合我需求,再次感谢。

Comment From: AnLiBoBo

@TableFiled(updateStrategy = FieldStrategy.NEVER) 设置后 使用 UpdateWrapper 手动设置值好像还是可以更新这个字段的