Skip to content

Commit def8d8e

Browse files
迭代@combine 动态表达式,通过默认值实现
完善中
1 parent 99bdb65 commit def8d8e

File tree

1 file changed

+27
-117
lines changed

1 file changed

+27
-117
lines changed

APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java

Lines changed: 27 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import com.alibaba.fastjson.JSONArray;
99
import com.alibaba.fastjson.JSONObject;
1010
import com.alibaba.fastjson.annotation.JSONField;
11-
import com.google.gson.JsonObject;
1211

1312
import java.util.ArrayList;
1413
import java.util.Arrays;
@@ -2749,7 +2748,6 @@ protected String parseCombineExpression(RequestMethod method, String quote, Stri
27492748
}
27502749

27512750
String result = "";
2752-
String tmpResult = "";//存储临时计算结果
27532751

27542752
List<Object> preparedValues = getPreparedValueList();
27552753
if (preparedValues == null && isHaving == false) {
@@ -2778,15 +2776,15 @@ protected String parseCombineExpression(RequestMethod method, String quote, Stri
27782776
char last = 0;
27792777
boolean first = true;
27802778
boolean isNot = false;
2779+
27812780
String key = "";
2782-
boolean combineKeyNotNull = true;
27832781
while (i <= n) { // "date> | (contactIdList<> & (name*~ | tag&$))"
27842782
boolean isOver = i >= n;
27852783
char c = isOver ? 0 : s.charAt(i);
27862784
boolean isBlankOrRightParenthesis = c == ' ' || c == ')';
27872785
if (isOver || isBlankOrRightParenthesis) {
27882786
boolean isEmpty = StringUtil.isEmpty(key, true);
2789-
if (combineKeyNotNull && isEmpty && last != ')') {
2787+
if (isEmpty && last != ')') {
27902788
throw new IllegalArgumentException(errPrefix + " 中字符 '" + (isOver ? s : s.substring(i))
27912789
+ "' 不合法!" + (c == ' ' ? "空格 ' ' " : "右括号 ')'") + " 左边缺少条件 key !逻辑连接符 & | 左右必须各一个相邻空格!"
27922790
+ "空格不能多也不能少!不允许首尾有空格,也不允许连续空格!左括号 ( 的右边 和 右括号 ) 的左边 都不允许有相邻空格!");
@@ -2798,38 +2796,35 @@ protected String parseCombineExpression(RequestMethod method, String quote, Stri
27982796
+ "'" + s.substring(i - key.length() - (isOver ? 1 : 0)) + "' 不合法!左边缺少 & | 其中一个逻辑连接符!");
27992797
}
28002798

2799+
allCount ++;
28012800
if (allCount > maxCombineCount && maxCombineCount > 0) {
28022801
throw new IllegalArgumentException(errPrefix + " 中字符 '" + s + "' 不合法!"
28032802
+ "其中 key 数量 " + allCount + " 已超过最大值,必须在条件键值对数量 0-" + maxCombineCount + " 内!");
28042803
}
2805-
if (1.0f*allCount/size > maxCombineRatio && maxCombineRatio > 0) {
2806-
throw new IllegalArgumentException(errPrefix + " 中字符 '" + s + "' 不合法!"
2807-
+ "其中 key 数量 " + allCount + " / 条件键值对数量 " + size + " = " + (1.0f*allCount/size)
2808-
+ " 已超过 最大倍数,必须在条件键值对数量 0-" + maxCombineRatio + " 倍内!");
2809-
}
28102804

28112805
String column = key;
2812-
2806+
int keyIndex = column.indexOf(":");
2807+
column = keyIndex > 0 ? column.substring(0, keyIndex) : column;
28132808
Object value = conditionMap.get(column);
2809+
String wi = "";
28142810
if (value == null) {
2815-
if (RequestMethod.isQueryMethod(method)) {
2816-
JSONObject jsonCombineExpr = rebuidCombineExpr(table, s, result, tmpResult, key, i - 1, depth);
2817-
result = jsonCombineExpr.getString("result");
2818-
i = jsonCombineExpr.getInteger("index");
2819-
depth = jsonCombineExpr.getIntValue("depth");
2820-
last = result.length() == 0 ? 0 : result.charAt(result.length() -1);
2821-
last = i > 0 && i < s.length() ? s.charAt(i) == '(' ? '(' : 0 : 0; // 兼容后续判断
2822-
tmpResult = "";
2823-
key = "";
2824-
lastLogic = 0;
2825-
combineKeyNotNull = false;
2826-
continue;
2811+
isNot = false; // 以默认表达式为准
2812+
size++; // 兼容 key 数量判断
2813+
wi = keyIndex > 0 ? key.substring(keyIndex + 1) : "";
2814+
if(StringUtil.isEmpty(wi)) {
2815+
throw new IllegalArgumentException(errPrefix + " 中字符 '" + key
2816+
+ "' 对应的条件键值对 " + column + ":value 不存在!");
28272817
}
2828-
throw new IllegalArgumentException(errPrefix + " 中字符 '" + key
2829-
+ "' 对应的条件键值对 " + column + ":value 不存在!");
2818+
} else {
2819+
wi = isHaving ? getHavingItem(quote, table, alias, column, (String) value, containRaw) : getWhereItem(column, value, method, verifyName);
28302820
}
2831-
2832-
String wi = isHaving ? getHavingItem(quote, table, alias, column, (String) value, containRaw) : getWhereItem(column, value, method, verifyName);
2821+
2822+
if (1.0f*allCount/size > maxCombineRatio && maxCombineRatio > 0) {
2823+
throw new IllegalArgumentException(errPrefix + " 中字符 '" + s + "' 不合法!"
2824+
+ "其中 key 数量 " + allCount + " / 条件键值对数量 " + size + " = " + (1.0f*allCount/size)
2825+
+ " 已超过 最大倍数,必须在条件键值对数量 0-" + maxCombineRatio + " 倍内!");
2826+
}
2827+
28332828
if (StringUtil.isEmpty(wi, true)) { // 转成 1=1 ?
28342829
throw new IllegalArgumentException(errPrefix + " 中字符 '" + key
28352830
+ "' 对应的 " + column + ":value 不是有效条件键值对!");
@@ -2841,17 +2836,13 @@ protected String parseCombineExpression(RequestMethod method, String quote, Stri
28412836
throw new IllegalArgumentException(errPrefix + " 中字符 '" + s + "' 不合法!"
28422837
+ "其中 '" + column + "' 重复引用,次数 " + count + " 已超过最大值,必须在 0-" + maxCombineKeyCount + " 内!");
28432838
}
2844-
allCount ++;
28452839
usedKeyCountMap.put(column, count);
2846-
result += tmpResult;
28472840
result += "( " + getCondition(isNot, wi) + " )";
2848-
tmpResult = "";
28492841
isNot = false;
28502842
first = false;
28512843
}
28522844

28532845
key = "";
2854-
combineKeyNotNull = true;
28552846
lastLogic = 0;
28562847

28572848
if (isOver) {
@@ -2869,7 +2860,7 @@ else if (c == '&') {
28692860
+ "不允许首尾有空格,也不允许连续空格!左括号 ( 的右边 和 右括号 ) 的左边 都不允许有相邻空格!");
28702861
}
28712862

2872-
tmpResult += SQL.AND;
2863+
result += SQL.AND;
28732864
lastLogic = c;
28742865
i ++;
28752866
}
@@ -2885,7 +2876,7 @@ else if (c == '|') {
28852876
+ "不允许首尾有空格,也不允许连续空格!左括号 ( 右边和右括号 ) 左边都不允许有相邻空格!");
28862877
}
28872878

2888-
tmpResult += SQL.OR;
2879+
result += SQL.OR;
28892880
lastLogic = c;
28902881
i ++;
28912882
}
@@ -2914,7 +2905,7 @@ else if (c == '!') {
29142905
}
29152906

29162907
if (next == '(') {
2917-
tmpResult += SQL.NOT;
2908+
result += SQL.NOT;
29182909
lastLogic = c;
29192910
}
29202911
else if (last <= 0 || last == ' ' || last == '(') {
@@ -2938,7 +2929,7 @@ else if (c == '(') {
29382929
+ "' 不合法!括号 (()) 嵌套层级 " + depth + " 已超过最大值,必须在 0-" + maxDepth + " 内!");
29392930
}
29402931

2941-
tmpResult += c;
2932+
result += c;
29422933
lastLogic = 0;
29432934
first = true;
29442935
}
@@ -2949,7 +2940,7 @@ else if (c == ')') {
29492940
+ "' 不合法!左括号 ( 比 右括号 ) 少!数量必须相等从而完整闭合 (...) !");
29502941
}
29512942

2952-
tmpResult += c;
2943+
result += c;
29532944
lastLogic = 0;
29542945
}
29552946
else {
@@ -2965,9 +2956,7 @@ else if (c == ')') {
29652956
+ "' 不合法!左括号 ( 比 右括号 ) 多!数量必须相等从而完整闭合 (...) !");
29662957
}
29672958
}
2968-
if(StringUtil.isNotEmpty(tmpResult)) {
2969-
result += tmpResult;
2970-
}
2959+
29712960
List<Object> exprPreparedValues = getPreparedValueList();
29722961
if (isHaving == false) { // 只收集 AND 条件值
29732962
setPreparedValueList(new ArrayList<>());
@@ -3019,85 +3008,6 @@ else if (StringUtil.isNotEmpty(andCond, true)) { // andCond 必须放后面,
30193008
return result;
30203009
}
30213010

3022-
private static JSONObject rebuidCombineExpr(String table, String combineExpr, String result, String tmpResult, String key, int index, int depth) {
3023-
boolean isBegin = index < 4 ? true : false; // 兼容 ((a)), ((!a)), key=a
3024-
boolean isEnd = index + 3 >= combineExpr.length() ? true : false; // 最多嵌套2层(())
3025-
char right = index + 1 >= combineExpr.length() ? 0 : combineExpr.charAt(index + 1);
3026-
boolean isNot = tmpResult.length() == 0 ? false : tmpResult.endsWith(SQL.NOT);
3027-
// 处理 (a) | b, ((a)) | b
3028-
boolean leftIsBracket = tmpResult.length() > 0 ? tmpResult.charAt(tmpResult.length() - 1) == '(' ? true : false : false;
3029-
// @combine=key
3030-
if (isBegin && isEnd) {
3031-
//combine条件存在,至少保证传递一个参数
3032-
result = "";
3033-
index = combineExpr.length() -1;
3034-
depth = 0;
3035-
} else if (isNot) { // 处理 ((!a))
3036-
// 一层、两层、无括号
3037-
} else if (leftIsBracket && right == ')') {
3038-
result += tmpResult;
3039-
} else { // 4、无单key括号比如:((a))、(a)
3040-
boolean isRemleft = tmpResult.length() == 0 ? false : (tmpResult.endsWith(SQL.AND) | tmpResult.endsWith(SQL.OR) | tmpResult.endsWith(SQL.NOT)) ? true : false;
3041-
if (isRemleft || right == ')') { // 去除左边
3042-
if (tmpResult.endsWith(SQL.AND)) {
3043-
result += tmpResult.substring(0, tmpResult.length() - SQL.AND.length());
3044-
} else if (tmpResult.endsWith(SQL.OR)) {
3045-
result += tmpResult.substring(0, tmpResult.length() - SQL.OR.length());
3046-
}
3047-
} else if (right == ' '){ // 去除右边
3048-
// a | (b!~ & d!),(a | (b!~ & d!)) key = a,b!~
3049-
result += tmpResult;
3050-
index += 3;
3051-
}
3052-
}
3053-
3054-
leftIsBracket = result.length() == 0 ? false : result.charAt(result.length() - 1) == '(' ? true : false;
3055-
if(leftIsBracket && right == ')') { // 多层括号
3056-
JSONObject json = bracketMatching(combineExpr, result, index, depth, true);
3057-
int resultLength = StringUtil.isEmpty(json.get("result")) ? 0 : json.getString("result").length();
3058-
leftIsBracket = resultLength == 0 ? false : json.getString("result").charAt(resultLength - 1) == '(' ? true : false;
3059-
right = json.getIntValue("index") >= combineExpr.length() ? 0 : combineExpr.charAt(json.getIntValue("index"));
3060-
if(leftIsBracket && right == ')') {
3061-
return bracketMatching(combineExpr, json.getString("result"), json.getIntValue("index"), json.getIntValue("depth"), false);
3062-
}
3063-
return json;
3064-
}
3065-
3066-
JSONObject json = new JSONObject();
3067-
json.put("result", result);
3068-
json.put("index", ++index); // 从下一个下标开始遍历
3069-
json.put("depth", depth);
3070-
return json;
3071-
}
3072-
3073-
private static JSONObject bracketMatching(String combineExpr, String result, int index, int depth, boolean isBracketOne) {
3074-
if (result.endsWith(SQL.AND + "(")) {
3075-
result = result.substring(0, result.length() - SQL.AND.length() - 1);
3076-
if(isBracketOne) {
3077-
++index;
3078-
}
3079-
} else if (result.endsWith(SQL.OR + "(")) {
3080-
result = result.substring(0, result.length() - SQL.OR.length() - 1);
3081-
if(isBracketOne) {
3082-
++index;
3083-
}
3084-
} else {
3085-
// 处理右侧
3086-
result = result.substring(0, result.length() -1);
3087-
char _right = index + 4 >= combineExpr.length() ? 0 : combineExpr.charAt(index + 2);
3088-
if (_right == ' ') {
3089-
index += 4;
3090-
} else {
3091-
index += 1;
3092-
}
3093-
}
3094-
JSONObject json = new JSONObject();
3095-
json.put("result", result);
3096-
json.put("index", ++index); // 从下一个下标开始遍历
3097-
json.put("depth", --depth);
3098-
return json;
3099-
}
3100-
31013011
/**@combine:"a,b" 条件组合。虽然有了 @combine:"a | b" 这种新方式,但为了 Join 多个 On 能保证顺序正确,以及这个性能更好,还是保留这个方式
31023012
* @param hasPrefix
31033013
* @param method

0 commit comments

Comments
 (0)