88import com .alibaba .fastjson .JSONArray ;
99import com .alibaba .fastjson .JSONObject ;
1010import com .alibaba .fastjson .annotation .JSONField ;
11+ import com .google .gson .JsonObject ;
1112
1213import java .util .ArrayList ;
1314import 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