From 3c214394b8484ae422de41e25863d7298fa195ad Mon Sep 17 00:00:00 2001 From: wuzeng Date: Fri, 18 Jul 2025 16:39:06 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E7=8E=B0=E5=9C=A8=E7=9A=84=20Join.j?= =?UTF-8?q?ava=20=E4=B8=AD=20SQLConfig=20outerConfig=20=E9=87=8D=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E6=88=90=20onConfig=20=E5=8F=8A=E5=AF=B9=E5=BA=94?= =?UTF-8?q?=E7=9A=84=20get=20set=20=E6=96=B9=E6=B3=95=EF=BC=8C=E7=84=B6?= =?UTF-8?q?=E5=90=8E=E5=86=8D=E5=8A=A0=E5=9B=9E=E6=9D=A5=20SQLConfig=20out?= =?UTF-8?q?erConfig=EF=BC=8C=E7=84=B6=E5=90=8E=E4=B8=8B=E6=96=B9=E7=9A=84?= =?UTF-8?q?=E9=94=AE=E5=80=BC=E5=AF=B9=E6=94=BE=E5=88=B0=20outerConfig=20?= =?UTF-8?q?=E4=B8=8A=EF=BC=8C=E5=90=8E=E9=9D=A2=E5=86=8D=E5=85=B7=E4=BD=93?= =?UTF-8?q?=20AbstractSQLConfig=20gainWhereString=E3=80=82=201=E3=80=81inn?= =?UTF-8?q?er=20join=20=E6=9C=AC=E8=BA=AB=E6=98=AF=E6=9C=80=E5=A4=96?= =?UTF-8?q?=E9=9D=A2=E5=A2=9E=E5=8A=A0=E6=9D=A1=E4=BB=B6=EF=BC=8C=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E5=A2=9E=E5=8A=A0=202=E3=80=81onConfig=20=20=20=20=20?= =?UTF-8?q?=20=20"@group":=20"key2+"=20=20//=20JOIN=20=E5=A4=96=E5=B1=82?= =?UTF-8?q?=20GROYP=20BY=20key2=20=20=20=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20"@having":=20"count(key3)>0"=20=20//=20JOIN=20?= =?UTF-8?q?=E5=A4=96=E5=B1=82=20HAVING=20count(key3)>0=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20"@order":=20"key2+,key3-"?= =?UTF-8?q?=20=20//=20JOIN=20=E5=A4=96=E5=B1=82=20ORDER=20BY=20key2=20ASC,?= =?UTF-8?q?=20key3=20DESC=20=20=E6=9C=AC=E8=BA=AB=E8=BF=99=E4=BA=9B?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E5=B0=B1=E6=98=AF=E5=8A=A0=E5=88=B0=E6=9C=80?= =?UTF-8?q?=E5=A4=96=E5=B1=82=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/apijson/orm/AbstractParser.java | 42 ++++++- .../java/apijson/orm/AbstractSQLConfig.java | 105 +++++++++++------- .../src/main/java/apijson/orm/Join.java | 34 ++++-- 3 files changed, 131 insertions(+), 50 deletions(-) diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java index eab5a368b..93657a1c3 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java @@ -1563,7 +1563,39 @@ else if (join != null){ throw new UnsupportedDataTypeException(TAG + ".onJoinParse join 只能是 String 或 Map 类型!"); } - Set> set = joinMap == null ? null : joinMap.entrySet(); + List> slashKeys = new ArrayList<>(); + List> nonSlashKeys = new ArrayList<>(); + Set> entries = joinMap == null ? null : joinMap.entrySet(); + + if (entries == null || entries.isEmpty()) { + Log.e(TAG, "onJoinParse set == null || set.isEmpty() >> return null;"); + return null; + } + for (Entry e : entries) { + String path = e.getKey(); + if (path != null && path.indexOf("/") > 0) { + slashKeys.add(e); // 以 / 开头的 key,例如 whereJoinMap = new LinkedHashMap<>(); + + for (Entry e : nonSlashKeys) { + String tableKey = e.getKey(); // 如 "Location_info" + Object tableObj = e.getValue(); // value 是 Map + + if (request.containsKey(tableKey)) { + whereJoinMap.put(tableKey, tableObj); + } else { + Log.w(TAG, "跳过 join 中 key = " + tableKey + ",因为它不在 request 中"); + } + } + + + Set> set = joinMap == null ? null : new LinkedHashSet<>(slashKeys); + ; if (set == null || set.isEmpty()) { Log.e(TAG, "onJoinParse set == null || set.isEmpty() >> return null;"); return null; @@ -1759,9 +1791,15 @@ else if (join != null){ j.setAlias(alias); M outerObj = (M) JSON.createJSONObject((Map) outer); - j.setOuter(outerObj); + j.setOn(outerObj); j.setRequest(requestObj); + if (whereJoinMap.containsKey(table)) { + Object rawOuter = whereJoinMap.get(table); + M outerObj1 = (M) JSON.createJSONObject((Map) rawOuter); + j.setOuter(outerObj1); + } + if (arrKey != null) { Integer count = getInteger(parentPathObj, apijson.JSONRequest.KEY_COUNT); j.setCount(count == null ? getDefaultQueryCount() : count); diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java index de1d17dc1..2d9c156f3 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java @@ -5,42 +5,21 @@ package apijson.orm; -import java.util.*; -import java.util.Map.Entry; -import java.util.regex.Pattern; - import apijson.*; import apijson.orm.Join.On; import apijson.orm.exception.NotExistException; import apijson.orm.exception.UnsupportedDataTypeException; -import apijson.orm.model.Access; -import apijson.orm.model.AllColumn; -import apijson.orm.model.AllColumnComment; -import apijson.orm.model.AllTable; -import apijson.orm.model.AllTableComment; -import apijson.orm.model.Column; -import apijson.orm.model.Document; -import apijson.orm.model.ExtendedProperty; -import apijson.orm.model.Function; -import apijson.orm.model.PgAttribute; -import apijson.orm.model.PgClass; -import apijson.orm.model.Request; -import apijson.orm.model.SysColumn; -import apijson.orm.model.SysTable; -import apijson.orm.model.Table; -import apijson.orm.model.TestRecord; +import apijson.orm.model.*; + +import java.util.*; +import java.util.Map.Entry; +import java.util.regex.Pattern; import static apijson.JSON.getBoolean; import static apijson.JSON.getString; import static apijson.JSONMap.*; -import static apijson.RequestMethod.DELETE; -import static apijson.RequestMethod.GET; -import static apijson.RequestMethod.POST; -import static apijson.RequestMethod.PUT; -import static apijson.SQL.AND; -import static apijson.SQL.NOT; -import static apijson.SQL.ON; -import static apijson.SQL.OR; +import static apijson.RequestMethod.*; +import static apijson.SQL.*; /**config sql for JSON Request * @author Lemon @@ -1574,7 +1553,7 @@ public String gainGroupString(boolean hasPrefix) { continue; } - SQLConfig ocfg = join.getOuterConfig(); + SQLConfig ocfg = join.getOnConfig(); SQLConfig cfg = (ocfg != null && ocfg.getGroup() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { @@ -1589,6 +1568,23 @@ public String gainGroupString(boolean hasPrefix) { first = false; } } + + ////先处理左/右关联,内关联忽略 + //SQLConfig outerConfig = join.getOuterConfig(); + //SQLConfig outerConfig2 = (outerConfig != null && outerConfig.getGroup() != null) || join.isLeftOrRightJoin() ? outerConfig : null; + // + //if (outerConfig2 != null) { + // outerConfig2.setMain(false).setKeyPrefix(true); + // //if (StringUtil.isEmpty(cfg.getAlias(), true)) { + // // cfg.setAlias(cfg.getTable()); + // //} + // String c = ((AbstractSQLConfig) outerConfig2).gainGroupString(false); + // + // if (StringUtil.isNotEmpty(c, true)) { + // joinGroup += (first ? "" : ", ") + c; + // first = false; + // } + //} } } @@ -1650,7 +1646,7 @@ public String gainHavingString(boolean hasPrefix) throws Exception { continue; } - SQLConfig ocfg = join.getOuterConfig(); + SQLConfig ocfg = join.getOnConfig(); SQLConfig cfg = (ocfg != null && ocfg.getHaving() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { @@ -1763,7 +1759,7 @@ public String gainSampleString(boolean hasPrefix) { continue; } - SQLConfig ocfg = join.getOuterConfig(); + SQLConfig ocfg = join.getOnConfig(); SQLConfig cfg = (ocfg != null && ocfg.getSample() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { @@ -1833,7 +1829,7 @@ public String gainLatestString(boolean hasPrefix) { continue; } - SQLConfig ocfg = join.getOuterConfig(); + SQLConfig ocfg = join.getOnConfig(); SQLConfig cfg = (ocfg != null && ocfg.getLatest() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { @@ -1898,7 +1894,7 @@ public String gainPartitionString(boolean hasPrefix) { continue; } - SQLConfig ocfg = join.getOuterConfig(); + SQLConfig ocfg = join.getOnConfig(); SQLConfig cfg = (ocfg != null && ocfg.getPartition() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { @@ -1963,7 +1959,7 @@ public String gainFillString(boolean hasPrefix) { continue; } - SQLConfig ocfg = join.getOuterConfig(); + SQLConfig ocfg = join.getOnConfig(); SQLConfig cfg = (ocfg != null && ocfg.getFill() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { @@ -2029,6 +2025,7 @@ public AbstractSQLConfig setOrder(String order) { public String gainOrderString(boolean hasPrefix) { //加上子表的 order String joinOrder = ""; + String joinOuterOrder = ""; if (joinList != null) { boolean first = true; for (Join join : joinList) { @@ -2036,7 +2033,7 @@ public String gainOrderString(boolean hasPrefix) { continue; } - SQLConfig ocfg = join.getOuterConfig(); + SQLConfig ocfg = join.getOnConfig(); SQLConfig cfg = (ocfg != null && ocfg.getOrder() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { @@ -2345,7 +2342,7 @@ public String gainColumnString(boolean inSQLJoin) throws Exception { continue; } - SQLConfig ocfg = join.getOuterConfig(); + SQLConfig ocfg = join.getOnConfig(); boolean isEmpty = ocfg == null || ocfg.getColumn() == null; boolean isLeftOrRightJoin = join.isLeftOrRightJoin(); @@ -3729,8 +3726,9 @@ protected String concatJoinWhereString(String whereString) throws Exception { List pvl = new ArrayList<>(getPreparedValueList()); SQLConfig jc; + SQLConfig outerConfig; String js; - + boolean isWsEmpty = StringUtil.isEmpty(ws, true); boolean changed = false; // 各种 JOIN 没办法统一用 & | !连接,只能按优先级,和 @combine 一样? for (Join j : joinList) { @@ -3741,6 +3739,24 @@ protected String concatJoinWhereString(String whereString) throws Exception { case "@": // APP JOIN case "<": // LEFT JOIN case ">": // RIGHT JOIN + outerConfig = j.getOuterConfig(); + if (outerConfig == null){ + break; + } + boolean isMain1 = outerConfig.isMain(); + outerConfig.setMain(false).setPrepared(isPrepared()).setPreparedValueList(new ArrayList()); + String outerWhere = outerConfig.gainWhereString(false); + + int logic1 = Logic.getType(jt); + newWs += " ( " + + gainCondition( + Logic.isNot(logic1), + ws + + ( isWsEmpty ? "" : (Logic.isAnd(logic1) ? AND : OR) ) + + " ( " + outerWhere + " ) " + ) + + " ) "; + changed = true; break; case "&": // INNER JOIN: A & B @@ -3761,7 +3777,7 @@ protected String concatJoinWhereString(String whereString) throws Exception { boolean isSideJoin = "^".equals(jt); boolean isAntiJoin = "(".equals(jt); boolean isForeignJoin = ")".equals(jt); - boolean isWsEmpty = StringUtil.isEmpty(ws, true); + //boolean isWsEmpty = StringUtil.isEmpty(ws, true); if (isWsEmpty) { if (isOuterJoin) { // ! OUTER JOIN: ! (A | B) @@ -5202,7 +5218,7 @@ public String gainJoinString() throws Exception { ); } - SQLConfig oc = j.getOuterConfig(); + SQLConfig oc = j.getOnConfig(); String ow = null; if (oc != null) { oc.setPrepared(isPrepared()); @@ -6305,13 +6321,22 @@ else if (joinConfig.getDatabase().equals(config.getDatabase()) == false) { joinConfig.setMain(false).setKeyPrefix(true); + if (join.getOn() != null) { + SQLConfig onConfig = newSQLConfig(method, table, alias, join.getOn(), null, false, callback); + onConfig.setMain(false) + .setKeyPrefix(true) + .setDatabase(joinConfig.getDatabase()) + .setSchema(joinConfig.getSchema()); //解决主表 JOIN 副表,引号不一致 + + join.setOnConfig(onConfig); + } + if (join.getOuter() != null) { SQLConfig outerConfig = newSQLConfig(method, table, alias, join.getOuter(), null, false, callback); outerConfig.setMain(false) .setKeyPrefix(true) .setDatabase(joinConfig.getDatabase()) .setSchema(joinConfig.getSchema()); //解决主表 JOIN 副表,引号不一致 - join.setOuterConfig(outerConfig); } } diff --git a/APIJSONORM/src/main/java/apijson/orm/Join.java b/APIJSONORM/src/main/java/apijson/orm/Join.java index 39ca09a61..411bb29cd 100644 --- a/APIJSONORM/src/main/java/apijson/orm/Join.java +++ b/APIJSONORM/src/main/java/apijson/orm/Join.java @@ -25,12 +25,14 @@ public class Join, L extends List> { private List onList; // ON User.id = Moment.userId AND ... private M request; // { "id@":"/Moment/userId" } - private M outer; // "join": { " joinConfig; private SQLConfig cacheConfig; - private SQLConfig outerConfig; + private SQLConfig onConfig; + private SQLConfig outerConfig; public String getPath() { return path; @@ -78,13 +80,29 @@ public M getRequest() { public void setRequest(M request) { this.request = request; } - public M getOuter() { - return outer; + public M getOn() { + return on; + } + public void setOn(M on) { + this.on = on; } + public void setOuter(M outer) { this.outer = outer; } + public M getOuter() { + return outer; + } + + public SQLConfig getOuterConfig() { + return outerConfig; + } + + public void setOuterConfig(SQLConfig outerConfig) { + this.outerConfig = outerConfig; + } + public SQLConfig getJoinConfig() { return joinConfig; } @@ -97,11 +115,11 @@ public SQLConfig getCacheConfig() { public void setCacheConfig(SQLConfig cacheConfig) { this.cacheConfig = cacheConfig; } - public SQLConfig getOuterConfig() { - return outerConfig; + public SQLConfig getOnConfig() { + return onConfig; } - public void setOuterConfig(SQLConfig outerConfig) { - this.outerConfig = outerConfig; + public void setOnConfig(SQLConfig onConfig) { + this.onConfig = onConfig; } public boolean isOne2One() { From 2122b8c89408bfb48ec60862057cb428c74904fb Mon Sep 17 00:00:00 2001 From: TommyLemon <1184482681@qq.com> Date: Sun, 20 Jul 2025 12:37:47 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BC=98=E5=8C=96=20AbstractParser.java=20?= =?UTF-8?q?=E7=BC=A9=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/apijson/orm/AbstractParser.java | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java index 93657a1c3..8e3c3a291 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java @@ -1563,39 +1563,39 @@ else if (join != null){ throw new UnsupportedDataTypeException(TAG + ".onJoinParse join 只能是 String 或 Map 类型!"); } - List> slashKeys = new ArrayList<>(); - List> nonSlashKeys = new ArrayList<>(); - Set> entries = joinMap == null ? null : joinMap.entrySet(); + List> slashKeys = new ArrayList<>(); + List> nonSlashKeys = new ArrayList<>(); + Set> entries = joinMap == null ? null : joinMap.entrySet(); - if (entries == null || entries.isEmpty()) { - Log.e(TAG, "onJoinParse set == null || set.isEmpty() >> return null;"); - return null; - } - for (Entry e : entries) { - String path = e.getKey(); - if (path != null && path.indexOf("/") > 0) { - slashKeys.add(e); // 以 / 开头的 key,例如 > return null;"); + return null; + } + for (Entry e : entries) { + String path = e.getKey(); + if (path != null && path.indexOf("/") > 0) { + slashKeys.add(e); // 以 / 开头的 key,例如 whereJoinMap = new LinkedHashMap<>(); + Map whereJoinMap = new LinkedHashMap<>(); - for (Entry e : nonSlashKeys) { - String tableKey = e.getKey(); // 如 "Location_info" - Object tableObj = e.getValue(); // value 是 Map + for (Entry e : nonSlashKeys) { + String tableKey = e.getKey(); // 如 "Location_info" + Object tableObj = e.getValue(); // value 是 Map + + if (request.containsKey(tableKey)) { + whereJoinMap.put(tableKey, tableObj); + } else { + Log.w(TAG, "跳过 join 中 key = " + tableKey + ",因为它不在 request 中"); + } + } - if (request.containsKey(tableKey)) { - whereJoinMap.put(tableKey, tableObj); - } else { - Log.w(TAG, "跳过 join 中 key = " + tableKey + ",因为它不在 request 中"); - } - } + Set> set = joinMap == null ? null : new LinkedHashSet<>(slashKeys); - Set> set = joinMap == null ? null : new LinkedHashSet<>(slashKeys); - ; if (set == null || set.isEmpty()) { Log.e(TAG, "onJoinParse set == null || set.isEmpty() >> return null;"); return null;