确认

  • [x] 我的版本是最新版本, 我的版本号与 version 相同, 并且项目里无依赖冲突
  • [x] 我已经在 issue 中搜索过, 确认问题没有被提出过
  • [x] 我已经修改标题, 将标题中的 描述 替换为遇到的问题

功能改进

我使用InsertBatchSomeColumn把程序将[null]替换成[default],数据库会将[default]换成[默认值],然后 但是我实现的MetaObjectHandler一个类在insertFill方法中将创建人设置当前登陆人,却设置不成功了

参考资料

No response

Comment From: miemieYaho

给出你的复现demo

Comment From: wang-deyin

  1. 重写的InsertBatchSomeColumn类: public class InsertBatchSomeColumn extends AbstractMethod { private Predicate predicate;

    public InsertBatchSomeColumn() { super("insertBatchSomeColumn"); }

    public InsertBatchSomeColumn(Predicate predicate) { super("insertBatchSomeColumn"); this.predicate = predicate; }

    public InsertBatchSomeColumn(String name, Predicate predicate) { super(name); this.predicate = predicate; }

    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) { KeyGenerator keyGenerator = NoKeyGenerator.INSTANCE; SqlMethod sqlMethod = SqlMethod.INSERT_ONE; List fieldList = tableInfo.getFieldList(); String insertSqlColumn = tableInfo.getKeyInsertSqlColumn(true, false) + this.filterTableFieldInfo(fieldList, this.predicate, TableFieldInfo::getInsertSqlColumn, ""); String columnScript = "(" + insertSqlColumn.substring(0, insertSqlColumn.length() - 1) + ")"; String insertSqlProperty = tableInfo.getKeyInsertSqlProperty(true, "et.", false) + this.filterTableFieldInfo(fieldList, this.predicate, (i) -> { return i.getInsertSqlProperty("et."); }, ""); insertSqlProperty = "(" + insertSqlProperty.substring(0, insertSqlProperty.length() - 1) + ")"; String valuesScript = SqlScriptUtils.convertForeach(insertSqlProperty, "list", (String)null, "et", ","); String keyProperty = null; String keyColumn = null; if (tableInfo.havePK()) { if (tableInfo.getIdType() == IdType.AUTO) { keyGenerator = Jdbc3KeyGenerator.INSTANCE; keyProperty = tableInfo.getKeyProperty(); keyColumn = tableInfo.getKeyColumn(); } else if (null != tableInfo.getKeySequence()) { keyGenerator = TableInfoHelper.genKeyGenerator(this.methodName, tableInfo, this.builderAssistant); keyProperty = tableInfo.getKeyProperty(); keyColumn = tableInfo.getKeyColumn(); } }

    String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), columnScript, valuesScript);
    SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
    return this.addInsertMappedStatement(mapperClass, modelClass, this.getMethod(sqlMethod), sqlSource, (KeyGenerator)keyGenerator, keyProperty, keyColumn);
    

    }

    public InsertBatchSomeColumn setPredicate(final Predicate predicate) { this.predicate = predicate; return this; }

    private String getInsertSqlProperty(TableFieldInfo tableFieldInfo,final String prefix) { String newPrefix = prefix == null ? "" : prefix; String elPart = SqlScriptUtils.safeParam(newPrefix + tableFieldInfo.getEl()); //属性为空时使用默认值 String result = SqlScriptUtils.convertIf(elPart, String.format("%s != null", newPrefix + tableFieldInfo.getEl()),false) + SqlScriptUtils.convertIf("default", String.format("%s == null", newPrefix + tableFieldInfo.getEl()),false); return result + ","; } }

  2. 设置的HaiCloudMetaObjectHandler @Component public class HaiCloudMetaObjectHandler implements MetaObjectHandler {

    @Override public void insertFill(MetaObject metaObject) { if (metaObject.hasSetter("createBy")) { this.strictInsertFill(metaObject, "createBy", SecurityUtils::getStringUserId, String.class); this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); } } }

Comment From: miemieYaho

SecurityUtils.getTenantId()你这个是有request才有值吧?那你说你失效的时候有request吗?

Comment From: wang-deyin

SecurityUtils.getTenantId()你这个是有request才有值吧?那你说你失效的时候有request吗?

肯定有的,我使用原生的InsertBatchSomeColumn,是可以成功赋值MetaObjectHandler里面的内容的, 但是我重写InsertBatchSomeColumn之后,加上以下方法,能成功赋值MySQL设置的默认值,但是无法赋值MetaObjectHandler里面的内容

private String getInsertSqlProperty(TableFieldInfo tableFieldInfo,final String prefix) { String newPrefix = prefix == null ? "" : prefix; String elPart = SqlScriptUtils.safeParam(newPrefix + tableFieldInfo.getEl()); //属性为空时使用默认值 String result = SqlScriptUtils.convertIf(elPart, String.format("%s != null", newPrefix + tableFieldInfo.getEl()),false) + SqlScriptUtils.convertIf("default", String.format("%s == null", newPrefix + tableFieldInfo.getEl()),false); return result + ","; }

Comment From: wang-deyin

我将创建人和创建时间都设置成常量也赋值不上

Comment From: miemieYaho

那你写个复现demo出来看看吧,git形式的

Comment From: wang-deyin

那等我写一个吧

Comment From: wang-deyin

demo已写:https://github.com/wang-deyin/mybatis-plus-demo

Comment From: wang-deyin

测试可见demo的TestController#batch方法

Comment From: miemieYaho

不生效是因为ognl在填充之前,if判断都走完了之后生成好sql了才走的填充

Comment From: wang-deyin

有什么解决方案吗

Comment From: miemieYaho

没有,必填项要么你就设置default,要么你就直接et.xx取值,二选一