Skip to content

Commit 77db282

Browse files
committed
解决 APP JOIN 一对多时子数组长度超过预设范围;提升 APP JOIN 一对多的子数组缓存性能;新增对 Year, Month, DayOfWeek 的支持
1 parent 2f890b8 commit 77db282

File tree

2 files changed

+52
-34
lines changed

2 files changed

+52
-34
lines changed

APIJSONORM/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
44
<modelVersion>4.0.0</modelVersion>
55

6-
<groupId>apijson.orm</groupId>
7-
<artifactId>apijson-orm</artifactId>
8-
<version>5.1.5</version>
6+
<groupId>com.github.Tencent</groupId>
7+
<artifactId>APIJSON</artifactId>
8+
<version>5.1.6</version>
99
<packaging>jar</packaging>
1010

1111
<name>APIJSONORM</name>

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

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import java.sql.Blob;
1111
import java.sql.Clob;
1212
import java.sql.Connection;
13-
import java.sql.Date;
13+
import java.util.Date;
1414
import java.sql.DriverManager;
1515
import java.sql.PreparedStatement;
1616
import java.sql.ResultSet;
@@ -20,7 +20,10 @@
2020
import java.sql.Statement;
2121
import java.sql.Time;
2222
import java.sql.Timestamp;
23+
import java.time.DayOfWeek;
2324
import java.time.LocalDateTime;
25+
import java.time.Month;
26+
import java.time.Year;
2427
import java.util.ArrayList;
2528
import java.util.Arrays;
2629
import java.util.Collection;
@@ -548,7 +551,7 @@ else if (curJoin.isOuterJoin() || curJoin.isAntiJoin()) {
548551
// 副表是按常规条件查询,缓存会导致其它同表同条件对象查询结果集为空 childMap.put(viceSql, new JSONObject()); // 缓存固定空数据,避免后续多余查询
549552
}
550553
else {
551-
curItem = (JSONObject) childMap.get(viceSql);
554+
curItem = childMap.get(viceSql);
552555
if (curItem == null) {
553556
curItem = new JSONObject(true);
554557
childMap.put(viceSql, curItem);
@@ -596,8 +599,8 @@ else if (curJoin.isOuterJoin() || curJoin.isAntiJoin()) {
596599

597600
if (isHead == false) {
598601
// @ APP JOIN 查询副表并缓存到 childMap <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
599-
Map<String,List<JSONObject>> appJoinChildMap = new HashMap<>();
600-
childMap.forEach((viceSql,item) -> appJoinChildMap.put(viceSql,Arrays.asList(item)));
602+
Map<String, List<JSONObject>> appJoinChildMap = new HashMap<>();
603+
childMap.forEach((viceSql, item) -> appJoinChildMap.put(viceSql, Arrays.asList(item)));
601604
executeAppJoin(config, resultList, appJoinChildMap);
602605

603606
// @ APP JOIN 查询副表并缓存到 childMap >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@@ -643,24 +646,21 @@ protected void executeAppJoin(SQLConfig config, List<JSONObject> resultList, Map
643646
List<Join> joinList = config.getJoinList();
644647
if (joinList != null) {
645648

646-
SQLConfig jc;
647-
SQLConfig cc;
648-
649649
for (Join join : joinList) {
650650
if (join.isAppJoin() == false) {
651651
Log.i(TAG, "executeAppJoin for (Join j : joinList) >> j.isAppJoin() == false >> continue;");
652652
continue;
653653
}
654654

655-
cc = join.getCacheConfig(); //这里用config改了getSQL后再还原很麻烦,所以提前给一个config2更好
655+
SQLConfig cc = join.getCacheConfig(); //这里用config改了getSQL后再还原很麻烦,所以提前给一个config2更好
656656
if (cc == null) {
657657
if (Log.DEBUG) {
658658
throw new NullPointerException("服务器内部错误, executeAppJoin cc == null ! 导致不能缓存 @ APP JOIN 的副表数据!");
659659
}
660660
continue;
661661
}
662662

663-
jc = join.getJoinConfig();
663+
SQLConfig jc = join.getJoinConfig();
664664

665665
List<On> onList = join.getOnList();
666666
int size = onList == null ? 0 : onList.size();
@@ -689,8 +689,8 @@ protected void executeAppJoin(SQLConfig config, List<JSONObject> resultList, Map
689689
}
690690

691691
// 替换为 "id{}": [userId1, userId2, userId3...]
692-
jc.putWhere(ok, null, false); // remove orginKey
693-
jc.putWhere(on.getKey() + "{}", targetValueList, true); // add orginKey{} }
692+
jc.putWhere(ok, null, false); // remove originKey
693+
jc.putWhere(on.getKey() + "{}", targetValueList, true); // add originKey{} }
694694
}
695695
}
696696

@@ -728,25 +728,28 @@ protected void executeAppJoin(SQLConfig config, List<JSONObject> resultList, Map
728728
executedSQLDuration += System.currentTimeMillis() - executedSQLStartTime;
729729
}
730730

731+
int childCount = cc.getCount();
732+
int allChildCount = childCount*config.getCount(); // 所有分组子项数量总和
733+
int count = 0;
734+
731735
int index = -1;
732736

733737
long startTime2 = System.currentTimeMillis();
734738
ResultSetMetaData rsmd = rs.getMetaData();
735739
final int length = rsmd.getColumnCount();
736740
sqlResultDuration += System.currentTimeMillis() - startTime2;
737741

738-
JSONObject result;
739-
String cacheSql;
742+
Map<String, Boolean> skipMap = new HashMap<>();
740743

741744
long lastCursorTime = System.currentTimeMillis();
742-
while (rs.next()) { //FIXME 同时有 @ APP JOIN 和 < 等 SQL JOIN 时,next = false 总是无法进入循环,导致缓存失效,可能是连接池或线程问题
745+
while ((allChildCount <= 0 || count < allChildCount) && rs.next()) { //FIXME 同时有 @ APP JOIN 和 < 等 SQL JOIN 时,next = false 总是无法进入循环,导致缓存失效,可能是连接池或线程问题
743746
sqlResultDuration += System.currentTimeMillis() - lastCursorTime;
744747
lastCursorTime = System.currentTimeMillis();
745748

746749
index ++;
747750
Log.d(TAG, "\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n executeAppJoin while (rs.next()){ index = " + index + "\n\n");
748751

749-
result = new JSONObject(true);
752+
JSONObject result = new JSONObject(true);
750753

751754
for (int i = 1; i <= length; i++) {
752755
result = onPutColumn(jc, rs, rsmd, index, result, i, null, null);
@@ -757,24 +760,33 @@ protected void executeAppJoin(SQLConfig config, List<JSONObject> resultList, Map
757760
Log.d(TAG, "\n executeAppJoin while (rs.next()) { resultList.put( " + index + ", result); "
758761
+ "\n >>>>>>>>>>>>>>>>>>>>>>>>>>> \n\n");
759762

760-
//缓存到 childMap
761763
if (onList != null) {
762-
for (On on : onList) {
764+
for (On on : onList) { // APP JOIN 应该有且只有一个 ON 条件
763765
String ok = on.getOriginKey();
764766
String vk = ok.substring(0, ok.length() - 1);
765767
//TODO 兼容复杂关联
766768
cc.putWhere(on.getKey(), result.get(on.getKey()), true);
767769
}
768770
}
769-
cacheSql = cc.getSQL(false);
770-
List<JSONObject> results = childMap.get(cacheSql);
771-
if (results == null) {
772-
results = new ArrayList<>();
773-
childMap.put(cacheSql, results);
774-
}
775-
results.add(result);
776-
Log.d(TAG, ">>> executeAppJoin childMap.put('" + cacheSql + "', result); childMap.size() = " + childMap.size());
777-
}
771+
772+
String cacheSql = cc.getSQL(false);
773+
List<JSONObject> results = childMap.get(cacheSql);
774+
775+
if (results == null || skipMap.get(cacheSql) == null) { // 避免添加重复数据
776+
results = new ArrayList<>(childCount);
777+
childMap.put(cacheSql, results);
778+
skipMap.put(cacheSql, Boolean.TRUE);
779+
}
780+
781+
if (childCount <= 0 || results.size() < childCount) { // 避免超过子数组每页数量
782+
// if (count == 1 && results.isEmpty() == false) { // 避免添加重复数据
783+
// results.clear();
784+
// }
785+
results.add(result); //缓存到 childMap
786+
count ++;
787+
Log.d(TAG, ">>> executeAppJoin childMap.put('" + cacheSql + "', result); childMap.size() = " + childMap.size());
788+
}
789+
}
778790
}
779791
finally {
780792
if (rs != null) {
@@ -910,14 +922,20 @@ protected Object getValue(@NotNull SQLConfig config, @NotNull ResultSet rs, @Not
910922
else if (value instanceof Timestamp) {
911923
value = ((Timestamp) value).toString();
912924
}
913-
else if (value instanceof Date) {
925+
else if (value instanceof Date) { // java.sql.Date 和 java.sql.Time 都继承 java.util.Date
914926
value = ((Date) value).toString();
915927
}
916-
else if (value instanceof Time) {
917-
value = ((Time) value).toString();
928+
else if (value instanceof LocalDateTime) {
929+
value = ((LocalDateTime) value).toString();
930+
}
931+
else if (value instanceof Year) {
932+
value = ((Year) value).getValue();
933+
}
934+
else if (value instanceof Month) {
935+
value = ((Month) value).getValue();
918936
}
919-
else if (value instanceof LocalDateTime) {
920-
value = ((LocalDateTime) value).toString();
937+
else if (value instanceof DayOfWeek) {
938+
value = ((DayOfWeek) value).getValue();
921939
}
922940
else if (value instanceof String && isJSONType(config, rsmd, columnIndex, lable)) { //json String
923941
castToJson = true;

0 commit comments

Comments
 (0)