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));
}
Aggregations