@@ -1350,7 +1350,7 @@ else if ("!".equals(ce.getKey())) {
1350
1350
if (joinList != null ) {
1351
1351
1352
1352
String newWs = "" ;
1353
- String ws = "" + whereString ;
1353
+ String ws = whereString ;
1354
1354
1355
1355
List <Object > newPvl = new ArrayList <>();
1356
1356
List <Object > pvl = new ArrayList <>(preparedValueList );
@@ -1371,6 +1371,8 @@ else if ("!".equals(ce.getKey())) {
1371
1371
case "|" : // FULL JOIN 不支持 <>, [] ,避免太多符号
1372
1372
case "&" : // INNER JOIN
1373
1373
case "!" : // OUTTER JOIN
1374
+ case "(" : // ANTI JOIN
1375
+ case ")" : // FOREIGN JOIN
1374
1376
case "^" : // SIDE JOIN
1375
1377
case "*" : // CROSS JOIN
1376
1378
jc = j .getJoinConfig ();
@@ -1379,7 +1381,18 @@ else if ("!".equals(ce.getKey())) {
1379
1381
js = jc .getWhereString (false );
1380
1382
jc .setMain (isMain );
1381
1383
1384
+ boolean isWsEmpty = StringUtil .isEmpty (ws , true );
1385
+
1382
1386
if (StringUtil .isEmpty (js , true )) {
1387
+ if (")" .equals (j .getJoinType ())) { // FOREIGN JOIN: B & ! A
1388
+ if (isWsEmpty ) {
1389
+ throw new NotExistException ("no result for ) FOREIGN JOIN(A & ! B) while both A and B are empty!" );
1390
+ }
1391
+
1392
+ newWs += " ( " + getCondition (true , ws ) + " ) " ;
1393
+ newPvl .addAll (pvl );
1394
+ changed = true ;
1395
+ }
1383
1396
continue ;
1384
1397
}
1385
1398
@@ -1388,27 +1401,42 @@ else if ("!".equals(ce.getKey())) {
1388
1401
}
1389
1402
1390
1403
//MySQL 因为 NULL 值处理问题,(A & ! B) | (B & ! A) 与 ! (A & B) 返回结果不一样,后者往往更多
1391
- if ("^" .equals (j .getJoinType ())) { // (A & ! B) | (B & ! A)
1392
- newWs += " ( ( " + ws + ( StringUtil .isEmpty (ws , true ) ? "" : AND + NOT ) + " ( " + js + " ) ) "
1393
- + OR
1394
- + " ( " + js + AND + NOT + " ( " + ws + " ) ) ) " ;
1395
-
1396
- newPvl .addAll (pvl );
1397
- newPvl .addAll (jc .getPreparedValueList ());
1398
- newPvl .addAll (jc .getPreparedValueList ());
1399
- newPvl .addAll (pvl );
1404
+ if ("^" .equals (j .getJoinType ())) { //SIDE JOIN: (A & ! B) | (B & ! A)
1405
+ if (isWsEmpty ) {
1406
+ newWs += js ;
1407
+
1408
+ newPvl .addAll (pvl );
1409
+ newPvl .addAll (jc .getPreparedValueList ());
1410
+ }
1411
+ else {
1412
+ newWs += " ( ( " + ws + AND + NOT + " ( " + js + " ) ) "
1413
+ + OR
1414
+ + " ( " + js + AND + NOT + " ( " + ws + " ) ) ) " ;
1415
+
1416
+ newPvl .addAll (pvl );
1417
+ newPvl .addAll (jc .getPreparedValueList ());
1418
+ newPvl .addAll (jc .getPreparedValueList ());
1419
+ newPvl .addAll (pvl );
1420
+ }
1400
1421
}
1401
1422
else {
1402
- logic = Logic .getType (j .getJoinType ());
1403
-
1404
- newWs += " ( "
1405
- + getCondition (
1406
- Logic .isNot (logic ),
1407
- ws
1408
- + ( StringUtil .isEmpty (ws , true ) ? "" : (Logic .isAnd (logic ) ? AND : OR ) )
1409
- + " ( " + js + " ) "
1410
- )
1411
- + " ) " ;
1423
+ if ("(" .equals (j .getJoinType ())) { // ANTI JOIN: A & ! B
1424
+ newWs += " ( " + ( isWsEmpty ? "" : ws + AND ) + NOT + " ( " + js + " ) " + " ) " ;
1425
+ }
1426
+ else if (")" .equals (j .getJoinType ())) { // FOREIGN JOIN: B & ! A
1427
+ newWs += " ( " + " ( " + js + " ) " + ( isWsEmpty ? "" : AND + NOT + ws ) + " ) " ;
1428
+ }
1429
+ else { // & INNER JOIN: A & B; | FULL JOIN: A | B; OUTER JOIN: ! (A & B)
1430
+ logic = Logic .getType (j .getJoinType ());
1431
+ newWs += " ( "
1432
+ + getCondition (
1433
+ Logic .isNot (logic ),
1434
+ ws
1435
+ + ( isWsEmpty ? "" : (Logic .isAnd (logic ) ? AND : OR ) )
1436
+ + " ( " + js + " ) "
1437
+ )
1438
+ + " ) " ;
1439
+ }
1412
1440
1413
1441
newPvl .addAll (pvl );
1414
1442
newPvl .addAll (jc .getPreparedValueList ());
@@ -1417,7 +1445,11 @@ else if ("!".equals(ce.getKey())) {
1417
1445
changed = true ;
1418
1446
break ;
1419
1447
default :
1420
- throw new UnsupportedOperationException ("join:value 中 value 里的 " + j .getJoinType () + "/" + j .getPath () + "错误!不支持 " + j .getJoinType () + " 等 [@ APP, < LEFT, > RIGHT, | FULL, & INNER, ! OUTTER, ^ SIDE, * CROSS] 之外的JOIN类型 !" );
1448
+ throw new UnsupportedOperationException (
1449
+ "join:value 中 value 里的 " + j .getJoinType () + "/" + j .getPath ()
1450
+ + "错误!不支持 " + j .getJoinType () + " 等 [ @ APP, < LEFT, > RIGHT, | FULL, & INNER, ! OUTTER"
1451
+ + ", ( ANTI, ) FOREIGN, ^ SIDE, * CROSS ] 之外的JOIN类型 !"
1452
+ );
1421
1453
}
1422
1454
}
1423
1455
@@ -1427,7 +1459,7 @@ else if ("!".equals(ce.getKey())) {
1427
1459
}
1428
1460
}
1429
1461
1430
- String s = whereString .isEmpty () ? "" : (hasPrefix ? " WHERE " : "" ) + whereString ;
1462
+ String s = StringUtil .isEmpty (whereString , true ) ? "" : (hasPrefix ? " WHERE " : "" ) + whereString ;
1431
1463
1432
1464
if (s .isEmpty () && RequestMethod .isQueryMethod (method ) == false ) {
1433
1465
throw new UnsupportedOperationException ("写操作请求必须带条件!!!" );
@@ -2313,13 +2345,18 @@ public String getJoinString() throws Exception {
2313
2345
case "&" : // INNER JOIN
2314
2346
case "!" : // OUTTER JOIN
2315
2347
case "^" : // SIDE JOIN
2348
+ case "(" : // ANTI JOIN
2349
+ case ")" : // FOREIGN JOIN
2316
2350
//场景少且性能差,默认禁用 case "*": // CROSS JOIN
2317
2351
sql = ("*" .equals (j .getJoinType ()) ? " CROSS JOIN " : " INNER JOIN " ) + jc .getTablePath ()
2318
2352
+ " ON " + quote + jt + quote + "." + quote + j .getKey () + quote + " = " + quote + tn + quote + "." + quote + j .getTargetKey () + quote ;
2319
2353
break ;
2320
2354
default :
2321
- throw new UnsupportedOperationException ("join:value 中 value 里的 " + j .getJoinType () + "/" + j .getPath () + "错误!不支持 " + j .getJoinType () + " 等 [@ APP, < LEFT, > RIGHT, | FULL, & INNER, ! OUTTER, ^ SIDE, * CROSS] 之外的JOIN类型 !" );
2322
- }
2355
+ throw new UnsupportedOperationException (
2356
+ "join:value 中 value 里的 " + j .getJoinType () + "/" + j .getPath ()
2357
+ + "错误!不支持 " + j .getJoinType () + " 等 [ @ APP, < LEFT, > RIGHT, | FULL, & INNER, ! OUTTER"
2358
+ + ", ( ANTI, ) FOREIGN, ^ SIDE, * CROSS ] 之外的JOIN类型 !"
2359
+ ); }
2323
2360
2324
2361
joinOns += " \n " + sql ;
2325
2362
}
0 commit comments