2525import java .util .List ;
2626import java .util .Map ;
2727import java .util .Map .Entry ;
28+ import java .util .Objects ;
2829import java .util .Set ;
2930
3031import com .alibaba .fastjson .JSON ;
@@ -267,39 +268,147 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknowType) throws
267268
268269 //<SELECT * FROM Comment WHERE momentId = '470', { id: 1, content: "csdgs" }>
269270 childMap = new HashMap <>(); //要存到cacheMap
271+ // Map<Integer, Join> columnIndexAndJoinMap = new HashMap<>(length);
272+ String lastTableName = null ; // 默认就是主表 config.getTable();
273+ int lastViceTableStart = 0 ;
274+ int lastViceColumnStart = 0 ;
275+ Join lastJoin = null ;
276+ // TODO String[] columnIndexAndTableMap = new String[length];
270277 // WHERE id = ? AND ... 或 WHERE ... AND id = ? 强制排序 remove 再 put,还是重新 getSQL吧
271278
272279
273- boolean hasJoin = config .hasJoin ();
274- int viceColumnStart = length + 1 ; //第一个副表字段的index
280+ List <Join > joinList = config .getJoinList ();
281+ boolean hasJoin = config .hasJoin () && joinList != null && ! joinList .isEmpty ();
282+
283+ // 直接用数组存取更快 Map<Integer, Join> columnIndexAndJoinMap = isExplain || ! hasJoin ? null : new HashMap<>(length);
284+ Join [] columnIndexAndJoinMap = isExplain || ! hasJoin ? null : new Join [length ];
285+
286+ // int viceColumnStart = length + 1; //第一个副表字段的index
275287 while (rs .next ()) {
276288 index ++;
277289 Log .d (TAG , "\n \n <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n execute while (rs.next()){ index = " + index + "\n \n " );
278290
279291 JSONObject item = new JSONObject (true );
280-
292+ boolean isMain = true ;
293+
281294 for (int i = 1 ; i <= length ; i ++) {
282295
283296 // if (hasJoin && viceColumnStart > length && config.getSQLTable().equalsIgnoreCase(rsmd.getTableName(i)) == false) {
284297 // viceColumnStart = i;
285298 // }
286299
287300 // bugfix-修复非常规数据库字段,获取表名失败导致输出异常
288- if (isExplain == false && hasJoin && viceColumnStart > length ) {
289- List <String > column = config .getColumn ();
290- String sqlTable = rsmd .getTableName (i );
291- if (config .isClickHouse ()&&(sqlTable .startsWith ("`" )||sqlTable .startsWith ("\" " ))){
292- sqlTable = sqlTable .substring (1 ,sqlTable .length ()-1 );
301+ Join curJoin = columnIndexAndJoinMap == null ? null : columnIndexAndJoinMap [i - 1 ]; // columnIndexAndJoinMap.get(i);
302+
303+ // 为什么 isExplain == false 不用判断?因为所有字段都在一张 Query Plan 表
304+ if (index <= 0 && hasJoin && ! isExplain ) { // && viceColumnStart > length) {
305+
306+ SQLConfig curConfig = curJoin == null || ! curJoin .isSQLJoin () ? null : curJoin .getCacheConfig ();
307+ List <String > curColumn = curConfig == null ? null : curConfig .getColumn ();
308+ String sqlTable = curConfig == null ? null : curConfig .getSQLTable ();
309+
310+ List <String > column = config .getColumn ();
311+ int mainColumnSize = column == null ? 0 : column .size ();
312+ boolean toFindJoin = mainColumnSize <= 0 || i > mainColumnSize ; // 主表就不用找 JOIN 配置
313+
314+ if (StringUtil .isEmpty (sqlTable , true )) {
315+ if (toFindJoin ) { // 在主表字段数量内的都归属主表
316+ sqlTable = rsmd .getTableName (i ); // SQL 函数甚至部分字段都不返回表名,当然如果没传 @column 生成的 Table.* 则返回的所有字段都会带表名
317+
318+ if (StringUtil .isEmpty (sqlTable , true )) { // hasJoin 已包含这个判断 && joinList != null) {
319+
320+ int nextViceColumnStart = lastViceColumnStart ; // 主表没有 @column 时会偏小 lastViceColumnStart
321+ for (int j = lastViceTableStart ; j < joinList .size (); j ++) { // 查找副表 @column,定位字段所在表
322+ Join join = joinList .get (j );
323+ SQLConfig cfg = join == null || ! join .isSQLJoin () ? null : join .getJoinConfig ();
324+ List <String > c = cfg == null ? null : cfg .getColumn ();
325+
326+ nextViceColumnStart += (
327+ c != null && ! c .isEmpty () ? c .size ()
328+ : (Objects .equals (sqlTable , lastTableName ) || sqlTable .equalsIgnoreCase (lastTableName ) ? 1 : 0 )
329+ );
330+ if (i < nextViceColumnStart ) {
331+ sqlTable = cfg .getSQLTable ();
332+ lastViceTableStart = j ; // 避免后面的空 @column 表内字段被放到之前的空 @column 表
333+
334+ curJoin = join ;
335+ curConfig = cfg ;
336+ curColumn = c ;
337+
338+ toFindJoin = false ;
339+ isMain = false ;
340+ break ;
341+ }
342+ }
343+ }
344+
345+ // 没有 @column,仍然定位不了,用前一个 table 名。FIXME 如果刚好某个表内第一个字段是就是 SQL 函数?
346+ if (StringUtil .isEmpty (sqlTable , true )) {
347+ sqlTable = lastTableName ;
348+ toFindJoin = false ;
349+ }
350+ }
293351 }
294- if (column != null && column . isEmpty () == false ) {
295- viceColumnStart = column . size () + 1 ;
352+ else if (config . isClickHouse () && ( sqlTable . startsWith ( "`" ) || sqlTable . startsWith ( " \" " ))) {
353+ sqlTable = sqlTable . substring ( 1 , sqlTable . length () - 1 ) ;
296354 }
297- else if (config .getSQLTable ().equalsIgnoreCase (sqlTable ) == false ) {
298- viceColumnStart = i ;
355+
356+ if ((sqlTable == null && lastTableName != null ) || (sqlTable != null && ! sqlTable .equalsIgnoreCase (lastTableName ))) {
357+ lastTableName = sqlTable ;
358+ lastViceColumnStart = i ;
359+
360+ if (toFindJoin ) { // 找到对应的副表 JOIN 配置
361+ for (int j = lastViceTableStart ; j < joinList .size (); j ++) { // 查找副表 @column,定位字段所在表
362+ Join join = joinList .get (j );
363+ SQLConfig cfg = join == null || ! join .isSQLJoin () ? null : join .getJoinConfig ();
364+
365+ if (cfg != null && sqlTable != null && sqlTable .equalsIgnoreCase (cfg .getSQLTable ())) {
366+ lastViceTableStart = j ; // 避免后面的空 @column 表内字段被放到之前的空 @column 表
367+
368+ curJoin = join ;
369+ curConfig = cfg ;
370+ curColumn = curConfig == null ? null : curConfig .getColumn ();
371+
372+ isMain = false ;
373+ break ;
374+ }
375+ }
376+ }
299377 }
378+
379+ if (isMain ) {
380+ lastViceColumnStart ++;
381+ }
382+ else {
383+ if (curJoin == null ) {
384+ curJoin = lastJoin ;
385+ }
386+ else {
387+ lastJoin = curJoin ;
388+ }
389+
390+ if (curColumn == null ) {
391+ curConfig = curJoin == null || ! curJoin .isSQLJoin () ? null : curJoin .getJoinConfig ();
392+ curColumn = curConfig == null ? null : curConfig .getColumn ();
393+ }
394+
395+ // 解决后面的表内 SQL 函数被放到之前的空 @column 表
396+ if (curColumn == null || curColumn .isEmpty ()) {
397+ lastViceColumnStart ++;
398+ }
399+ }
400+
401+ columnIndexAndJoinMap [i - 1 ] = curJoin ; // columnIndexAndJoinMap.put(i, curJoin); // TODO columnIndexAndTableMap[i] = sqlTable 提速?
402+
403+ // if (column != null && column.isEmpty() == false) {
404+ // viceColumnStart = column.size() + 1;
405+ // }
406+ // else if (config.getSQLTable().equalsIgnoreCase(sqlTable) == false) {
407+ // viceColumnStart = i;
408+ // }
300409 }
301410
302- item = onPutColumn (config , rs , rsmd , index , item , i , isExplain == false && hasJoin && i >= viceColumnStart ? childMap : null );
411+ item = onPutColumn (config , rs , rsmd , index , item , i , curJoin , childMap ); // isExplain == false && hasJoin && i >= viceColumnStart ? childMap : null);
303412 }
304413
305414 resultList = onPutTable (config , rs , rsmd , resultList , index , item );
@@ -391,21 +500,21 @@ protected void executeAppJoin(SQLConfig config, List<JSONObject> resultList, Map
391500 SQLConfig jc ;
392501 SQLConfig cc ;
393502
394- for (Join j : joinList ) {
395- if (j .isAppJoin () == false ) {
503+ for (Join join : joinList ) {
504+ if (join .isAppJoin () == false ) {
396505 Log .i (TAG , "executeAppJoin for (Join j : joinList) >> j.isAppJoin() == false >> continue;" );
397506 continue ;
398507 }
399508
400- cc = j .getCacheConfig (); //这里用config改了getSQL后再还原很麻烦,所以提前给一个config2更好
509+ cc = join .getCacheConfig (); //这里用config改了getSQL后再还原很麻烦,所以提前给一个config2更好
401510 if (cc == null ) {
402511 if (Log .DEBUG ) {
403512 throw new NullPointerException ("服务器内部错误, executeAppJoin cc == null ! 导致不能缓存 @ APP JOIN 的副表数据!" );
404513 }
405514 continue ;
406515 }
407516
408- jc = j .getJoinConfig ();
517+ jc = join .getJoinConfig ();
409518
410519 //取出 "id@": "@/User/userId" 中所有 userId 的值
411520 List <Object > targetValueList = new ArrayList <>();
@@ -414,7 +523,7 @@ protected void executeAppJoin(SQLConfig config, List<JSONObject> resultList, Map
414523
415524 for (int i = 0 ; i < resultList .size (); i ++) {
416525 mainTable = resultList .get (i );
417- targetValue = mainTable == null ? null : mainTable .get (j .getTargetKey ());
526+ targetValue = mainTable == null ? null : mainTable .get (join .getTargetKey ());
418527
419528 if (targetValue != null && targetValueList .contains (targetValue ) == false ) {
420529 targetValueList .add (targetValue );
@@ -423,8 +532,8 @@ protected void executeAppJoin(SQLConfig config, List<JSONObject> resultList, Map
423532
424533
425534 //替换为 "id{}": [userId1, userId2, userId3...]
426- jc .putWhere (j .getOriginKey (), null , false ); // remove orginKey
427- jc .putWhere (j .getKey () + "{}" , targetValueList , true ); // add orginKey{}
535+ jc .putWhere (join .getOriginKey (), null , false ); // remove orginKey
536+ jc .putWhere (join .getKey () + "{}" , targetValueList , true ); // add orginKey{}
428537
429538 jc .setMain (true ).setPreparedValueList (new ArrayList <>());
430539
@@ -462,7 +571,7 @@ protected void executeAppJoin(SQLConfig config, List<JSONObject> resultList, Map
462571
463572 for (int i = 1 ; i <= length ; i ++) {
464573
465- result = onPutColumn (jc , rs , rsmd , index , result , i , null );
574+ result = onPutColumn (jc , rs , rsmd , index , result , i , null , null );
466575 }
467576
468577 //每个 result 都要用新的 SQL 来存 childResultMap = onPutTable(config, rs, rsmd, childResultMap, index, result);
@@ -471,7 +580,7 @@ protected void executeAppJoin(SQLConfig config, List<JSONObject> resultList, Map
471580 + "\n >>>>>>>>>>>>>>>>>>>>>>>>>>> \n \n " );
472581
473582 //缓存到 childMap
474- cc .putWhere (j .getKey (), result .get (j .getKey ()), true );
583+ cc .putWhere (join .getKey (), result .get (join .getKey ()), true );
475584 cacheSql = cc .getSQL (false );
476585 childMap .put (cacheSql , result );
477586
@@ -512,7 +621,7 @@ protected void executeAppJoin(SQLConfig config, List<JSONObject> resultList, Map
512621 * @throws Exception
513622 */
514623 protected JSONObject onPutColumn (@ NotNull SQLConfig config , @ NotNull ResultSet rs , @ NotNull ResultSetMetaData rsmd
515- , final int tablePosition , @ NotNull JSONObject table , final int columnIndex , Map <String , JSONObject > childMap ) throws Exception {
624+ , final int tablePosition , @ NotNull JSONObject table , final int columnIndex , Join join , Map <String , JSONObject > childMap ) throws Exception {
516625
517626 if (isHideColumn (config , rs , rsmd , tablePosition , table , columnIndex , childMap )) {
518627 Log .i (TAG , "onPutColumn isHideColumn(config, rs, rsmd, tablePosition, table, columnIndex, childMap) >> return table;" );
@@ -524,40 +633,40 @@ protected JSONObject onPutColumn(@NotNull SQLConfig config, @NotNull ResultSet r
524633 // int dotIndex = lable.indexOf(".");
525634 String lable = getKey (config , rs , rsmd , tablePosition , table , columnIndex , childMap );
526635
527- String childTable = childMap == null ? null : rsmd .getTableName (columnIndex ); //dotIndex < 0 ? null : lable.substring(0, dotIndex);
636+ // String childTable = childMap == null ? null : sqlTableName; // rsmd.getTableName(columnIndex); //dotIndex < 0 ? null : lable.substring(0, dotIndex);
528637
529638 JSONObject finalTable = null ;
530639 String childSql = null ;
531- SQLConfig childConfig = null ;
532-
533- if (childTable == null ) {
640+
641+ SQLConfig childConfig = join == null || join . isSQLJoin () == false ? null : join . getCacheConfig ();
642+ if (childConfig == null ) {
534643 finalTable = table ;
535644 }
536645 else {
537646 // lable = column;
538647
539648 //<sql, Table>
540649
541- List <Join > joinList = config .getJoinList ();
542- if (joinList != null ) {
543- for (Join j : joinList ) {
544- childConfig = j .isAppJoin () ? null : j .getCacheConfig (); //这里用config改了getSQL后再还原很麻烦,所以提前给一个config2更好
650+ // List<Join> joinList = config.getJoinList();
651+ // if (joinList != null) {
652+ // for (Join j : joinList) {
653+ // childConfig = j.isAppJoin() ? null : j.getCacheConfig(); //这里用config改了getSQL后再还原很麻烦,所以提前给一个config2更好
545654
546655 // FIXME 副表的 SQL 函数,甚至普通字段都可能从 rsmd.getTableName(columnIndex) 拿到 ""
547- if (childConfig != null && childTable .equalsIgnoreCase (childConfig .getSQLTable ())) {
656+ // if (childConfig != null && childTable.equalsIgnoreCase(childConfig.getSQLTable())) {
548657
549- childConfig .putWhere (j .getKey (), table .get (j .getTargetKey ()), true );
658+ childConfig .putWhere (join .getKey (), table .get (join .getTargetKey ()), true );
550659 childSql = childConfig .getSQL (false );
551660
552661 if (StringUtil .isEmpty (childSql , true )) {
553662 return table ;
554663 }
555664
556665 finalTable = (JSONObject ) childMap .get (childSql );
557- break ;
558- }
559- }
560- }
666+ // break;
667+ // }
668+ // }
669+ // }
561670
562671 }
563672
0 commit comments