Skip to content

Commit 4018963

Browse files
committed
Server:新增APP JOIN,"join":"@/User/id@";AbstractSQLExecutor.execute减少因为viceColumnStart起始值错误导致的多余一次缓存
1 parent a54385c commit 4018963

File tree

4 files changed

+249
-46
lines changed

4 files changed

+249
-46
lines changed

APIJSON-Java-Server/APIJSONLibrary/src/main/java/zuo/biao/apijson/server/AbstractParser.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,9 @@ private List<Join> onJoinParse(String join, JSONObject request) throws Exception
822822
tableObj.put(key, tableObj.remove(key)); //保证和SQLExcecutor缓存的Config里where顺序一致,生成的SQL也就一致
823823

824824
Join j = new Join();
825+
j.setPath(path);
826+
j.setOriginKey(key);
827+
j.setOriginValue(targetPath);
825828
j.setJoinType(joinType);
826829
j.setName(table);
827830
j.setTargetName(targetTable);

APIJSON-Java-Server/APIJSONLibrary/src/main/java/zuo/biao/apijson/server/AbstractSQLConfig.java

Lines changed: 77 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -491,13 +491,17 @@ public String getColumnString() throws Exception {
491491

492492
return "(" + StringUtil.getString(column.toArray()) + ")";
493493
case GET:
494-
case GETS: //TODO 支持SQL函数 json_length(contactIdList):contactCount
494+
case GETS:
495495
boolean isQuery = RequestMethod.isQueryMethod(method);
496496
String joinColumn = "";
497497
if (isQuery && joinList != null) {
498498
SQLConfig c;
499499
boolean first = true;
500500
for (Join j : joinList) {
501+
if (j.isAppJoin()) {
502+
continue;
503+
}
504+
501505
c = j.getJoinConfig();
502506
c.setAlias(c.getTable());
503507
joinColumn += (first ? "" : ", ") + ((AbstractSQLConfig) c).getColumnString();
@@ -637,7 +641,7 @@ public String getColumnString() throws Exception {
637641
}
638642
}
639643

640-
644+
641645
@Override
642646
public List<List<Object>> getValues() {
643647
return values;
@@ -862,10 +866,14 @@ public AbstractSQLConfig putWhere(String key, Object value, boolean prior) {
862866
if (where == null) {
863867
where = new LinkedHashMap<String, Object>();
864868
}
865-
where.put(key, value);
869+
if (value == null) {
870+
where.remove(key);
871+
} else {
872+
where.put(key, value);
873+
}
866874

867875
combine = getCombine();
868-
List<String> andList = combine == null ? null : combine.get("&");
876+
List<String> andList = combine.get("&");
869877
if (value == null) {
870878
andList.remove(key);
871879
}
@@ -984,12 +992,21 @@ else if ("!".equals(ce.getKey())) {
984992
//各种 JOIN 没办法统一用 & | !连接,只能按优先级,和 @combine 一样?
985993
for (Join j : joinList) {
986994
switch (j.getJoinType()) {
987-
case "":
988-
case "|": //不支持 <>, [] ,避免太多符号
989-
case "&":
990-
case "!":
991-
case "^":
992-
case "*":
995+
case "@": // APP JOIN
996+
newWs = whereString; //解决 生成的 SQL 里 where = null
997+
newPvl = preparedValueList; //解决总是 preparedValueList = new ArrayList
998+
break;
999+
1000+
case "<": // LEFT JOIN
1001+
case ">": // RIGHT JOIN
1002+
break;
1003+
1004+
case "": // FULL JOIN
1005+
case "|": // FULL JOIN 不支持 <>, [] ,避免太多符号
1006+
case "&": // INNER JOIN
1007+
case "!": // OUTTER JOIN
1008+
case "^": // SIDE JOIN
1009+
case "*": // CROSS JOIN
9931010
jc = j.getJoinConfig();
9941011
boolean isMain = jc.isMain();
9951012
jc.setMain(false).setPrepared(isPrepared()).setPreparedValueList(new ArrayList<Object>());
@@ -1031,8 +1048,8 @@ else if ("!".equals(ce.getKey())) {
10311048
}
10321049

10331050
break;
1034-
//可能 LEFT JOIN 和 INNER JOIN 同时存在 default:
1035-
// throw new UnsupportedOperationException("");
1051+
default:
1052+
throw new UnsupportedOperationException("join:value 中 value 里的 " + j.getJoinType() + "/" + j.getPath() + "错误!不支持 " + j.getJoinType() + " 等 [@ APP, < LEFT, > RIGHT, | FULL, & INNER, ! OUTTER, ^ SIDE, * CROSS] 之外的JOIN类型 !");
10361053
}
10371054
}
10381055

@@ -1688,6 +1705,7 @@ public AbstractSQLConfig setKeyPrefix(boolean keyPrefix) {
16881705

16891706
public String getJoinString() throws Exception {
16901707
String joinOns = "";
1708+
16911709
if (joinList != null) {
16921710
String quote = getQuote();
16931711

@@ -1696,6 +1714,9 @@ public String getJoinString() throws Exception {
16961714
String jt;
16971715
String tn;
16981716
for (Join j : joinList) {
1717+
if (j.isAppJoin()) { // APP JOIN,只是作为一个标记,执行完主表的查询后自动执行副表的查询 User.id IN($commentIdList)
1718+
continue;
1719+
}
16991720

17001721
//LEFT JOIN sys.apijson_user AS User ON User.id = Moment.userId, 都是用 = ,通过relateType处理缓存
17011722
// <"INNER JOIN User ON User.id = Moment.userId", UserConfig> TODO AS 放 getSQLTable 内
@@ -1709,18 +1730,12 @@ public String getJoinString() throws Exception {
17091730
tn = tn.toLowerCase();
17101731
}
17111732

1712-
switch (j.getJoinType()) {
1713-
case "":
1714-
case "|": //不支持 <>, [] ,避免太多符号
1715-
case "&":
1716-
case "!":
1717-
case "^":
1718-
case "*":
1719-
sql = ("*".equals(j.getJoinType()) ? " CROSS JOIN " : " INNER JOIN ") + jc.getTablePath()
1720-
+ " ON " + quote + jt + quote + "." + quote + j.getKey() + quote + " = " + quote + tn + quote + "." + quote + j.getTargetKey() + quote;
1721-
break;
1722-
case "<":
1723-
case ">":
1733+
switch (j.getJoinType()) { //TODO $ SELF JOIN
1734+
// case "@": // APP JOIN
1735+
// continue;
1736+
1737+
case "<": // LEFT JOIN
1738+
case ">": // RIGHT JOIN
17241739
jc.setMain(true).setKeyPrefix(false);
17251740
sql = ( ">".equals(j.getJoinType()) ? " RIGHT" : " LEFT") + " JOIN ( " + jc.getSQL(isPrepared()) + " ) AS "
17261741
+ quote + jt + quote + " ON " + quote + jt + quote + "." + quote + j.getKey() + quote + " = "
@@ -1729,13 +1744,24 @@ public String getJoinString() throws Exception {
17291744

17301745
preparedValueList.addAll(jc.getPreparedValueList());
17311746
break;
1747+
1748+
case "": // FULL JOIN
1749+
case "|": // FULL JOIN 不支持 <>, [] ,避免太多符号
1750+
case "&": // INNER JOIN
1751+
case "!": // OUTTER JOIN
1752+
case "^": // SIDE JOIN
1753+
//场景少且性能差,默认禁用 case "*": // CROSS JOIN
1754+
sql = ("*".equals(j.getJoinType()) ? " CROSS JOIN " : " INNER JOIN ") + jc.getTablePath()
1755+
+ " ON " + quote + jt + quote + "." + quote + j.getKey() + quote + " = " + quote + tn + quote + "." + quote + j.getTargetKey() + quote;
1756+
break;
17321757
default:
1733-
throw new UnsupportedOperationException("服务器内部错误:不支持JOIN类型 " + j.getJoinType() + " !");
1758+
throw new UnsupportedOperationException("join:value 中 value 里的 " + j.getJoinType() + "/" + j.getPath() + "错误!不支持 " + j.getJoinType() + " 等 [@ APP, < LEFT, > RIGHT, | FULL, & INNER, ! OUTTER, ^ SIDE, * CROSS] 之外的JOIN类型 !");
17341759
}
17351760

17361761
joinOns += " \n " + sql;
17371762
}
17381763
}
1764+
17391765
return joinOns;
17401766
}
17411767

@@ -1752,8 +1778,7 @@ public static AbstractSQLConfig newSQLConfig(RequestMethod method, String table,
17521778
AbstractSQLConfig config = callback.getSQLConfig(method, table);
17531779

17541780
//放后面会导致主表是空对象时 joinList 未解析
1755-
config.setJoinList(parseJoin(method, joinList, callback));
1756-
config.setKeyPrefix(RequestMethod.isQueryMethod(method) && (config.isMain() == false || (joinList != null && joinList.isEmpty() == false)));
1781+
config = parseJoin(method, config, joinList, callback);
17571782

17581783
if (request.isEmpty()) { // User:{} 这种空内容在查询时也有效
17591784
return config; //request.remove(key); 前都可以直接return,之后必须保证 put 回去
@@ -2023,21 +2048,39 @@ else if (whereList != null && whereList.contains(key)) {
20232048
}
20242049

20252050

2026-
public static List<Join> parseJoin(RequestMethod method, List<Join> joinList, Callback callback) throws Exception {
2051+
/**
2052+
* @param method
2053+
* @param config
2054+
* @param joinList
2055+
* @param callback
2056+
* @return
2057+
* @throws Exception
2058+
*/
2059+
public static AbstractSQLConfig parseJoin(RequestMethod method, AbstractSQLConfig config, List<Join> joinList, Callback callback) throws Exception {
2060+
boolean isQuery = RequestMethod.isQueryMethod(method);
2061+
config.setKeyPrefix(isQuery && config.isMain() == false);
20272062

20282063
//TODO 解析出 SQLConfig 再合并 column, order, group 等
2029-
if (joinList == null || joinList.isEmpty()) {
2030-
return null;
2064+
if (joinList == null || joinList.isEmpty() || RequestMethod.isQueryMethod(method) == false) {
2065+
return config;
20312066
}
20322067

20332068

20342069
String name;
20352070
for (Join j : joinList) {
20362071
name = j.getName();
20372072
//JOIN子查询不能设置LIMIT,因为ON关系是在子查询后处理的,会导致结果会错误
2038-
SQLConfig joinConfig = newSQLConfig(method, name, j.getTable(), null, callback).setMain(false).setKeyPrefix(true);
2073+
SQLConfig joinConfig = newSQLConfig(method, name, j.getTable(), null, callback);
20392074
SQLConfig cacheConfig = newSQLConfig(method, name, j.getTable(), null, callback).setCount(1);
20402075

2076+
if (j.isAppJoin() == false) { //除了 @ APP JOIN,其它都是 SQL JOIN,则副表要这样配置
2077+
if (isQuery) {
2078+
config.setKeyPrefix(true);
2079+
}
2080+
2081+
joinConfig.setMain(false).setKeyPrefix(true);
2082+
}
2083+
20412084
//解决 query: 1/2 查数量时报错
20422085
/* SELECT count(*) AS count FROM sys.Moment AS Moment
20432086
LEFT JOIN ( SELECT count(*) AS count FROM sys.Comment ) AS Comment ON Comment.momentId = Moment.id LIMIT 1 OFFSET 0 */
@@ -2053,10 +2096,10 @@ LEFT JOIN ( SELECT count(*) AS count FROM sys.Comment ) AS Comment ON Comment.m
20532096
j.setCacheConfig(cacheConfig);
20542097
}
20552098

2056-
return joinList;
2057-
}
2058-
2099+
config.setJoinList(joinList);
20592100

2101+
return config;
2102+
}
20602103

20612104

20622105

0 commit comments

Comments
 (0)