Skip to content

Commit 2b35c83

Browse files
committed
Server:新增 ( ANTI JOIN 和 ) FOREIGN JOIN
1 parent 5ef8a5e commit 2b35c83

File tree

2 files changed

+62
-25
lines changed

2 files changed

+62
-25
lines changed

APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,7 +1350,7 @@ else if ("!".equals(ce.getKey())) {
13501350
if (joinList != null) {
13511351

13521352
String newWs = "";
1353-
String ws = "" + whereString;
1353+
String ws = whereString;
13541354

13551355
List<Object> newPvl = new ArrayList<>();
13561356
List<Object> pvl = new ArrayList<>(preparedValueList);
@@ -1371,6 +1371,8 @@ else if ("!".equals(ce.getKey())) {
13711371
case "|": // FULL JOIN 不支持 <>, [] ,避免太多符号
13721372
case "&": // INNER JOIN
13731373
case "!": // OUTTER JOIN
1374+
case "(": // ANTI JOIN
1375+
case ")": // FOREIGN JOIN
13741376
case "^": // SIDE JOIN
13751377
case "*": // CROSS JOIN
13761378
jc = j.getJoinConfig();
@@ -1379,7 +1381,18 @@ else if ("!".equals(ce.getKey())) {
13791381
js = jc.getWhereString(false);
13801382
jc.setMain(isMain);
13811383

1384+
boolean isWsEmpty = StringUtil.isEmpty(ws, true);
1385+
13821386
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+
}
13831396
continue;
13841397
}
13851398

@@ -1388,27 +1401,42 @@ else if ("!".equals(ce.getKey())) {
13881401
}
13891402

13901403
//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+
}
14001421
}
14011422
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+
}
14121440

14131441
newPvl.addAll(pvl);
14141442
newPvl.addAll(jc.getPreparedValueList());
@@ -1417,7 +1445,11 @@ else if ("!".equals(ce.getKey())) {
14171445
changed = true;
14181446
break;
14191447
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+
);
14211453
}
14221454
}
14231455

@@ -1427,7 +1459,7 @@ else if ("!".equals(ce.getKey())) {
14271459
}
14281460
}
14291461

1430-
String s = whereString.isEmpty() ? "" : (hasPrefix ? " WHERE " : "") + whereString;
1462+
String s = StringUtil.isEmpty(whereString, true) ? "" : (hasPrefix ? " WHERE " : "") + whereString;
14311463

14321464
if (s.isEmpty() && RequestMethod.isQueryMethod(method) == false) {
14331465
throw new UnsupportedOperationException("写操作请求必须带条件!!!");
@@ -2313,13 +2345,18 @@ public String getJoinString() throws Exception {
23132345
case "&": // INNER JOIN
23142346
case "!": // OUTTER JOIN
23152347
case "^": // SIDE JOIN
2348+
case "(": // ANTI JOIN
2349+
case ")": // FOREIGN JOIN
23162350
//场景少且性能差,默认禁用 case "*": // CROSS JOIN
23172351
sql = ("*".equals(j.getJoinType()) ? " CROSS JOIN " : " INNER JOIN ") + jc.getTablePath()
23182352
+ " ON " + quote + jt + quote + "." + quote + j.getKey() + quote + " = " + quote + tn + quote + "." + quote + j.getTargetKey() + quote;
23192353
break;
23202354
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+
); }
23232360

23242361
joinOns += " \n " + sql;
23252362
}

APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/orm/Join.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class Join {
2828
private String originKey;
2929
private String originValue;
3030

31-
private String joinType; // "@" - APP, "&" - INNER, "|" - FULL, "!" - OUTTER, "<" - LEFT, ">" - RIGHT, "^" - SIDE, "*" - CROSS
31+
private String joinType; // "@" - APP, "<" - LEFT, ">" - RIGHT, "&" - INNER, "|" - FULL, "!" - OUTTER, "(" - ANTI, ")" - FOREIGN, "^" - SIDE, "*" - CROSS
3232
private String relateType; // "" - 一对一, "{}" - 一对多, "<>" - 多对一
3333
private JSONObject request; // { "id@":"/Moment/userId" }
3434
private String table; //User

0 commit comments

Comments
 (0)