Skip to content

Commit 906d14c

Browse files
配置@combine模版, c端传递 参数,生成参数对应 where条件
最初版,还会调整
1 parent a91a44f commit 906d14c

1 file changed

Lines changed: 124 additions & 11 deletions

File tree

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

Lines changed: 124 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
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;
1112

1213
import java.util.ArrayList;
1314
import java.util.Arrays;
@@ -2748,6 +2749,7 @@ protected String parseCombineExpression(RequestMethod method, String quote, Stri
27482749
}
27492750

27502751
String result = "";
2752+
String tmpResult = "";//存储临时计算结果
27512753

27522754
List<Object> preparedValues = getPreparedValueList();
27532755
if (preparedValues == null && isHaving == false) {
@@ -2776,15 +2778,15 @@ protected String parseCombineExpression(RequestMethod method, String quote, Stri
27762778
char last = 0;
27772779
boolean first = true;
27782780
boolean isNot = false;
2779-
27802781
String key = "";
2782+
boolean combineKeyNotNull = true;
27812783
while (i <= n) { // "date> | (contactIdList<> & (name*~ | tag&$))"
27822784
boolean isOver = i >= n;
27832785
char c = isOver ? 0 : s.charAt(i);
27842786
boolean isBlankOrRightParenthesis = c == ' ' || c == ')';
27852787
if (isOver || isBlankOrRightParenthesis) {
27862788
boolean isEmpty = StringUtil.isEmpty(key, true);
2787-
if (isEmpty && last != ')') {
2789+
if (combineKeyNotNull == true && isEmpty && last != ')') {
27882790
throw new IllegalArgumentException(errPrefix + " 中字符 '" + (isOver ? s : s.substring(i))
27892791
+ "' 不合法!" + (c == ' ' ? "空格 ' ' " : "右括号 ')'") + " 左边缺少条件 key !逻辑连接符 & | 左右必须各一个相邻空格!"
27902792
+ "空格不能多也不能少!不允许首尾有空格,也不允许连续空格!左括号 ( 的右边 和 右括号 ) 的左边 都不允许有相邻空格!");
@@ -2796,7 +2798,6 @@ protected String parseCombineExpression(RequestMethod method, String quote, Stri
27962798
+ "'" + s.substring(i - key.length() - (isOver ? 1 : 0)) + "' 不合法!左边缺少 & | 其中一个逻辑连接符!");
27972799
}
27982800

2799-
allCount ++;
28002801
if (allCount > maxCombineCount && maxCombineCount > 0) {
28012802
throw new IllegalArgumentException(errPrefix + " 中字符 '" + s + "' 不合法!"
28022803
+ "其中 key 数量 " + allCount + " 已超过最大值,必须在条件键值对数量 0-" + maxCombineCount + " 内!");
@@ -2811,6 +2812,19 @@ protected String parseCombineExpression(RequestMethod method, String quote, Stri
28112812

28122813
Object value = conditionMap.get(column);
28132814
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;
2827+
}
28142828
throw new IllegalArgumentException(errPrefix + " 中字符 '" + key
28152829
+ "' 对应的条件键值对 " + column + ":value 不存在!");
28162830
}
@@ -2827,14 +2841,17 @@ protected String parseCombineExpression(RequestMethod method, String quote, Stri
28272841
throw new IllegalArgumentException(errPrefix + " 中字符 '" + s + "' 不合法!"
28282842
+ "其中 '" + column + "' 重复引用,次数 " + count + " 已超过最大值,必须在 0-" + maxCombineKeyCount + " 内!");
28292843
}
2844+
allCount ++;
28302845
usedKeyCountMap.put(column, count);
2831-
2846+
result += tmpResult;
28322847
result += "( " + getCondition(isNot, wi) + " )";
2848+
tmpResult = "";
28332849
isNot = false;
28342850
first = false;
28352851
}
28362852

28372853
key = "";
2854+
combineKeyNotNull = true;
28382855
lastLogic = 0;
28392856

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

2855-
result += SQL.AND;
2872+
tmpResult += SQL.AND;
28562873
lastLogic = c;
28572874
i ++;
28582875
}
@@ -2868,7 +2885,7 @@ else if (c == '|') {
28682885
+ "不允许首尾有空格,也不允许连续空格!左括号 ( 右边和右括号 ) 左边都不允许有相邻空格!");
28692886
}
28702887

2871-
result += SQL.OR;
2888+
tmpResult += SQL.OR;
28722889
lastLogic = c;
28732890
i ++;
28742891
}
@@ -2897,7 +2914,7 @@ else if (c == '!') {
28972914
}
28982915

28992916
if (next == '(') {
2900-
result += SQL.NOT;
2917+
tmpResult += SQL.NOT;
29012918
lastLogic = c;
29022919
}
29032920
else if (last <= 0 || last == ' ' || last == '(') {
@@ -2921,7 +2938,7 @@ else if (c == '(') {
29212938
+ "' 不合法!括号 (()) 嵌套层级 " + depth + " 已超过最大值,必须在 0-" + maxDepth + " 内!");
29222939
}
29232940

2924-
result += c;
2941+
tmpResult += c;
29252942
lastLogic = 0;
29262943
first = true;
29272944
}
@@ -2932,7 +2949,7 @@ else if (c == ')') {
29322949
+ "' 不合法!左括号 ( 比 右括号 ) 少!数量必须相等从而完整闭合 (...) !");
29332950
}
29342951

