Search in sources :

Example 1 with EntityUpdateExtend

use of org.sagacity.sqltoy.model.inner.EntityUpdateExtend in project sagacity-sqltoy by chenrenfei.

the class SqlToyDaoSupport method updateByQuery.

/**
 * @TODO 针对单表对象查询进行更新操作(update和delete 操作filters过滤是无效的,必须是精准的条件参数)
 * @param entityClass
 * @param entityUpdate
 * @update 2021-12-23 支持update table set field=field+1等计算模式
 * @return
 */
protected Long updateByQuery(Class entityClass, EntityUpdate entityUpdate) {
    if (null == entityClass || null == entityUpdate || StringUtil.isBlank(entityUpdate.getInnerModel().where) || StringUtil.isBlank(entityUpdate.getInnerModel().values) || entityUpdate.getInnerModel().updateValues.isEmpty()) {
        throw new IllegalArgumentException("updateByQuery: entityClass、where条件、条件值value、变更值setValues不能为空!");
    }
    EntityUpdateExtend innerModel = entityUpdate.getInnerModel();
    boolean isName = SqlConfigParseUtils.hasNamedParam(innerModel.where);
    Object[] values = innerModel.values;
    String[] paramNames = null;
    String where = innerModel.where;
    int valueSize = (values == null) ? 0 : values.length;
    // 重新通过对象反射获取参数条件的值
    if (isName) {
        if (values.length > 1) {
            throw new IllegalArgumentException("updateByQuery: where条件采用:paramName形式传参,values只能传递单个VO或Map对象!");
        }
        paramNames = SqlConfigParseUtils.getSqlParamsName(where, false);
        values = BeanUtil.reflectBeanToAry(values[0], paramNames);
        // 重新设置值数组的长度
        valueSize = values.length;
    } else {
        if (DialectUtils.getParamsCount(where) != valueSize) {
            throw new IllegalArgumentException("updateByQuery: where语句中的?数量跟对应values 数组长度不一致,请检查!");
        }
    }
    EntityMeta entityMeta = getEntityMeta(entityClass);
    // 处理where 中写的java 字段名称为数据库表字段名称
    where = SqlUtil.convertFieldsToColumns(entityMeta, where);
    StringBuilder sql = new StringBuilder();
    sql.append("update ").append(entityMeta.getSchemaTable(null, null)).append(" set ");
    Entry<String, Object> entry;
    // 对统一更新字段做处理
    IUnifyFieldsHandler unifyHandler = getSqlToyContext().getUnifyFieldsHandler();
    if (unifyHandler != null) {
        Map<String, Object> updateFields = unifyHandler.updateUnifyFields();
        if (updateFields != null && !updateFields.isEmpty()) {
            Iterator<Entry<String, Object>> updateIter = updateFields.entrySet().iterator();
            while (updateIter.hasNext()) {
                entry = updateIter.next();
                // 是数据库表的字段
                if (entityMeta.getColumnName(entry.getKey()) != null) {
                    // 是否已经主动update
                    if (innerModel.updateValues.containsKey(entry.getKey())) {
                        // 判断是否存在强制更新
                        if (unifyHandler.forceUpdateFields() != null && unifyHandler.forceUpdateFields().contains(entry.getKey())) {
                            innerModel.updateValues.put(entry.getKey(), entry.getValue());
                        }
                    } else {
                        innerModel.updateValues.put(entry.getKey(), entry.getValue());
                    }
                }
            }
        }
    }
    Object[] realValues = new Object[innerModel.updateValues.size() + valueSize];
    if (valueSize > 0) {
        System.arraycopy(values, 0, realValues, innerModel.updateValues.size(), valueSize);
    }
    Integer[] paramsTypes = new Integer[realValues.length];
    for (int i = 0; i < paramsTypes.length; i++) {
        paramsTypes[i] = java.sql.Types.OTHER;
    }
    String[] realNames = null;
    if (isName) {
        realNames = new String[realValues.length];
        System.arraycopy(paramNames, 0, realNames, innerModel.updateValues.size(), valueSize);
    }
    int index = 0;
    String columnName;
    FieldMeta fieldMeta;
    Iterator<Entry<String, Object>> iter = innerModel.updateValues.entrySet().iterator();
    String[] fields;
    String fieldSetValue;
    // 设置一个扩展标志,避免set field=field+? 场景构造成field=field+:fieldExtParam跟where
    // field=:field名称冲突
    final String extSign = "ExtParam";
    while (iter.hasNext()) {
        entry = iter.next();
        // 考虑 field=filed+? 模式,分割成2部分
        fields = entry.getKey().split("=");
        fieldMeta = entityMeta.getFieldMeta(fields[0].trim());
        // entry.getKey() 直接是数据库字段名称
        if (fieldMeta == null) {
            // 先通过数据字段名称获得类的属性名称再获取fieldMeta
            fieldMeta = entityMeta.getFieldMeta(entityMeta.getColumnFieldMap().get(fields[0].trim().toLowerCase()));
        }
        columnName = fieldMeta.getColumnName();
        // 设置字段类型
        if (fields.length == 1) {
            paramsTypes[index] = fieldMeta.getType();
        }
        // 保留字处理
        columnName = ReservedWordsUtil.convertWord(columnName, null);
        if (isName) {
            if (fields.length > 1) {
                if (fields[1].contains("?")) {
                    // 拼接扩展字符,避免where后面有同样的参数名称
                    realNames[index] = fieldMeta.getFieldName().concat(extSign);
                } else {
                    realNames[index] = SqlConfigParseUtils.getSqlParamsName(fields[1], true)[0];
                }
            } else {
                realNames[index] = fieldMeta.getFieldName();
            }
        }
        realValues[index] = entry.getValue();
        if (index > 0) {
            sql.append(",");
        }
        if (fields.length == 1) {
            sql.append(columnName).append("=").append(isName ? (":" + fieldMeta.getFieldName()) : "?");
        } else {
            // field=filed+? 类似模式
            fieldSetValue = fields[1];
            sql.append(columnName).append("=");
            if (isName && fieldSetValue.contains("?")) {
                fieldSetValue = fieldSetValue.replace("?", ":" + fieldMeta.getFieldName().concat(extSign));
            }
            fieldSetValue = SqlUtil.convertFieldsToColumns(entityMeta, fieldSetValue);
            sql.append(fieldSetValue);
        }
        index++;
    }
    sql.append(" where ").append(where);
    String sqlStr = sql.toString();
    SqlToyConfig sqlToyConfig = sqlToyContext.getSqlToyConfig(sqlStr, SqlType.update, getDialect(innerModel.dataSource));
    QueryExecutor queryExecutor = new QueryExecutor(sqlStr).names(realNames).values(realValues);
    setEntitySharding(queryExecutor, entityMeta);
    return dialectFactory.executeSql(sqlToyContext, sqlToyConfig, queryExecutor, paramsTypes, null, getDataSource(innerModel.dataSource, sqlToyConfig));
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) FieldMeta(org.sagacity.sqltoy.config.model.FieldMeta) EntityUpdateExtend(org.sagacity.sqltoy.model.inner.EntityUpdateExtend) IUnifyFieldsHandler(org.sagacity.sqltoy.plugins.IUnifyFieldsHandler) Entry(java.util.Map.Entry) ParallQueryExecutor(org.sagacity.sqltoy.dialect.executor.ParallQueryExecutor) QueryExecutor(org.sagacity.sqltoy.model.QueryExecutor)

Aggregations

Entry (java.util.Map.Entry)1 EntityMeta (org.sagacity.sqltoy.config.model.EntityMeta)1 FieldMeta (org.sagacity.sqltoy.config.model.FieldMeta)1 SqlToyConfig (org.sagacity.sqltoy.config.model.SqlToyConfig)1 ParallQueryExecutor (org.sagacity.sqltoy.dialect.executor.ParallQueryExecutor)1 QueryExecutor (org.sagacity.sqltoy.model.QueryExecutor)1 EntityUpdateExtend (org.sagacity.sqltoy.model.inner.EntityUpdateExtend)1 IUnifyFieldsHandler (org.sagacity.sqltoy.plugins.IUnifyFieldsHandler)1