@@ -3891,9 +3891,55 @@ protected String concatJoinOn(@NotNull String sql, @NotNull String quote, @NotNu
38913891 sql += (first ? ON : AND ) + quote + jt + quote + "." + quote + on .getKey () + quote + " " + rt + " "
38923892 + quote + on .getTargetTable () + quote + "." + quote + on .getTargetKey () + quote ;
38933893 }
3894- else if ("$" .equals (rt )) {
3895- sql += (first ? ON : AND ) + quote + jt + quote + "." + quote + on .getKey () + quote + (isNot ? NOT : "" )
3896- + " LIKE concat('%', " + quote + on .getTargetTable () + quote + "." + quote + on .getTargetKey () + quote + ", '%')" ;
3894+ else if (rt .endsWith ("$" )) {
3895+ String t = rt .substring (0 , rt .length () - 1 );
3896+ char r = t .isEmpty () ? 0 : t .charAt (t .length () - 1 );
3897+
3898+ char l ;
3899+ if (r == '%' || r == '_' || r == '?' ) {
3900+ t = t .substring (0 , t .length () - 1 );
3901+
3902+ if (t .isEmpty ()) {
3903+ if (r == '?' ) {
3904+ throw new IllegalArgumentException (on .getOriginKey () + ":value 中字符 " + on .getOriginKey () + " 不合法!key$:value 中不允许只有单独的 '?',必须和 '%', '_' 之一配合使用 !" );
3905+ }
3906+
3907+ l = r ;
3908+ }
3909+ else {
3910+ l = t .charAt (t .length () - 1 );
3911+ if (l == '%' || l == '_' || l == '?' ) {
3912+ if (l == r ) {
3913+ throw new IllegalArgumentException (on .getOriginKey () + ":value 中字符 " + t + " 不合法!key$:value 中不允许 key 中有连续相同的占位符!" );
3914+ }
3915+
3916+ t = t .substring (0 , t .length () - 1 );
3917+ }
3918+ else if (l > 0 && StringUtil .isName (String .valueOf (l ))) {
3919+ l = r ;
3920+ }
3921+ }
3922+
3923+ if (l == '?' ) {
3924+ l = 0 ;
3925+ }
3926+ if (r == '?' ) {
3927+ r = 0 ;
3928+ }
3929+ }
3930+ else {
3931+ l = r = 0 ;
3932+ }
3933+
3934+ if (l <= 0 && r <= 0 ) {
3935+ sql += (first ? ON : AND ) + quote + jt + quote + "." + quote + on .getKey () + quote + (isNot ? NOT : "" )
3936+ + " LIKE " + quote + on .getTargetTable () + quote + "." + quote + on .getTargetKey () + quote ;
3937+ }
3938+ else {
3939+ sql += (first ? ON : AND ) + quote + jt + quote + "." + quote + on .getKey () + quote + (isNot ? NOT : "" )
3940+ + (l <= 0 ? " LIKE concat(" : " LIKE concat('" + l + "', " ) + quote + on .getTargetTable () + quote
3941+ + "." + quote + on .getTargetKey () + quote + (r <= 0 ? ")" : ", '" + r + "')" );
3942+ }
38973943 }
38983944 else if (rt .endsWith ("~" )) {
38993945 boolean ignoreCase = "*~" .equals (rt );
@@ -3992,10 +4038,10 @@ else if (isClickHouse()) {
39924038 }
39934039
39944040 protected void onJoinNotRelation (String sql , String quote , Join j , String jt , List <On > onList , On on ) {
3995- throw new UnsupportedOperationException ("JOIN 已禁用 '!' 非逻辑连接符 !性能很差、需求极少,如要取消禁用可在后端重写相关方法!" );
4041+ // throw new UnsupportedOperationException("JOIN 已禁用 '!' 非逻辑连接符 !性能很差、需求极少,如要取消禁用可在后端重写相关方法!");
39964042 }
39974043 protected void onJoinComplextRelation (String sql , String quote , Join j , String jt , List <On > onList , On on ) {
3998- throw new UnsupportedOperationException ("JOIN 已禁用 $, ~, {}, <>, >, <, >=, <= 等复杂关联 !性能很差、需求极少,默认只允许等价关联,如要取消禁用可在后端重写相关方法!" );
4044+ // throw new UnsupportedOperationException("JOIN 已禁用 $, ~, {}, <>, >, <, >=, <= 等复杂关联 !性能很差、需求极少,默认只允许等价关联,如要取消禁用可在后端重写相关方法!");
39994045 }
40004046 protected void onGetCrossJoinString (Join j ) throws UnsupportedOperationException {
40014047 throw new UnsupportedOperationException ("已禁用 * CROSS JOIN !性能很差、需求极少,如要取消禁用可在后端重写相关方法!" );
@@ -4599,7 +4645,27 @@ public static String getRealKey(RequestMethod method, String originKey
45994645
46004646 String key = new String (originKey );
46014647 if (key .endsWith ("$" )) {//搜索 LIKE,查询时处理
4602- key = key .substring (0 , key .length () - 1 );
4648+ String k = key .substring (0 , key .length () - 1 );
4649+ // key%$:"a" -> key LIKE '%a%'; key?%$:"a" -> key LIKE 'a%'; key_?$:"a" -> key LIKE '_a'; key_%$:"a" -> key LIKE '_a%'
4650+ char c = k .isEmpty () ? 0 : k .charAt (k .length () - 1 );
4651+
4652+ if (c == '%' || c == '_' || c == '?' ) {
4653+ k = k .substring (0 , k .length () - 1 );
4654+
4655+ char c2 = k .isEmpty () ? 0 : k .charAt (k .length () - 1 );
4656+ if (c2 == '%' || c2 == '_' || c2 == '?' ) {
4657+ if (c2 == c ) {
4658+ throw new IllegalArgumentException (originKey + ":value 中字符 " + k + " 不合法!key$:value 中不允许 key 中有连续相同的占位符!" );
4659+ }
4660+
4661+ k = k .substring (0 , k .length () - 1 );
4662+ }
4663+ else if (c == '?' ) {
4664+ throw new IllegalArgumentException (originKey + ":value 中字符 " + originKey + " 不合法!key$:value 中不允许只有单独的 '?',必须和 '%', '_' 之一配合使用 !" );
4665+ }
4666+ }
4667+
4668+ key = k ;
46034669 }
46044670 else if (key .endsWith ("~" )) {//匹配正则表达式 REGEXP,查询时处理
46054671 key = key .substring (0 , key .length () - 1 );
@@ -4648,6 +4714,8 @@ else if (key.endsWith("-")) {//缩减,PUT查询时处理
46484714 }
46494715 }
46504716
4717+ //TODO if (key.endsWith("-")) { // 表示 key 和 value 顺序反过来: value LIKE key
4718+
46514719 String last = null ;//不用Logic优化代码,否则 key 可能变为 key| 导致 key=value 变成 key|=value 而出错
46524720 if (RequestMethod .isQueryMethod (method )) {//逻辑运算符仅供GET,HEAD方法使用
46534721 last = key .isEmpty () ? "" : key .substring (key .length () - 1 );
0 commit comments