@@ -475,7 +475,7 @@ public static boolean isContainKeyInArray(String key, String[] array) {
475475
476476 /**获取单个对象,该对象处于parentObject内
477477 * @param parentPath parentObject的路径
478- * @param parentConfig
478+ * @param parentConfig 对子object的SQL查询配置,需要传两个层级
479479 * @param name parentObject的key
480480 * @param request parentObject的value
481481 * @return
@@ -494,15 +494,13 @@ private JSONObject getObject(String parentPath, final QueryConfig parentConfig,
494494 && isInRelationMap (path ) == false ) {
495495 return request ;
496496 }
497- //优化查询性能并避免"[]":{"0":{"1":{}}}这种导致第3层当成[]的直接子Object
497+ //为第二遍parseRelation = true服务, 优化查询性能并避免"[]":{"0":{"1":{}}}这种导致第3层当成[]的直接子Object
498498 final boolean isArrayChild = parentConfig != null && StringUtil .isNumer (name ) && ("" + parentConfig .getPosition ()).equals (name );
499+ final String table = isArrayChild ? null : Pair .parseEntry (name , true ).getKey ();
500+ final boolean isTableKey = isArrayChild == false && isTableKey (table );
501+ Log .d (TAG , "getObject table = " + table + "; isTableKey = " + isTableKey );
499502
500- String table = Pair .parseEntry (name , true ).getKey ();
501- Log .d (TAG , "getObject table = " + table );
502503
503-
504-
505-
506504 boolean containRelation = false ;
507505
508506 JSONObject transferredRequest = new JSONObject (true );//must init
@@ -527,8 +525,16 @@ && isInRelationMap(path) == false) {
527525 if (isArrayKey (key )) {//APIJSON Array
528526 result = getArray (path , parentConfig , key , (JSONObject ) value );
529527 } else {//APIJSON Object
530- result = getObject (path , isArrayChild == false || isFirst == false //以第0个JSONObject为准
531- ? null : parentConfig , key , (JSONObject ) value );
528+ result = getObject (path , isFirst && isArrayChild //以第0个JSONObject为准
529+ ? parentConfig : null , key , (JSONObject ) value );
530+
531+ //如果第0个都为空,那后面的也都无意义了。
532+ if (isFirst && isArrayChild && (result == null || result .isEmpty ())) {
533+ Log .d (TAG , "getObject isFirst && isArrayChild"
534+ + " && (result == null || result.isEmpty()) >> return null;" );
535+ return null ;
536+ }
537+
532538 isFirst = false ;//[]里第一个不能为[]
533539 }
534540 Log .i (TAG , "getObject key = " + key + "; result = " + result );
@@ -554,7 +560,6 @@ && isInRelationMap(path) == false) {
554560 //GET <<<<<<<<<<<<<<<<<<<<<<<<<
555561 JSONObject arrayRequest = new JSONObject ();
556562 arrayRequest .put (QueryConfig .ID , request .get (QueryConfig .ID ));
557- // arrayRequest.setColumn(realKey);//put请求会对id添加功能符?
558563 arrayRequest .put (JSONRequest .KEY_COLUMN , realKey );
559564 JSONRequest getRequest = new JSONRequest (table , arrayRequest );
560565 JSONObject response = new Parser ().parseResponse (getRequest );
@@ -596,46 +601,45 @@ && isInRelationMap(path) == false) {
596601 throw new IllegalArgumentException ("\" key@\" : 后面必须为依赖路径String!" );
597602 }
598603 System .out .println ("getObject key.endsWith(@) >> parseRelation = " + parseRelation );
599- String replaceKey = key .substring (0 , key .length () - 1 );//key{}@ getRealKey(requestMethod, key, false, false);
604+ String replaceKey = key .substring (0 , key .length () - 1 );//key{}@ getRealKey
600605 String keyPath = getAbsPath (path , replaceKey );
601- String valuePath ;// = new String((String) value);
602-
603- if (parseRelation ) {
604- //不是能直接获取到valuePath吗?因为更新?
605- valuePath = getRelationValuePath (keyPath );
606- Object target = getValueByPath (valuePath , true );
607- Log .d (TAG , "getObject valuePath = " + valuePath + "; target = " + target );
608- if (valuePath .equals (target ) && isTableKey (table )) {
609- Log .e (TAG , "getObject ((String) value).equals(target) && isTableKey(table) >> return null;" );
610- return null ;//parseRelation时还获取不到就不用再做无效的query了。不考虑 Table:{Table:{}}嵌套
611- }
612- //还要isInRelationMap(path)判断 removeRelation(keyPath);
613- // updateRelation(getAbsPath(path, key), keyPath);//request结构已改变,需要更新依赖关系
606+ String valuePath = parseRelation ? getRelationValuePath (keyPath ) : new String ((String ) value );
614607
608+ if (valuePath .startsWith (SEPARATOR )) {
609+ valuePath = getAbsPath (parentPath , valuePath );
610+ }
611+ //先尝试获取,尽量保留缺省依赖路径,这样就不需要担心路径改变
612+ Object target = getValueByPath (valuePath , true );
613+ Log .i (TAG , "getObject valuePath = " + valuePath + "; target = " + target );
614+
615+ if (valuePath .equals (target )) {//必须valuePath和保证getValueByPath传进去的一致!
616+ Log .i (TAG , "getObject target != null && target instanceof String"
617+ + " && ((String) target).startsWith(valuePath) >> " );
618+ if (parseRelation ) {
619+ if (isTableKey ) {
620+ Log .e (TAG , "getObject parseRelation >> isTableKey(table) >> return null;" );
621+ return null ;//parseRelation时还获取不到就不用再做无效的query了。不考虑 Table:{Table:{}}嵌套
622+ } else {
623+ Log .d (TAG , "getObject parseRelation >> isTableKey(table) == false >> continue;" );
624+ continue ;//舍去,对Table无影响
625+ }
626+ } else {//标记并存放依赖关系
627+ Log .i (TAG , "getObject parseRelation == false"
628+ + " >> containRelation = true; putRelation(keyPath, valuePath);" );
629+ containRelation = true ;
630+ putRelation (keyPath , valuePath );
631+ }
632+ } else {//直接替换原来的key@:path为key:target
633+ Log .i (TAG , "getObject >> key = replaceKey; value = target;" );
615634 key = replaceKey ;
616635 value = target ;
617- } else {
618- //尽量保留缺省依赖路径,这样就不需要担心路径改变
619- valuePath = new String ((String ) value );
620- //先尝试获取
621- if (valuePath .startsWith (SEPARATOR )) {
622- valuePath = getAbsPath (parentPath , valuePath );
623- }
624- // Object target = getValueByPath((String) value);
625- // Log.d(TAG, "getObject value = " + value + "; target = " + target);
626- // if (target == null || ((String) value).equals(target)) {//标记并存放依赖关系
627- containRelation = true ;
628- putRelation (keyPath , valuePath );
629- // } else {//直接替换原来的key@:path为key:target
630- // transferredRequest.remove(key);
631- // transferredRequest.put(replaceKey, target);
632- // }
633636 }
637+ Log .d (TAG , "getObject key = " + key + "; value = " + value );
634638 }
635639
636640 if (key .endsWith ("()" )) {
637641 if (value instanceof String == false ) {
638- throw new IllegalArgumentException (" \" key() \" : 后面必须为函数String!" );
642+ throw new IllegalArgumentException (path + "/" + key + "():function() 后面必须为函数String!" );
639643 }
640644 functionMap .put (key , (String ) value );
641645 } else if (key .startsWith ("@" ) && QueryConfig .TABLE_KEY_LIST .contains (key ) == false ) {
@@ -650,10 +654,11 @@ && isInRelationMap(path) == false) {
650654
651655 boolean query = false ;
652656 //执行SQL操作数据库
653- if (containRelation == false && isTableKey ( table ) ) {//提高性能
657+ if (containRelation == false && isTableKey ) {//提高性能
654658 if (parseRelation == false || isInRelationMap (path )) {//避免覆盖原来已经获取的
655659 query = true ;
656660 // keyValuePathMap.remove(path);
661+ //移除所有startswith path的keyPath?
657662 QueryConfig config = newQueryConfig (table , transferredRequest );
658663
659664 if (parentConfig == null ) {//导致全部都是第0个 || isArrayChild == false) {
@@ -714,7 +719,7 @@ && isInRelationMap(path) == false) {
714719
715720 /**获取对象数组,该对象数组处于parentObject内
716721 * @param parentPath parentObject的路径
717- * @param parentConfig parentObject对子object的SQL查询配置 ,需要传两个层级
722+ * @param parentConfig 对子object的SQL查询配置 ,需要传两个层级
718723 * @param name parentObject的key
719724 * @param request parentObject的value
720725 * @return 转为JSONArray不可行,因为会和被当成条件的key:JSONArray冲突。好像一般也就key{}:JSONArray用到??
@@ -733,18 +738,16 @@ private JSONObject getArray(String parentPath, QueryConfig parentConfig, String
733738 String path = getAbsPath (parentPath , name );
734739
735740 int page = 0 , count = 0 , total = 0 ;
736- try {
737- page = request .getIntValue (JSONRequest .KEY_PAGE );
738- count = request .getIntValue (JSONRequest .KEY_COUNT );
739- } catch (Exception e ) {
740- Log .i (TAG , "getArray try { page = arrayObject.getIntValue(page); ..." +
741- " >> } catch (Exception e) {\n " + e .getMessage ());
742- }
741+
742+ count = request .getIntValue (JSONRequest .KEY_COUNT );
743+ page = request .getIntValue (JSONRequest .KEY_PAGE );
744+ request .remove (JSONRequest .KEY_COUNT );
745+ request .remove (JSONRequest .KEY_PAGE );
746+
743747 if (count <= 0 || count > 100 ) {//count最大为100
744748 count = 100 ;
745749 }
746750
747- String firstTableKey = null ;
748751 //最好先获取第一个table的所有项(where条件),填充一个列表?
749752 Set <String > set = new LinkedHashSet <>(request .keySet ());
750753 if (count <= 0 || count > 5 ) {//5以下不优化长度
@@ -755,13 +758,6 @@ private JSONObject getArray(String parentPath, QueryConfig parentConfig, String
755758 table = Pair .parseEntry (key , true ).getKey ();
756759 value = isTableKey (table ) ? request .get (key ) : null ;
757760 if (value != null && value instanceof JSONObject ) {// && value.isEmpty() == false) {
758- // totalCount = QueryHelper.getInstance().getCount(key);
759- firstTableKey = key ;
760- // JSONObject response = new Parser(HEAD)
761- // .parseResponse(new JSONRequest(key, object));
762- // JSONObject target = response == null ? null : response.getJSONObject(key);
763- // total = target == null ? 0 : target.getIntValue(JSONResponse.KEY_COUNT);
764-
765761 total = estimateMaxCount (path , table , (JSONObject ) value );
766762 break ;
767763 }
@@ -772,64 +768,55 @@ private JSONObject getArray(String parentPath, QueryConfig parentConfig, String
772768 }
773769 if (count > total ) {
774770 count = total ;
775- request .put (JSONRequest .KEY_COUNT , count );
776- // set = request.keySet();
777771 }
778772 }
779773 }
780-
781-
782774 Log .i (TAG , "getArray page = " + page + "; count = " + count );
783775
784776 QueryConfig config = new QueryConfig (requestMethod , count , page );
785777
778+
786779 JSONObject transferredRequest = new JSONObject (true );
780+
787781 JSONObject parent = null ;
788782 Object value ;
789783 JSONObject result ;
784+ Log .d (TAG , "getArray parseRelation = " + parseRelation );
790785 if (parseRelation == false ) {
791786 //生成count个
792787 for (int i = 0 ; i < count ; i ++) {
793- parent = new JSONObject (true );
794- for (String key : set ) {
795- value = request .get (key );
796- if (value instanceof JSONObject ) {//JSONObject
797- config .setPosition (i );
798- if (isArrayKey (key )) {//json array
799- result = getArray (getAbsPath (path , "" + i ), config , key , (JSONObject ) value );
800- } else {//json object
801- result = getObject (getAbsPath (path , "" + i ), config , key , (JSONObject ) value );
802- }
803- Log .i (TAG , "getArray parseRelation == false"
804- + " >> i = " + i + "result = " + result );
805- if (result != null && result .isEmpty () == false ) {//只添加!=null的值,可能数据库返回数据不够count
806- parent .put (key , result );
807-
808- updateRelation (path , getAbsPath (path , "" + i ));//request结构已改变,需要更新依赖关系
809- }
810- } else {//JSONArray或其它Object,直接填充
811- transferredRequest .put (key , value );//array里不允许关联,只能在object中关联
812- }
813- }
814- if (parent .isEmpty () == false ) {//可能数据库返回数据不够count
815- transferredRequest .put ("" + i , parent );
788+ parent = getObject (path , config .setPosition (i ), "" + i , request );
789+ if (parent == null || parent .isEmpty ()) {
790+ break ;//数据库返回数量不够count,后面没有了。有依赖不为空,无依赖直接查询数据库。
816791 }
792+ transferredRequest .put ("" + i , parent );
793+ updateRelation (path , getAbsPath (path , "" + i ));//request结构已改变,需要更新依赖关系
794+ }
795+
796+ if (isInRelationMap (path )) {
797+ transferredRequest .put (JSONRequest .KEY_COUNT , count );
798+ transferredRequest .put (JSONRequest .KEY_PAGE , page );
817799 }
818800 } else {
801+ boolean isArrayKey ;
819802 for (String key : set ) {//0:{},1:{}...
820803 value = request .get (key );
821804 if (value instanceof JSONObject ) {//JSONObject,往下一级提取
822805 config .setPosition (Integer .valueOf (0 + StringUtil .getNumber (key , true )));
823- if (isArrayKey (key )) {//json array
806+ isArrayKey = isArrayKey (key );
807+ if (isArrayKey ) {//json array
824808 result = getArray (path , config , key , (JSONObject ) value );
825809 } else {//json object
826810 result = getObject (path , config , key , (JSONObject ) value );
827811 }
828- if (result != null && result .isEmpty () == false ) {//只添加!=null的值,可能数据库返回数据不够count
829- //先实现功能,后续再优化 if (result.containsKey(firstTableKey)) {//第一个Table都没有,后面的也无效
830- transferredRequest .put (key , result );
831- // }
812+ if (result == null || result .isEmpty ()) {
813+ if (isArrayKey ) {
814+ continue ;
815+ } else {
816+ break ;//数据库返回数量不够count,后面没有了。有依赖不为空,无依赖直接查询数据库。
817+ }
832818 }
819+ transferredRequest .put (key , result );
833820 } else {//JSONArray或其它Object
834821 //array里不允许关联,只能在object中关联
835822 }
@@ -838,12 +825,6 @@ private JSONObject getArray(String parentPath, QueryConfig parentConfig, String
838825
839826 Log .i (TAG , "getArray return " + JSON .toJSONString (transferredRequest ) + "\n >>>>>>>>>>>>>>>\n \n \n " );
840827
841- //可能部分情况下还是会返回,应该在getObject内解析了relation后 keyValuePathMap.remove(path + SEPARATOR + key);
842- if (parseRelation == false && isInRelationMap (path ) == false ) {//parseRelation == true时不会添加进去
843- transferredRequest .remove (JSONRequest .KEY_PAGE );
844- transferredRequest .remove (JSONRequest .KEY_COUNT );
845- }
846-
847828 return transferredRequest ;
848829 }
849830
@@ -934,18 +915,18 @@ private String getAbsPath(String path, String name) {
934915 //依赖引用关系 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
935916
936917 /**有关联代码的object的关联key在relationMap里
937- * @param path
918+ * @param keyPath
938919 * @return
939920 */
940- private boolean isInRelationMap (String path ) {
941- if (path == null ) {
921+ private boolean isInRelationMap (String keyPath ) {
922+ if (keyPath == null ) {
942923 return false ;
943924 }
944925 // return keyValuePathMap == null ? false : keyValuePathMap.containsKey(path);
945926 Set <String > set = keyValuePathMap == null ? null : keyValuePathMap .keySet ();
946927 if (set != null ) {
947928 for (String key : set ) {
948- if (path .equals (key ) || key .startsWith (path + "/" )) {//解决相同字符导致的错误) {//key.contains(path)) {//
929+ if (keyPath .equals (key ) || key .startsWith (keyPath + "/" )) {//解决相同字符导致的错误) {//key.contains(path)) {//
949930 return true ;
950931 }
951932 }
@@ -1133,7 +1114,8 @@ public static boolean isWord(String key) {
11331114 *
11341115 * 方法2:在所有用到key的地方用getRealKey(key)代替key
11351116 * 优点:修改代码集中
1136- * 缺点:完成查询后key没有替换为客户端所需的,要么不解决,要么最后增加一次遍历来替换key;需要在getValueByPath和putValueByPath中遍历keySet找到映射key
1117+ * 缺点:完成查询后key没有替换为客户端所需的,要么不解决,要么最后增加一次遍历来替换key;
1118+ * 需要在getValueByPath和putValueByPath中遍历keySet找到映射key
11371119 *
11381120 * 方法3:方法1,2结合。增加一个keyMap<origin, real>,
11391121 * getValueByPath和putValueByPath中path中的realKey如果有映射就替换为originKey,
@@ -1146,10 +1128,10 @@ public static boolean isWord(String key) {
11461128 */
11471129
11481130 /**获取客户端实际需要的key
1149- * <br> "userId@":"/User/id" //@根据路径依赖,@始终在最后。value是'/'分隔的字符串。
1131+ * <br> "userId@":"/User/id" //@根据路径依赖,@始终在最后。value是'/'分隔的字符串。
11501132 * <br> "isPraised()":"isContain(Collection:idList,long:id)" //()使用方法,value是方法表达式。不能与@并用。
1151- * <br> "content$":"%searchKey%" //$搜索,右边紧跟key。value是搜索表达式。
1152- * <br> "@columns":"id,sex,name" //关键字,左边紧跟key。暂时不用,因为目前关键字很少,几乎不会发生冲突。value是','分隔的字符串。
1133+ * <br> "content$":"%searchKey%" //$搜索,右边紧跟key。value是搜索表达式。
1134+ * <br> "@columns":"id,sex,name" //关键字,左边紧跟key。暂时不用,因为目前关键字很少,几乎不会发生冲突。value是','分隔的字符串。
11531135 *
11541136 * @param method
11551137 * @param originKey
0 commit comments