Skip to content

Commit 4161902

Browse files
authored
新增支持 LEFT,RIGHT JOIN 传外层 WHERE 条件,感谢 wz11wz 的贡献 #829
Join.java 中 SQLConfig outerConfig 重命名成 onConfig,然后用原来的 outerConfig 增加最外层的where 查询条件 #829
2 parents f051dea + 2122b8c commit 4161902

File tree

3 files changed

+131
-50
lines changed

3 files changed

+131
-50
lines changed

APIJSONORM/src/main/java/apijson/orm/AbstractParser.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,7 +1563,39 @@ else if (join != null){
15631563
throw new UnsupportedDataTypeException(TAG + ".onJoinParse join 只能是 String 或 Map<String, Object> 类型!");
15641564
}
15651565

1566-
Set<Entry<String, Object>> set = joinMap == null ? null : joinMap.entrySet();
1566+
List<Entry<String, Object>> slashKeys = new ArrayList<>();
1567+
List<Entry<String, Object>> nonSlashKeys = new ArrayList<>();
1568+
Set<Entry<String, Object>> entries = joinMap == null ? null : joinMap.entrySet();
1569+
1570+
if (entries == null || entries.isEmpty()) {
1571+
Log.e(TAG, "onJoinParse set == null || set.isEmpty() >> return null;");
1572+
return null;
1573+
}
1574+
for (Entry<String, Object> e : entries) {
1575+
String path = e.getKey();
1576+
if (path != null && path.indexOf("/") > 0) {
1577+
slashKeys.add(e); // 以 / 开头的 key,例如 </Table/key@
1578+
} else {
1579+
nonSlashKeys.add(e); // 普通 key,例如 Table: {}
1580+
}
1581+
}
1582+
1583+
Map<String, Object> whereJoinMap = new LinkedHashMap<>();
1584+
1585+
for (Entry<String, Object> e : nonSlashKeys) {
1586+
String tableKey = e.getKey(); // 如 "Location_info"
1587+
Object tableObj = e.getValue(); // value 是 Map
1588+
1589+
if (request.containsKey(tableKey)) {
1590+
whereJoinMap.put(tableKey, tableObj);
1591+
} else {
1592+
Log.w(TAG, "跳过 join 中 key = " + tableKey + ",因为它不在 request 中");
1593+
}
1594+
}
1595+
1596+
1597+
Set<Entry<String, Object>> set = joinMap == null ? null : new LinkedHashSet<>(slashKeys);
1598+
15671599
if (set == null || set.isEmpty()) {
15681600
Log.e(TAG, "onJoinParse set == null || set.isEmpty() >> return null;");
15691601
return null;
@@ -1759,9 +1791,15 @@ else if (join != null){
17591791
j.setAlias(alias);
17601792

17611793
M outerObj = (M) JSON.createJSONObject((Map<String, Object>) outer);
1762-
j.setOuter(outerObj);
1794+
j.setOn(outerObj);
17631795
j.setRequest(requestObj);
17641796

1797+
if (whereJoinMap.containsKey(table)) {
1798+
Object rawOuter = whereJoinMap.get(table);
1799+
M outerObj1 = (M) JSON.createJSONObject((Map<String, Object>) rawOuter);
1800+
j.setOuter(outerObj1);
1801+
}
1802+
17651803
if (arrKey != null) {
17661804
Integer count = getInteger(parentPathObj, apijson.JSONRequest.KEY_COUNT);
17671805
j.setCount(count == null ? getDefaultQueryCount() : count);

APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java

Lines changed: 65 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,21 @@
55

66
package apijson.orm;
77

8-
import java.util.*;
9-
import java.util.Map.Entry;
10-
import java.util.regex.Pattern;
11-
128
import apijson.*;
139
import apijson.orm.Join.On;
1410
import apijson.orm.exception.NotExistException;
1511
import apijson.orm.exception.UnsupportedDataTypeException;
16-
import apijson.orm.model.Access;
17-
import apijson.orm.model.AllColumn;
18-
import apijson.orm.model.AllColumnComment;
19-
import apijson.orm.model.AllTable;
20-
import apijson.orm.model.AllTableComment;
21-
import apijson.orm.model.Column;
22-
import apijson.orm.model.Document;
23-
import apijson.orm.model.ExtendedProperty;
24-
import apijson.orm.model.Function;
25-
import apijson.orm.model.PgAttribute;
26-
import apijson.orm.model.PgClass;
27-
import apijson.orm.model.Request;
28-
import apijson.orm.model.SysColumn;
29-
import apijson.orm.model.SysTable;
30-
import apijson.orm.model.Table;
31-
import apijson.orm.model.TestRecord;
12+
import apijson.orm.model.*;
13+
14+
import java.util.*;
15+
import java.util.Map.Entry;
16+
import java.util.regex.Pattern;
3217

3318
import static apijson.JSON.getBoolean;
3419
import static apijson.JSON.getString;
3520
import static apijson.JSONMap.*;
36-
import static apijson.RequestMethod.DELETE;
37-
import static apijson.RequestMethod.GET;
38-
import static apijson.RequestMethod.POST;
39-
import static apijson.RequestMethod.PUT;
40-
import static apijson.SQL.AND;
41-
import static apijson.SQL.NOT;
42-
import static apijson.SQL.ON;
43-
import static apijson.SQL.OR;
21+
import static apijson.RequestMethod.*;
22+
import static apijson.SQL.*;
4423

4524
/**config sql for JSON Request
4625
* @author Lemon
@@ -1583,7 +1562,7 @@ public String gainGroupString(boolean hasPrefix) {
15831562
continue;
15841563
}
15851564

1586-
SQLConfig<T, M, L> ocfg = join.getOuterConfig();
1565+
SQLConfig<T, M, L> ocfg = join.getOnConfig();
15871566
SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getGroup() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
15881567

15891568
if (cfg != null) {
@@ -1598,6 +1577,23 @@ public String gainGroupString(boolean hasPrefix) {
15981577
first = false;
15991578
}
16001579
}
1580+
1581+
////先处理左/右关联,内关联忽略
1582+
//SQLConfig<T, M, L> outerConfig = join.getOuterConfig();
1583+
//SQLConfig<T, M, L> outerConfig2 = (outerConfig != null && outerConfig.getGroup() != null) || join.isLeftOrRightJoin() ? outerConfig : null;
1584+
//
1585+
//if (outerConfig2 != null) {
1586+
// outerConfig2.setMain(false).setKeyPrefix(true);
1587+
// //if (StringUtil.isEmpty(cfg.getAlias(), true)) {
1588+
// // cfg.setAlias(cfg.getTable());
1589+
// //}
1590+
// String c = ((AbstractSQLConfig<?, ?, ?>) outerConfig2).gainGroupString(false);
1591+
//
1592+
// if (StringUtil.isNotEmpty(c, true)) {
1593+
// joinGroup += (first ? "" : ", ") + c;
1594+
// first = false;
1595+
// }
1596+
//}
16011597
}
16021598
}
16031599

@@ -1659,7 +1655,7 @@ public String gainHavingString(boolean hasPrefix) throws Exception {
16591655
continue;
16601656
}
16611657

1662-
SQLConfig<T, M, L> ocfg = join.getOuterConfig();
1658+
SQLConfig<T, M, L> ocfg = join.getOnConfig();
16631659
SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getHaving() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
16641660

16651661
if (cfg != null) {
@@ -1772,7 +1768,7 @@ public String gainSampleString(boolean hasPrefix) {
17721768
continue;
17731769
}
17741770

1775-
SQLConfig<T, M, L> ocfg = join.getOuterConfig();
1771+
SQLConfig<T, M, L> ocfg = join.getOnConfig();
17761772
SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getSample() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
17771773

17781774
if (cfg != null) {
@@ -1842,7 +1838,7 @@ public String gainLatestString(boolean hasPrefix) {
18421838
continue;
18431839
}
18441840

1845-
SQLConfig<T, M, L> ocfg = join.getOuterConfig();
1841+
SQLConfig<T, M, L> ocfg = join.getOnConfig();
18461842
SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getLatest() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
18471843

18481844
if (cfg != null) {
@@ -1907,7 +1903,7 @@ public String gainPartitionString(boolean hasPrefix) {
19071903
continue;
19081904
}
19091905

1910-
SQLConfig<T, M, L> ocfg = join.getOuterConfig();
1906+
SQLConfig<T, M, L> ocfg = join.getOnConfig();
19111907
SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getPartition() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
19121908

19131909
if (cfg != null) {
@@ -1972,7 +1968,7 @@ public String gainFillString(boolean hasPrefix) {
19721968
continue;
19731969
}
19741970

1975-
SQLConfig<T, M, L> ocfg = join.getOuterConfig();
1971+
SQLConfig<T, M, L> ocfg = join.getOnConfig();
19761972
SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getFill() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
19771973

19781974
if (cfg != null) {
@@ -2038,14 +2034,15 @@ public AbstractSQLConfig<T, M, L> setOrder(String order) {
20382034
public String gainOrderString(boolean hasPrefix) {
20392035
//加上子表的 order
20402036
String joinOrder = "";
2037+
String joinOuterOrder = "";
20412038
if (joinList != null) {
20422039
boolean first = true;
20432040
for (Join<T, M, L> join : joinList) {
20442041
if (join.isAppJoin()) {
20452042
continue;
20462043
}
20472044

2048-
SQLConfig<T, M, L> ocfg = join.getOuterConfig();
2045+
SQLConfig<T, M, L> ocfg = join.getOnConfig();
20492046
SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getOrder() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
20502047

20512048
if (cfg != null) {
@@ -2354,7 +2351,7 @@ public String gainColumnString(boolean inSQLJoin) throws Exception {
23542351
continue;
23552352
}
23562353

2357-
SQLConfig<T, M, L> ocfg = join.getOuterConfig();
2354+
SQLConfig<T, M, L> ocfg = join.getOnConfig();
23582355
boolean isEmpty = ocfg == null || ocfg.getColumn() == null;
23592356
boolean isLeftOrRightJoin = join.isLeftOrRightJoin();
23602357

@@ -3738,8 +3735,9 @@ protected String concatJoinWhereString(String whereString) throws Exception {
37383735
List<Object> pvl = new ArrayList<>(getPreparedValueList());
37393736

37403737
SQLConfig<T, M, L> jc;
3738+
SQLConfig<T, M, L> outerConfig;
37413739
String js;
3742-
3740+
boolean isWsEmpty = StringUtil.isEmpty(ws, true);
37433741
boolean changed = false;
37443742
// 各种 JOIN 没办法统一用 & | !连接,只能按优先级,和 @combine 一样?
37453743
for (Join<T, M, L> j : joinList) {
@@ -3750,6 +3748,24 @@ protected String concatJoinWhereString(String whereString) throws Exception {
37503748
case "@": // APP JOIN
37513749
case "<": // LEFT JOIN
37523750
case ">": // RIGHT JOIN
3751+
outerConfig = j.getOuterConfig();
3752+
if (outerConfig == null){
3753+
break;
3754+
}
3755+
boolean isMain1 = outerConfig.isMain();
3756+
outerConfig.setMain(false).setPrepared(isPrepared()).setPreparedValueList(new ArrayList<Object>());
3757+
String outerWhere = outerConfig.gainWhereString(false);
3758+
3759+
int logic1 = Logic.getType(jt);
3760+
newWs += " ( "
3761+
+ gainCondition(
3762+
Logic.isNot(logic1),
3763+
ws
3764+
+ ( isWsEmpty ? "" : (Logic.isAnd(logic1) ? AND : OR) )
3765+
+ " ( " + outerWhere + " ) "
3766+
)
3767+
+ " ) ";
3768+
changed = true;
37533769
break;
37543770

37553771
case "&": // INNER JOIN: A & B
@@ -3770,7 +3786,7 @@ protected String concatJoinWhereString(String whereString) throws Exception {
37703786
boolean isSideJoin = "^".equals(jt);
37713787
boolean isAntiJoin = "(".equals(jt);
37723788
boolean isForeignJoin = ")".equals(jt);
3773-
boolean isWsEmpty = StringUtil.isEmpty(ws, true);
3789+
//boolean isWsEmpty = StringUtil.isEmpty(ws, true);
37743790

37753791
if (isWsEmpty) {
37763792
if (isOuterJoin) { // ! OUTER JOIN: ! (A | B)
@@ -5211,7 +5227,7 @@ public String gainJoinString() throws Exception {
52115227
);
52125228
}
52135229

5214-
SQLConfig<T, M, L> oc = j.getOuterConfig();
5230+
SQLConfig<T, M, L> oc = j.getOnConfig();
52155231
String ow = null;
52165232
if (oc != null) {
52175233
oc.setPrepared(isPrepared());
@@ -6314,13 +6330,22 @@ else if (joinConfig.getDatabase().equals(config.getDatabase()) == false) {
63146330

63156331
joinConfig.setMain(false).setKeyPrefix(true);
63166332

6333+
if (join.getOn() != null) {
6334+
SQLConfig<T, M, L> onConfig = newSQLConfig(method, table, alias, join.getOn(), null, false, callback);
6335+
onConfig.setMain(false)
6336+
.setKeyPrefix(true)
6337+
.setDatabase(joinConfig.getDatabase())
6338+
.setSchema(joinConfig.getSchema()); //解决主表 JOIN 副表,引号不一致
6339+
6340+
join.setOnConfig(onConfig);
6341+
}
6342+
63176343
if (join.getOuter() != null) {
63186344
SQLConfig<T, M, L> outerConfig = newSQLConfig(method, table, alias, join.getOuter(), null, false, callback);
63196345
outerConfig.setMain(false)
63206346
.setKeyPrefix(true)
63216347
.setDatabase(joinConfig.getDatabase())
63226348
.setSchema(joinConfig.getSchema()); //解决主表 JOIN 副表,引号不一致
6323-
63246349
join.setOuterConfig(outerConfig);
63256350
}
63266351
}

APIJSONORM/src/main/java/apijson/orm/Join.java

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ public class Join<T, M extends Map<String, Object>, L extends List<Object>> {
2525
private List<On> onList; // ON User.id = Moment.userId AND ...
2626

2727
private M request; // { "id@":"/Moment/userId" }
28-
private M outer; // "join": { "</User": { "@order":"id-", "@group":"id", "name~":"a", "tag$":"%a%", "@combine": "name~,tag$" } } 中的 </User 对应值
28+
private M on; // "join": { "</User": { "@order":"id-", "@group":"id", "name~":"a", "tag$":"%a%", "@combine": "name~,tag$" } } 中的 </User 对应值
2929

30+
private M outer; // "join": { "</User": { "key2": value2, "@column": "key2,key3","@group": "key2+" }}
3031
private SQLConfig<T, M, L> joinConfig;
3132
private SQLConfig<T, M, L> cacheConfig;
32-
private SQLConfig<T, M, L> outerConfig;
33+
private SQLConfig<T, M, L> onConfig;
3334

35+
private SQLConfig<T, M, L> outerConfig;
3436

3537
public String getPath() {
3638
return path;
@@ -78,13 +80,29 @@ public M getRequest() {
7880
public void setRequest(M request) {
7981
this.request = request;
8082
}
81-
public M getOuter() {
82-
return outer;
83+
public M getOn() {
84+
return on;
85+
}
86+
public void setOn(M on) {
87+
this.on = on;
8388
}
89+
8490
public void setOuter(M outer) {
8591
this.outer = outer;
8692
}
8793

94+
public M getOuter() {
95+
return outer;
96+
}
97+
98+
public SQLConfig<T, M, L> getOuterConfig() {
99+
return outerConfig;
100+
}
101+
102+
public void setOuterConfig(SQLConfig<T, M, L> outerConfig) {
103+
this.outerConfig = outerConfig;
104+
}
105+
88106
public SQLConfig<T, M, L> getJoinConfig() {
89107
return joinConfig;
90108
}
@@ -97,11 +115,11 @@ public SQLConfig<T, M, L> getCacheConfig() {
97115
public void setCacheConfig(SQLConfig<T, M, L> cacheConfig) {
98116
this.cacheConfig = cacheConfig;
99117
}
100-
public SQLConfig<T, M, L> getOuterConfig() {
101-
return outerConfig;
118+
public SQLConfig<T, M, L> getOnConfig() {
119+
return onConfig;
102120
}
103-
public void setOuterConfig(SQLConfig<T, M, L> outerConfig) {
104-
this.outerConfig = outerConfig;
121+
public void setOnConfig(SQLConfig<T, M, L> onConfig) {
122+
this.onConfig = onConfig;
105123
}
106124

107125
public boolean isOne2One() {

0 commit comments

Comments
 (0)