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