2935-
result += c;
2952+
tmpResult += c;
29362953
lastLogic = 0;
29372954
}
29382955
else {
@@ -2948,7 +2965,9 @@ else if (c == ')') {
29482965
+ "' 不合法!左括号 ( 比 右括号 ) 多!数量必须相等从而完整闭合 (...) !");
29492966
}
29502967
}
2951-
2968+
if(StringUtil.isNotEmpty(tmpResult)) {
2969+
result += tmpResult;
2970+
}
29522971
List<Object> exprPreparedValues = getPreparedValueList();
29532972
if (isHaving == false) { // 只收集 AND 条件值
29542973
setPreparedValueList(new ArrayList<>());
@@ -3000,6 +3019,85 @@ else if (StringUtil.isNotEmpty(andCond, true)) { // andCond 必须放后面,
30003019
return result;
30013020
}
30023021

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+
30033101
/**@combine:"a,b" 条件组合。虽然有了 @combine:"a | b" 这种新方式,但为了 Join 多个 On 能保证顺序正确,以及这个性能更好,还是保留这个方式
30043102
* @param hasPrefix
30053103
* @param method
@@ -5122,8 +5220,9 @@ else if (w.startsWith("!")) {
51225220
combineMap.put("!", notList);
51235221
}
51245222
config.setCombineMap(combineMap);
5223+
//combineExpr = callback.onMissingKey4Combine(table, request, combineExpr, tableWhere);
51255224
config.setCombine(combineExpr);
5126-
5225+
51275226
config.setContent(tableContent);
51285227
}
51295228

@@ -5605,6 +5704,16 @@ public static interface Callback<T extends Object> extends IdCallback<T> {
56055704
* @param request
56065705
*/
56075706
public void onMissingKey4Combine(String name, JSONObject request, String combine, String item, String key) throws Exception;
5707+
5708+
/***
5709+
* 前端 搜索条件动态生成@combine 表达式
5710+
* 1、orm、route配置 @combine 表达式
5711+
* Document json、Request structure 配置 @combine = a | (b & c)
5712+
* 2、将 @combine 表达式 生成执行 @combine语句
5713+
* 比如:传递参数a,b , 生成执行 combineExpr = a | b
5714+
* @return
5715+
*/
5716+
public String onMissingKey4Combine(String name, JSONObject request, String combineExpr, Map<String, Object> tableWhere);
56085717
}
56095718

56105719
public static Long LAST_ID;
@@ -5641,6 +5750,10 @@ public void onMissingKey4Combine(String name, JSONObject request, String combine
56415750
throw new IllegalArgumentException(name + ":{} 里的 @combine:value 中的value里 " + item + " 对应的条件 " + key + ":value 中 value 不能为 null!");
56425751
}
56435752

5753+
@Override
5754+
public String onMissingKey4Combine(String name, JSONObject request, String combineExpr, Map<String, Object> tableWhere) {
5755+
return combineExpr;
5756+
}
56445757
}
56455758

56465759
private static boolean keyInCombineExpr(String combineExpr, String key) {

0 commit comments

Comments
 (0)