Skip to content

Commit 6023bc0

Browse files
committed
解决某个字段值为 null 导致中断后续正常返回值;解决 LEFT/RIGHT JOIN 副表关联主表外键的字段取别名导致 SQL 报错
1 parent 0ffe78c commit 6023bc0

File tree

3 files changed

+35
-26
lines changed

3 files changed

+35
-26
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ public JSONObject parseResponse(JSONObject request) {
432432
requestObject.put("sql:generate|cache|execute|maxExecute", getSQLExecutor().getGeneratedSQLCount() + "|" + getSQLExecutor().getCachedSQLCount() + "|" + getSQLExecutor().getExecutedSQLCount() + "|" + getMaxSQLCount());
433433
requestObject.put("depth:count|max", queryDepth + "|" + getMaxQueryDepth());
434434
requestObject.put("time:start|duration|end", startTime + "|" + duration + "|" + endTime);
435+
// TODO 放在 msg 中的调试和提示信息应该单独放一个字段,避免 APIAuto 异常分支不显示提示语或太长,以及 DEBUG 和非 DEBUG 模式下提示语不一致 requestObject.put("debug", debugStr);
435436
if (error != null) {
436437
requestObject.put("throw", error.getClass().getName());
437438
requestObject.put("trace", error.getStackTrace());

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

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public abstract class AbstractSQLConfig implements SQLConfig {
8383
// * 和 / 不能同时出现,防止 /* */ 段注释! # 和 -- 不能出现,防止行注释! ; 不能出现,防止隔断SQL语句!空格不能出现,防止 CRUD,DROP,SHOW TABLES等语句!
8484
private static final Pattern PATTERN_RANGE;
8585
private static final Pattern PATTERN_FUNCTION;
86-
private static final Pattern PATTERN_STRING;
86+
private static final Pattern PATTERN_STRING;
8787

8888
/**
8989
* 表名映射,隐藏真实表名,对安全要求很高的表可以这么做
@@ -1490,9 +1490,8 @@ public String getColumnString(boolean inSQLJoin) throws Exception {
14901490
return "(" + s + ")";
14911491
case GET:
14921492
case GETS:
1493-
boolean isQuery = RequestMethod.isQueryMethod(method); //TODO 这个有啥用?上面应是 getMethod 的值 GET 和 GETS 了。
14941493
String joinColumn = "";
1495-
if (isQuery && joinList != null) {
1494+
if (joinList != null) {
14961495
SQLConfig ecfg;
14971496
SQLConfig cfg;
14981497
String c;
@@ -1501,23 +1500,31 @@ public String getColumnString(boolean inSQLJoin) throws Exception {
15011500
if (j.isAppJoin()) {
15021501
continue;
15031502
}
1504-
1505-
ecfg = j.getOuterConfig();
1506-
if (ecfg != null && ecfg.getColumn() != null) { //优先级更高
1507-
cfg = ecfg;
1508-
}
1509-
else {
1510-
cfg = j.getJoinConfig();
1511-
}
1512-
1513-
if (StringUtil.isEmpty(cfg.getAlias(), true)) {
1514-
cfg.setAlias(cfg.getTable());
1515-
}
1516-
1517-
c = ((AbstractSQLConfig) cfg).getColumnString(true);
1518-
if (StringUtil.isEmpty(c, true) == false) {
1519-
joinColumn += (first ? "" : ", ") + c;
1503+
1504+
if (j.isLeftOrRightJoin()) {
1505+
// 改为 SELECT ViceTable.* 解决 SELECT sum(ViceTable.id) LEFT/RIGHT JOIN (SELECT sum(id) FROM ViceTable...) AS ViceTable
1506+
// 不仅导致 SQL 函数重复计算,还有时导致 SQL 报错或对应字段未返回
1507+
String quote = getQuote();
1508+
joinColumn += (first ? "" : ", ") + quote + (StringUtil.isEmpty(j.getAlias(), true) ? j.getTable() : j.getAlias()) + quote + ".*";
15201509
first = false;
1510+
} else {
1511+
ecfg = j.getOuterConfig();
1512+
if (ecfg != null && ecfg.getColumn() != null) { //优先级更高
1513+
cfg = ecfg;
1514+
}
1515+
else {
1516+
cfg = j.getJoinConfig();
1517+
}
1518+
1519+
if (StringUtil.isEmpty(cfg.getAlias(), true)) {
1520+
cfg.setAlias(cfg.getTable());
1521+
}
1522+
1523+
c = ((AbstractSQLConfig) cfg).getColumnString(true);
1524+
if (StringUtil.isEmpty(c, true) == false) {
1525+
joinColumn += (first ? "" : ", ") + c;
1526+
first = false;
1527+
}
15211528
}
15221529

15231530
inSQLJoin = true;

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,8 @@ protected JSONObject onPutColumn(@NotNull SQLConfig config, @NotNull ResultSet r
542542
if (joinList != null) {
543543
for (Join j : joinList) {
544544
childConfig = j.isAppJoin() ? null : j.getCacheConfig(); //这里用config改了getSQL后再还原很麻烦,所以提前给一个config2更好
545-
545+
546+
// FIXME 副表的 SQL 函数,甚至普通字段都可能从 rsmd.getTableName(columnIndex) 拿到 ""
546547
if (childConfig != null && childTable.equalsIgnoreCase(childConfig.getSQLTable())) {
547548

548549
childConfig.putWhere(j.getKey(), table.get(j.getTargetKey()), true);
@@ -561,13 +562,13 @@ protected JSONObject onPutColumn(@NotNull SQLConfig config, @NotNull ResultSet r
561562
}
562563

563564
Object value = getValue(config, rs, rsmd, tablePosition, table, columnIndex, lable, childMap);
564-
if (value != null) {
565-
if (finalTable == null) {
566-
finalTable = new JSONObject(true);
567-
childMap.put(childSql, finalTable);
568-
}
569-
finalTable.put(lable, value);
565+
// 必须 put 进去,否则某个字段为 null 可能导致中断后续正常返回值 if (value != null) {
566+
if (finalTable == null) {
567+
finalTable = new JSONObject(true);
568+
childMap.put(childSql, finalTable);
570569
}
570+
finalTable.put(lable, value);
571+
// }
571572

572573
return table;
573574
}

0 commit comments

Comments
 (0)