存储过程去除对#{xxx(), varchar} 类型的解析,对于参数类型不区分大小写处理。

This commit is contained in:
jmxd
2023-08-22 10:54:52 +08:00
parent 9507f3b8af
commit d67fd0325a
4 changed files with 85 additions and 172 deletions

View File

@@ -1,48 +1,38 @@
package org.ssssssss.magicapi.modules.db;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.ssssssss.magicapi.core.model.Options;
import org.ssssssss.magicapi.modules.DynamicModule;
import org.ssssssss.magicapi.modules.db.dialect.DialectAdapter;
import org.ssssssss.magicapi.datasource.model.MagicDynamicDataSource;
import org.ssssssss.magicapi.datasource.model.MagicDynamicDataSource.DataSourceNode;
import org.ssssssss.magicapi.core.annotation.MagicModule;
import org.ssssssss.magicapi.core.context.RequestContext;
import org.ssssssss.magicapi.core.context.RequestEntity;
import org.ssssssss.magicapi.core.interceptor.ResultProvider;
import org.ssssssss.magicapi.core.model.Options;
import org.ssssssss.magicapi.datasource.model.MagicDynamicDataSource;
import org.ssssssss.magicapi.datasource.model.MagicDynamicDataSource.DataSourceNode;
import org.ssssssss.magicapi.modules.DynamicModule;
import org.ssssssss.magicapi.modules.db.cache.SqlCache;
import org.ssssssss.magicapi.modules.db.dialect.Dialect;
import org.ssssssss.magicapi.modules.db.dialect.DialectAdapter;
import org.ssssssss.magicapi.modules.db.inteceptor.NamedTableInterceptor;
import org.ssssssss.magicapi.modules.db.inteceptor.SQLInterceptor;
import org.ssssssss.magicapi.modules.db.model.Page;
import org.ssssssss.magicapi.modules.db.model.SqlMode;
import org.ssssssss.magicapi.modules.db.model.SqlTypes;
import org.ssssssss.magicapi.modules.db.model.StoreMode;
import org.ssssssss.magicapi.modules.db.model.StoredParam;
import org.ssssssss.magicapi.modules.db.provider.PageProvider;
import org.ssssssss.magicapi.modules.db.table.NamedTable;
import org.ssssssss.magicapi.core.interceptor.ResultProvider;
import org.ssssssss.magicapi.utils.ScriptManager;
import org.ssssssss.script.MagicScriptContext;
import org.ssssssss.script.annotation.Comment;
import org.ssssssss.script.functions.DynamicAttribute;
import org.ssssssss.script.parsing.GenericTokenParser;
import org.ssssssss.script.parsing.ast.literal.BooleanLiteral;
import org.ssssssss.script.parsing.ast.statement.ClassConverter;
import org.ssssssss.script.reflection.JavaReflection;
import org.ssssssss.script.runtime.RuntimeContext;
import java.beans.Transient;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 数据库查询模块
@@ -53,9 +43,6 @@ import java.util.stream.Stream;
public class SQLModule implements DynamicAttribute<SQLModule, SQLModule>, DynamicModule<SQLModule> {
static {
try {
Field[] fields = Types.class.getFields();
Map<String, Integer> mappings = Stream.of(fields)
.collect(Collectors.toMap(field -> field.getName().toLowerCase(), field -> (Integer) JavaReflection.getFieldValue(Types.class, field)));
ClassConverter.register("sql", (value, params) -> {
if (params == null || params.length == 0) {
return value;
@@ -67,7 +54,7 @@ public class SQLModule implements DynamicAttribute<SQLModule, SQLModule>, Dynami
if (StringUtils.isBlank(target)) {
return value;
}
Integer sqlType = mappings.get(target.toLowerCase());
Integer sqlType = SqlTypes.getSqlType(target);
return sqlType == null ? value : new SqlParameterValue(sqlType, target, value);
});
} catch (Exception ignored) {

View File

@@ -0,0 +1,25 @@
package org.ssssssss.magicapi.modules.db.model;
import org.ssssssss.script.reflection.JavaReflection;
import java.lang.reflect.Field;
import java.sql.Types;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class SqlTypes {
private static final Map<String, Integer> SQL_TYPE_MAPPINGS;
static {
Field[] fields = Types.class.getFields();
SQL_TYPE_MAPPINGS = Stream.of(fields)
.collect(Collectors.toMap(field -> field.getName().toLowerCase(), field -> (Integer) JavaReflection.getFieldValue(Types.class, field)));
}
public static Integer getSqlType(String type){
return SQL_TYPE_MAPPINGS.get(type.toLowerCase());
}
}

View File

@@ -1,12 +1,12 @@
package org.ssssssss.magicapi.modules.db.model;
import java.sql.Types;
import java.util.Objects;
/**
* 过程入参
*/
public class StoredParam {
//参数SQL类型
private Integer type;
@@ -41,83 +41,7 @@ public class StoredParam {
}
public static int paramType(String type){
if (Objects.equals(type, "BIT")) {
return Types.BIT;
} else if (Objects.equals(type, "TINYINT")) {
return Types.TINYINT;
} else if (Objects.equals(type, "SMALLINT")) {
return Types.SMALLINT;
} else if (Objects.equals(type, "INTEGER")) {
return Types.INTEGER;
} else if (Objects.equals(type, "BIGINT")) {
return Types.BIGINT;
} else if (Objects.equals(type, "FLOAT")) {
return Types.FLOAT;
} else if (Objects.equals(type, "REAL")) {
return Types.REAL;
} else if (Objects.equals(type, "NUMERIC")) {
return Types.NUMERIC;
} else if (Objects.equals(type, "DECIMAL")) {
return Types.DECIMAL;
} else if (Objects.equals(type, "CHAR")) {
return Types.CHAR;
} else if (Objects.equals(type, "VARCHAR")) {
return Types.VARCHAR;
} else if (Objects.equals(type, "LONGVARCHAR")) {
return Types.LONGVARCHAR;
} else if (Objects.equals(type, "DATE")) {
return Types.DATE;
} else if (Objects.equals(type, "TIME")) {
return Types.TIME;
} else if (Objects.equals(type, "TIMESTAMP")) {
return Types.TIMESTAMP;
} else if (Objects.equals(type, "BINARY")) {
return Types.BINARY;
} else if (Objects.equals(type, "VARBINARY")) {
return Types.VARBINARY;
} else if (Objects.equals(type, "LONGVARBINARY")) {
return Types.LONGVARBINARY;
} else if (Objects.equals(type, "NULL")) {
return Types.NULL;
} else if (Objects.equals(type, "OTHER")) {
return Types.OTHER;
} else if (Objects.equals(type, "JAVA_OBJECT")) {
return Types.JAVA_OBJECT;
} else if (Objects.equals(type, "DISTINCT")) {
return Types.DISTINCT;
} else if (Objects.equals(type, "STRUCT")) {
return Types.STRUCT;
} else if (Objects.equals(type, "ARRAY")) {
return Types.ARRAY;
} else if (Objects.equals(type, "BLOB")) {
return Types.BLOB;
} else if (Objects.equals(type, "CLOB")) {
return Types.CLOB;
} else if (Objects.equals(type, "REF")) {
return Types.REF;
} else if (Objects.equals(type, "DATALINK")) {
return Types.DATALINK;
} else if (Objects.equals(type, "BOOLEAN")) {
return Types.BOOLEAN;
} else if (Objects.equals(type, "ROWID")) {
return Types.ROWID;
} else if (Objects.equals(type, "NCHAR")) {
return Types.NCHAR;
} else if (Objects.equals(type, "NVARCHAR")) {
return Types.NVARCHAR;
} else if (Objects.equals(type, "LONGNVARCHAR")) {
return Types.LONGNVARCHAR;
} else if (Objects.equals(type, "NCLOB")) {
return Types.NCLOB;
} else if (Objects.equals(type, "SQLXML")) {
return Types.SQLXML;
} else if (Objects.equals(type, "REF_CURSOR")) {
return Types.REF_CURSOR;
} else if (Objects.equals(type, "TIME_WITH_TIMEZONE")) {
return Types.TIME_WITH_TIMEZONE;
} else if (Objects.equals(type, "TIMESTAMP_WITH_TIMEZONE")) {
return Types.TIMESTAMP_WITH_TIMEZONE;
}
return Types.NULL;
Integer sqlType = SqlTypes.getSqlType(type);
return sqlType == null ? Types.NULL : sqlType;
}
}

View File

@@ -35,15 +35,13 @@ public class TextSqlNode extends SqlNode {
private static final GenericTokenParser OUT_PARAM_TOKEN_PARSER = new GenericTokenParser("@{", ",", true);
private static final GenericTokenParser OUT_TOKEN_PARSER = new GenericTokenParser("@{", "}", true);
private static final GenericTokenParser OUT_TOKEN_PARSER = new GenericTokenParser("@{", "}", true);
private static final GenericTokenParser TYPE_TOKEN_PARSER = new GenericTokenParser(",", "}", true);
private static final GenericTokenParser TYPE_TOKEN_PARSER = new GenericTokenParser(",", "}", true);
private static final GenericTokenParser INOUT_TOKEN_PARSER = new GenericTokenParser("@{", "(", true);
private static final GenericTokenParser INOUT_TOKEN_PARSER = new GenericTokenParser("@{", "(", true);
private static final GenericTokenParser IN_PARAM_TOKEN_PARSER = new GenericTokenParser("#{", ",", true);
private static final GenericTokenParser PARAM_TOKEN_PARSER = new GenericTokenParser("(", ")", true);
private static final GenericTokenParser PARAM_TOKEN_PARSER = new GenericTokenParser("(", ")", true);
/**
* SQL
@@ -55,7 +53,7 @@ public class TextSqlNode extends SqlNode {
}
public static String parseSql(String sql, Map<String, Object> varMap, List<Object> parameters) {
SQLModule.params = new ArrayList<>();
SQLModule.params = new ArrayList<>();
// 处理?{}参数
sql = IF_TOKEN_PARSER.parse(sql.trim(), text -> {
AtomicBoolean ifTrue = new AtomicBoolean(false);
@@ -69,72 +67,51 @@ public class TextSqlNode extends SqlNode {
sql = CONCAT_TOKEN_PARSER.parse(sql, text -> String.valueOf(ScriptManager.executeExpression(text, varMap)));
// 处理#{}参数
sql = REPLACE_TOKEN_PARSER.parse(sql, text -> {
StoredParam storedParam = new StoredParam();
if (text.indexOf(",") > 0) {
IN_PARAM_TOKEN_PARSER.parse("#{" + text, param -> {
PARAM_TOKEN_PARSER.parse(param,variable -> {
Object value = ScriptManager.executeExpression(variable, varMap);
storedParam.setValue(value);
storedParam.setInOut(StoreMode.IN);
TYPE_TOKEN_PARSER.parse(text + "}", type -> {
storedParam.setType(StoredParam.paramType(type));
SQLModule.params.add(new SqlParameter(param, StoredParam.paramType(type)));
return null;
});
parameters.add(storedParam);
return null;
});
return null;
});
return "?";
} else {
Object value = ScriptManager.executeExpression(text, varMap);
if (value == null) {
parameters.add(null);
return "?";
}
try {
//对集合自动展开
List<Object> objects = StreamExtension.arrayLikeToList(value);
parameters.addAll(objects);
return IntStream.range(0, objects.size()).mapToObj(t -> "?").collect(Collectors.joining(","));
} catch (Exception e) {
parameters.add(value);
return "?";
}
}
Object value = ScriptManager.executeExpression(text, varMap);
if (value == null) {
parameters.add(null);
return "?";
}
try {
//对集合自动展开
List<Object> objects = StreamExtension.arrayLikeToList(value);
parameters.addAll(objects);
return IntStream.range(0, objects.size()).mapToObj(t -> "?").collect(Collectors.joining(","));
} catch (Exception e) {
parameters.add(value);
return "?";
}
});
sql = OUT_TOKEN_PARSER.parse(sql, text -> {
StoredParam storedParam = new StoredParam();
String val = OUT_PARAM_TOKEN_PARSER.parse("@{" + text, param -> {
TYPE_TOKEN_PARSER.parse(text + "}", type -> {
if (param.indexOf("(") > 0) {
PARAM_TOKEN_PARSER.parse(param, variable -> {
Object value = ScriptManager.executeExpression(variable, varMap);
storedParam.setValue(value);
storedParam.setInOut(StoreMode.INOUT);
storedParam.setType(StoredParam.paramType(type));
return null;
});
INOUT_TOKEN_PARSER.parse("@{" + param, inoutParam -> {
SQLModule.params.add(new SqlInOutParameter(inoutParam, StoredParam.paramType(type)));
return null;
});
} else {
Object value = ScriptManager.executeExpression(param, varMap);
storedParam.setValue(value);
storedParam.setInOut(StoreMode.OUT);
storedParam.setType(StoredParam.paramType(type));
SQLModule.params.add(new SqlOutParameter(param, StoredParam.paramType(type)));
}
return null;
});
parameters.add(storedParam);
return null;
});
return "?";
});
sql = OUT_TOKEN_PARSER.parse(sql,text -> {
StoredParam storedParam = new StoredParam();
String val = OUT_PARAM_TOKEN_PARSER.parse("@{" + text, param -> {
TYPE_TOKEN_PARSER.parse(text + "}", type -> {
if (param.indexOf("(") > 0) {
PARAM_TOKEN_PARSER.parse(param,variable -> {
Object value = ScriptManager.executeExpression(variable, varMap);
storedParam.setValue(value);
storedParam.setInOut(StoreMode.INOUT);
storedParam.setType(StoredParam.paramType(type));
return null;
});
INOUT_TOKEN_PARSER.parse("@{" + param, inoutParam -> {
SQLModule.params.add(new SqlInOutParameter(inoutParam, StoredParam.paramType(type)));
return null;
});
} else {
Object value = ScriptManager.executeExpression(param, varMap);
storedParam.setValue(value);
storedParam.setInOut(StoreMode.OUT);
storedParam.setType(StoredParam.paramType(type));
SQLModule.params.add(new SqlOutParameter(param, StoredParam.paramType(type)));
}
return null;
});
parameters.add(storedParam);
return null;
});
return "?";
});
return sql;
}