diff --git a/APIJSONORM/README.md b/APIJSONORM/README.md
index 8007c02c3..0cb431e27 100644
--- a/APIJSONORM/README.md
+++ b/APIJSONORM/README.md
@@ -1,4 +1,4 @@
-# APIJSONORM  [![](https://jitpack.io/v/Tencent/APIJSON.svg)](https://jitpack.io/#Tencent/APIJSON)
+# APIJSONORM  [![](https://jitpack.io/v/Tencent/APIJSON.svg)](https://jitpack.io/#Tencent/APIJSON) [<img src="https://devin.ai/assets/deepwiki-badge.png" alt="Ask DeepWiki.com" height="20"/>](https://deepwiki.com/Tencent/APIJSON)
 腾讯 [APIJSON](https://github.com/Tencent/APIJSON) ORM 库，可通过 Maven, Gradle 等远程依赖。<br />
 Tencent [APIJSON](https://github.com/Tencent/APIJSON) ORM library for remote dependencies with Maven, Gradle, etc.
 
diff --git a/APIJSONORM/pom.xml b/APIJSONORM/pom.xml
index 391319beb..bd340fa5f 100644
--- a/APIJSONORM/pom.xml
+++ b/APIJSONORM/pom.xml
@@ -5,7 +5,7 @@
 
 	<groupId>com.github.Tencent</groupId>
 	<artifactId>APIJSON</artifactId>
-	<version>8.0.0</version>
+	<version>8.0.2</version>
 	<packaging>jar</packaging>
 
 	<name>APIJSONORM</name>
diff --git a/APIJSONORM/src/main/java/apijson/JSON.java b/APIJSONORM/src/main/java/apijson/JSON.java
index c2039c958..0a14e0420 100755
--- a/APIJSONORM/src/main/java/apijson/JSON.java
+++ b/APIJSONORM/src/main/java/apijson/JSON.java
@@ -1,9 +1,11 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
 package apijson;
 
+import java.util.Collection;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -11,60 +13,68 @@
  * @author Lemon
  */
 public class JSON {
-	public static Class<?> JSON_OBJECT_CLASS = JSONObject.class;
-	public static Class<?> JSON_ARRAY_CLASS = JSONArray.class;
 
 	static final String TAG = "JSON";
 
 	public static JSONParser<? extends Map<String, Object>, ? extends List<Object>> DEFAULT_JSON_PARSER;
 
 	static {
-		DEFAULT_JSON_PARSER = new JSONParser<JSONObject, JSONArray>() {
-
-			@Override
-			public JSONObject createJSONObject() {
-				return new JSONObject();
-			}
-
-			@Override
-			public JSONArray createJSONArray() {
-				return new JSONArray();
-			}
-
-			@Override
-			public String toJSONString(Object obj, boolean format) {
-				throw new UnsupportedOperationException();
-			}
-
-			@Override
-			public Object parseJSON(Object json) {
-				throw new UnsupportedOperationException();
-			}
-
-			@Override
-			public JSONObject parseObject(Object json) {
-				throw new UnsupportedOperationException();
-			}
-
-			@Override
-			public <T> T parseObject(Object json, Class<T> clazz) {
-				throw new UnsupportedOperationException();
-			}
-
-			@Override
-			public JSONArray parseArray(Object json) {
-				throw new UnsupportedOperationException();
-			}
-
-			@Override
-			public <T> List<T> parseArray(Object json, Class<T> clazz) {
-				throw new UnsupportedOperationException();
-			}
+		//DEFAULT_JSON_PARSER = new JSONParser<LinkedHashMap<String, Object>, List<Object>>() {
+		//
+		//	@Override
+		//	public LinkedHashMap<String, Object> createJSONObject() {
+		//		throw new UnsupportedOperationException();
+		//	}
+		//
+		//	@Override
+		//	public List<Object> createJSONArray() {
+		//		throw new UnsupportedOperationException();
+		//	}
+		//
+		//	@Override
+		//	public String toJSONString(Object obj, boolean format) {
+		//		throw new UnsupportedOperationException();
+		//	}
+		//
+		//	@Override
+		//	public Object parse(Object json) {
+		//		throw new UnsupportedOperationException();
+		//	}
+		//
+		//	@Override
+		//	public LinkedHashMap<String, Object> parseObject(Object json) {
+		//		throw new UnsupportedOperationException();
+		//	}
+		//
+		//	@Override
+		//	public <T> T parseObject(Object json, Class<T> clazz) {
+		//		throw new UnsupportedOperationException();
+		//	}
+		//
+		//	@Override
+		//	public List<Object> parseArray(Object json) {
+		//		throw new UnsupportedOperationException();
+		//	}
+		//
+		//	@Override
+		//	public <T> List<T> parseArray(Object json, Class<T> clazz) {
+		//		throw new UnsupportedOperationException();
+		//	}
+		//
+		//};
 
-		};
 	}
 
 //	public static JSONCreator<? extends Map<String, Object>, ? extends List<Object>> DEFAULT_JSON_CREATOR = DEFAULT_JSON_PARSER;
+//	public static <M extends Map<String, Object>> M newObj() {
+//		return createJSONObject();
+//	}
+//	public static <M extends Map<String, Object>> M newObj(String key, Object value) {
+//		return createJSONObject(key, value);
+//	}
+//	public static <M extends Map<String, Object>> M newObj(Map<? extends String, ?> map) {
+//		return createJSONObject(map);
+//	}
 
 	public static <M extends Map<String, Object>> M createJSONObject() {
 		return (M) DEFAULT_JSON_PARSER.createJSONObject();
@@ -76,65 +86,47 @@ public static <M extends Map<String, Object>> M createJSONObject(Map<? extends S
 		return (M) DEFAULT_JSON_PARSER.createJSONObject(map);
 	}
 
+	//public static <L extends List<Object>> L newArr() {
+	//	return createJSONArray();
+	//}
+	//public static <L extends List<Object>> L newArr(Object obj) {
+	//	return createJSONArray(obj);
+	//}
+	//public static <L extends List<Object>> L newArr(List<?> list) {
+	//	return createJSONArray(list);
+	//}
+
 	public static <L extends List<Object>> L createJSONArray() {
 		return (L) DEFAULT_JSON_PARSER.createJSONArray();
 	}
 	public static <L extends List<Object>> L createJSONArray(Object obj) {
 		return (L) DEFAULT_JSON_PARSER.createJSONArray(obj);
 	}
-	public static <L extends List<Object>> L createJSONArray(List<?> list) {
+	public static <L extends List<Object>> L createJSONArray(Collection<?> list) {
 		return (L) DEFAULT_JSON_PARSER.createJSONArray(list);
 	}
 
-	public static Object parseJSON(Object json) {
-		if (json instanceof Boolean || json instanceof Number || json instanceof Enum<?>) {
-			return json;
-		}
-
-		String s = StringUtil.trim(toJSONString(json));
-		if (s.startsWith("{")) {
-			return parseObject(json, DEFAULT_JSON_PARSER);
-		}
-
-		if (s.startsWith("[")) {
-			return parseArray(json, DEFAULT_JSON_PARSER);
-		}
-
-		throw new IllegalArgumentException("JSON 格式错误！" + s);
+	public static Object parse(Object json) {
+		return DEFAULT_JSON_PARSER.parse(json);
 	}
 
-	/**
-	 * @param json
-	 * @return
-	 */
-	public static <M extends Map<String, Object>> M parseObject(Object json) {
-		return (M) parseObject(json, DEFAULT_JSON_PARSER);
-	}
 
-	public static <M extends Map<String, Object>, L extends List<Object>> M parseObject(Object json, JSONParser<M, L> parser) {
+	public static <M extends Map<String, Object>> M parseObject(Object json) {
 		String s = toJSONString(json);
 		if (StringUtil.isEmpty(s, true)) {
 			return null;
 		}
 
-		return parser.parseObject(s);
+		return (M) DEFAULT_JSON_PARSER.parseObject(s);
 	}
 
 	public static <T> T parseObject(Object json, Class<T> clazz) {
-		return parseObject(json, clazz, DEFAULT_JSON_PARSER);
-	}
-
-	public static <T, M extends Map<String, Object>, L extends List<Object>> T parseObject(Object json, Class<T> clazz, JSONParser<M, L> parser) {
 		String s = toJSONString(json);
 		if (StringUtil.isEmpty(s, true)) {
 			return null;
 		}
 
-		if (parser == null) {
-			parser = (JSONParser<M, L>) DEFAULT_JSON_PARSER;
-		}
-
-		return parser.parseObject(s, clazz);
+		return DEFAULT_JSON_PARSER.parseObject(s, clazz);
 	}
 
 	/**
@@ -142,17 +134,13 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> T parse
 	 * @return
 	 */
 	public static <L extends List<Object>> L parseArray(Object json) {
-		return (L) parseArray(json, DEFAULT_JSON_PARSER);
-	}
-
-	public static <M extends Map<String, Object>, L extends List<Object>> L parseArray(Object json, JSONParser<M, L> parser) {
 		String s = toJSONString(json);
 		if (StringUtil.isEmpty(s, true)) {
 			return null;
 		}
 
 		try {
-			L arr = parser.parseArray(s);
+			L arr = (L) DEFAULT_JSON_PARSER.parseArray(s);
 			return arr;
 		} catch (Exception e) {
 			Log.i(TAG, "parseArray catch \n" + e.getMessage());
@@ -161,17 +149,13 @@ public static <M extends Map<String, Object>, L extends List<Object>> L parseArr
 	}
 
 	public static <T> List<T> parseArray(Object json, Class<T> clazz) {
-		return parseArray(json, clazz, DEFAULT_JSON_PARSER);
-	}
-
-	public static <T, M extends Map<String, Object>, L extends List<Object>> List<T> parseArray(Object json, Class<T> clazz, JSONParser<M, L> parser) {
 		String s = toJSONString(json);
 		if (StringUtil.isEmpty(s, true)) {
 			return null;
 		}
 
 		try {
-			return parser.parseArray(s, clazz);
+			return DEFAULT_JSON_PARSER.parseArray(s, clazz);
 		} catch (Exception e) {
 			Log.i(TAG, "parseArray catch \n" + e.getMessage());
 		}
@@ -343,14 +327,14 @@ public static <L extends List<Object>> L getJSONArray(List<Object> list, int ind
 	 * @throws IllegalArgumentException If value is not a Map and cannot be converted
 	 */
 	@SuppressWarnings("unchecked")
-	public static Map<String, Object> getMap(Map<String, Object> map, String key) throws IllegalArgumentException {
+	public static <K, V> Map<K, V> getMap(Map<String, Object> map, String key) throws IllegalArgumentException {
 		Object value = map == null || key == null ? null : map.get(key);
 		if (value == null) {
 			return null;
 		}
 
 		if (value instanceof Map) {
-			return (Map<String, Object>) value;
+			return (Map<K, V>) value;
 		}
 
 		throw new IllegalArgumentException("Value for key '" + key + "' is not a Map: " + value.getClass().getName());
@@ -364,14 +348,14 @@ public static Map<String, Object> getMap(Map<String, Object> map, String key) th
 	 * @throws IllegalArgumentException If value is not a List and cannot be converted
 	 */
 	@SuppressWarnings("unchecked")
-	public static List<Object> getList(Map<String, Object> map, String key) throws IllegalArgumentException {
+	public static <T> List<T> getList(Map<String, Object> map, String key) throws IllegalArgumentException {
 		Object value = map == null || key == null ? null : map.get(key);
 		if (value == null) {
 			return null;
 		}
 
 		if (value instanceof List) {
-			return (List<Object>) value;
+			return (List<T>) value;
 		}
 
 		throw new IllegalArgumentException("Value for key '" + key + "' is not a List: " + value.getClass().getName());
@@ -690,4 +674,18 @@ public static String getString(Map<String, Object> map, String key) {
 		return value.toString();
 	}
 
+
+	public static Object getFromObjOrArr(Object parent, String k) {
+		if (parent instanceof Map<?, ?>) {
+			return ((Map<String, Object>) parent).get(k);
+		}
+
+		if (parent instanceof List<?>) {
+			int j = Integer.valueOf(k);
+			return ((List<?>) parent).get(j);
+		}
+
+		return null;
+	}
+
 }
diff --git a/APIJSONORM/src/main/java/apijson/JSONArray.java b/APIJSONORM/src/main/java/apijson/JSONArray.java
deleted file mode 100644
index 60c7926df..000000000
--- a/APIJSONORM/src/main/java/apijson/JSONArray.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
-
-This source code is licensed under the Apache License Version 2.0.*/
-
-package apijson;
-
-import java.util.*;
-
-/**
- * Custom JSONArray implementation based on ArrayList to replace com.alibaba.fastjson.JSONArray
- * Maintains same API as fastjson but uses standard Java List implementation
- * @author Lemon
- */
-public class JSONArray extends JSON implements List<Object> {
-    private static final String TAG = "JSONArray";
-
-    private ArrayList<Object> list = new ArrayList<>();
-    /**
-     * Create an empty JSONArray
-     */
-    public JSONArray() {
-        super();
-    }
-
-    private int initialCapacity = 10;
-    /**
-     * Create a JSONArray with initial capacity
-     * @param initialCapacity the initial capacity
-     */
-    public JSONArray(int initialCapacity) {
-        this.initialCapacity = initialCapacity;
-        this.list = new ArrayList<>(initialCapacity);
-    }
-    
-    /**
-     * Create a JSONArray from a Collection
-     * @param collection the collection to copy from
-     */
-    public JSONArray(Collection<?> collection) {
-        super();
-        if (collection != null) {
-            addAll(collection);
-        }
-    }
-    
-    /**
-     * Create a JSONArray from a JSON string
-     * @param json JSON string
-     */
-    public JSONArray(String json) {
-        this();
-        List<Object> list = JSON.parseArray(json);
-        if (list != null) {
-            addAll(list);
-        }
-    }
-    
-    /**
-     * Get a JSONObject at the specified index
-     * @param index the index
-     * @return the JSONObject or null if not a JSONObject
-     */
-    public JSONObject getJSONObject(int index) {
-        if (index < 0 || index >= size()) {
-            return null;
-        }
-        
-        Object obj = get(index);
-        if (obj instanceof JSONObject) {
-            return (JSONObject) obj;
-        }
-        else if (obj instanceof Map) {
-            return new JSONObject(obj);
-        }
-        return null;
-    }
-    
-    /**
-     * Get a JSONArray at the specified index
-     * @param index the index
-     * @return the JSONArray or null if not a JSONArray
-     */
-    public JSONArray getJSONArray(int index) {
-        if (index < 0 || index >= size()) {
-            return null;
-        }
-        
-        Object obj = get(index);
-        if (obj instanceof List) {
-            @SuppressWarnings("unchecked")
-            List<Object> list = (List<Object>) obj;
-            return new JSONArray(list);
-        } else if (obj instanceof List<?>) {
-            return (JSONArray) obj;
-        }
-        return null;
-    }
-    
-    /**
-     * Get a boolean value at the specified index
-     * @param index the index
-     * @return the boolean value or false if not found
-     */
-    public boolean getBooleanValue(int index) {
-        if (index < 0 || index >= size()) {
-            return false;
-        }
-        
-        Object obj = get(index);
-        if (obj instanceof Boolean) {
-            return (Boolean) obj;
-        } else if (obj instanceof Number) {
-            return ((Number) obj).intValue() != 0;
-        } else if (obj instanceof String) {
-            return Boolean.parseBoolean((String) obj);
-        }
-        return false;
-    }
-    
-    /**
-     * Get an integer value at the specified index
-     * @param index the index
-     * @return the integer value or 0 if not found
-     */
-    public int getIntValue(int index) {
-        if (index < 0 || index >= size()) {
-            return 0;
-        }
-        
-        Object obj = get(index);
-        if (obj instanceof Number) {
-            return ((Number) obj).intValue();
-        } else if (obj instanceof String) {
-            try {
-                return Integer.parseInt((String) obj);
-            } catch (NumberFormatException e) {
-                // Ignore
-            }
-        }
-        return 0;
-    }
-    
-    /**
-     * Get a long value at the specified index
-     * @param index the index
-     * @return the long value or 0 if not found
-     */
-    public long getLongValue(int index) {
-        if (index < 0 || index >= size()) {
-            return 0L;
-        }
-        
-        Object obj = get(index);
-        if (obj instanceof Number) {
-            return ((Number) obj).longValue();
-        } else if (obj instanceof String) {
-            try {
-                return Long.parseLong((String) obj);
-            } catch (NumberFormatException e) {
-                // Ignore
-            }
-        }
-        return 0L;
-    }
-    
-    /**
-     * Get a double value at the specified index
-     * @param index the index
-     * @return the double value or 0 if not found
-     */
-    public double getDoubleValue(int index) {
-        if (index < 0 || index >= size()) {
-            return 0.0;
-        }
-        
-        Object obj = get(index);
-        if (obj instanceof Number) {
-            return ((Number) obj).doubleValue();
-        } else if (obj instanceof String) {
-            try {
-                return Double.parseDouble((String) obj);
-            } catch (NumberFormatException e) {
-                // Ignore
-            }
-        }
-        return 0.0;
-    }
-    
-    /**
-     * Get a string value at the specified index
-     * @param index the index
-     * @return the string value or null if not found
-     */
-    public String getString(int index) {
-        if (index < 0 || index >= size()) {
-            return null;
-        }
-        
-        Object obj = get(index);
-        return obj != null ? obj.toString() : null;
-    }
-    
-    /**
-     * Add a value to the JSONArray
-     * @param obj the value to add
-     * @return this JSONArray
-     */
-    public JSONArray fluentAdd(Object obj) {
-        add(obj);
-        return this;
-    }
-    
-    @Override
-    public String toString() {
-        return JSON.toJSONString(this);
-    }
-
-    @Override
-    public int size() {
-        return list.size();
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return list.isEmpty();
-    }
-
-    @Override
-    public boolean contains(Object o) {
-        return list.contains(o);
-    }
-
-    @Override
-    public Iterator<Object> iterator() {
-        return list.iterator();
-    }
-
-    @Override
-    public Object[] toArray() {
-        return list.toArray();
-    }
-
-    @Override
-    public <T> T[] toArray(T[] a) {
-        return list.toArray(a);
-    }
-
-    @Override
-    public boolean add(Object o) {
-        return list.add(o);
-    }
-
-    @Override
-    public boolean remove(Object o) {
-        return list.remove(o);
-    }
-
-    @Override
-    public boolean containsAll(Collection<?> c) {
-        if (c == null || c.isEmpty()) {
-            return true;
-        }
-        return list.containsAll(c);
-    }
-
-    @Override
-    public boolean addAll(Collection<?> c) {
-        if (c == null || c.isEmpty()) {
-            return true;
-        }
-        return list.addAll(c);
-    }
-
-    @Override
-    public boolean addAll(int index, Collection<?> c) {
-        int sz = size();
-        if (index < 0) {
-            index += sz;
-        }
-
-        if (c == null || c.isEmpty()) {
-            return true;
-        }
-        return list.addAll(index, c);
-    }
-
-    @Override
-    public boolean removeAll(Collection<?> c) {
-        if (c == null || c.isEmpty()) {
-            return true;
-        }
-        return list.removeAll(c);
-    }
-
-    @Override
-    public boolean retainAll(Collection<?> c) {
-        if (c == null || c.isEmpty()) {
-            return true;
-        }
-        return list.retainAll(c);
-    }
-
-    @Override
-    public void clear() {
-        list.clear();
-    }
-
-    @Override
-    public Object get(int index) {
-        int sz = size();
-        if (index < 0) {
-            index += sz;
-        }
-
-        return list.get(index);
-    }
-
-    @Override
-    public Object set(int index, Object element) {
-        return list.set(index, element);
-    }
-
-    @Override
-    public void add(int index, Object element) {
-        list.add(index, element);
-    }
-
-    @Override
-    public Object remove(int index) {
-        int sz = size();
-        if (index < 0) {
-            index += sz;
-        }
-        if (index >= sz) {
-            return null;
-        }
-
-        return list.remove(index);
-    }
-
-    @Override
-    public int indexOf(Object o) {
-        return list.indexOf(o);
-    }
-
-    @Override
-    public int lastIndexOf(Object o) {
-        return list.lastIndexOf(o);
-    }
-
-    @Override
-    public ListIterator<Object> listIterator() {
-        return list.listIterator();
-    }
-
-    @Override
-    public ListIterator<Object> listIterator(int index) {
-        int sz = size();
-        if (index < 0) {
-            index += sz;
-        }
-
-        return list.listIterator(index);
-    }
-
-    @Override
-    public List<Object> subList(int fromIndex, int toIndex) {
-        if (fromIndex < 0) {
-            fromIndex += size();
-        }
-        if (toIndex < 0) {
-            toIndex += size();
-        }
-        return list.subList(fromIndex, toIndex);
-    }
-}
\ No newline at end of file
diff --git a/APIJSONORM/src/main/java/apijson/JSONCreator.java b/APIJSONORM/src/main/java/apijson/JSONCreator.java
index 8e4f6c8cb..df0d9066a 100755
--- a/APIJSONORM/src/main/java/apijson/JSONCreator.java
+++ b/APIJSONORM/src/main/java/apijson/JSONCreator.java
@@ -1,17 +1,15 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
 
 package apijson;
 
-import apijson.orm.SQLConfig;
-import apijson.orm.SQLExecutor;
-
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
-/**SQL相关创建器
+/**JSON相关创建器
  * @author Lemon
  */
 public interface JSONCreator<M extends Map<String, Object>, L extends List<Object>> {
@@ -46,10 +44,10 @@ default L createJSONArray(Object obj){
     }
 
     @NotNull
-    default L createJSONArray(List<?> l){
+    default L createJSONArray(Collection<?> list){
         L arr = createJSONArray();
-        if (l != null && ! l.isEmpty()) {
-            arr.addAll(l);
+        if (list != null && ! list.isEmpty()) {
+            arr.addAll(list);
         }
         return arr;
     }
diff --git a/APIJSONORM/src/main/java/apijson/JSONField.java b/APIJSONORM/src/main/java/apijson/JSONField.java
deleted file mode 100644
index 11a5cc309..000000000
--- a/APIJSONORM/src/main/java/apijson/JSONField.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package apijson;
-
-public @interface JSONField {
-    boolean serialize() default true;
-}
diff --git a/APIJSONORM/src/main/java/apijson/JSONList.java b/APIJSONORM/src/main/java/apijson/JSONList.java
new file mode 100644
index 000000000..092bf9f39
--- /dev/null
+++ b/APIJSONORM/src/main/java/apijson/JSONList.java
@@ -0,0 +1,312 @@
+/*Copyright (C) 2020 Tencent.  All rights reserved.
+
+This source code is licensed under the Apache License Version 2.0.*/
+
+package apijson;
+
+import java.util.*;
+
+/**
+ * Custom JSONList implementation based on ArrayList to replace com.alibaba.fastjson.JSONList
+ * Maintains same API as fastjson but uses standard Java List implementation
+ * @author Lemon
+ */
+public interface JSONList<M extends Map<String, Object>, L extends List<Object>> extends List<Object> {
+    public static final String TAG = "JSONList";
+
+    ///**
+    // * Create an empty JSONList
+    // */
+    //default JSONList() {
+    //    super();
+    //}
+    //
+    //private int initialCapacity = 10;
+    ///**
+    // * Create a JSONList with initial capacity
+    // * @param initialCapacity the initial capacity
+    // */
+    //default JSONList(int initialCapacity) {
+    //    super(initialCapacity);
+    //}
+    //
+    ///**
+    // * Create a JSONList from a Collection
+    // * @param collection the collection to copy from
+    // */
+    //default JSONList(Collection<?> collection) {
+    //    super(collection);
+    //}
+    //
+    ///**
+    // * Create a JSONList from a JSON string
+    // * @param json JSON string
+    // */
+    //default JSONList(String json) {
+    //    this();
+    //    List<Object> list = JSON.parseArray(json);
+    //    if (list != null) {
+    //        addAll(list);
+    //    }
+    //}
+    //
+    /**
+     * Get a JSONMap at the specified index
+     * @param index the index
+     * @return the JSONMap or null if not a JSONMap
+     */
+    default M getJSONObject(int index) {
+        if (index < 0 || index >= size()) {
+            return null;
+        }
+        
+        Object obj = get(index);
+        if (obj instanceof Map<?, ?>) {
+            return JSON.createJSONObject((Map<? extends String, ?>) obj);
+        }
+
+        return null;
+    }
+    
+    /**
+     * Get a JSONList at the specified index
+     * @param index the index
+     * @return the JSONList or null if not a JSONList
+     */
+    default L getJSONArray(int index) {
+        if (index < 0 || index >= size()) {
+            return null;
+        }
+        
+        Object obj = get(index);
+        if (obj instanceof List<?>) {
+            return JSON.createJSONArray((List<?>) obj);
+        }
+
+        return null;
+    }
+    
+    /**
+     * Get a boolean value at the specified index
+     * @param index the index
+     * @return the boolean value or false if not found
+     */
+    default boolean getBooleanValue(int index) {
+        if (index < 0 || index >= size()) {
+            return false;
+        }
+        
+        Object obj = get(index);
+        if (obj instanceof Boolean) {
+            return (Boolean) obj;
+        } else if (obj instanceof Number) {
+            return ((Number) obj).intValue() != 0;
+        } else if (obj instanceof String) {
+            return Boolean.parseBoolean((String) obj);
+        }
+
+        return false;
+    }
+    
+    /**
+     * Get an integer value at the specified index
+     * @param index the index
+     * @return the integer value or 0 if not found
+     */
+    default int getIntValue(int index) {
+        if (index < 0 || index >= size()) {
+            return 0;
+        }
+        
+        Object obj = get(index);
+        if (obj instanceof Number) {
+            return ((Number) obj).intValue();
+        } else if (obj instanceof String) {
+            try {
+                return Integer.parseInt((String) obj);
+            } catch (NumberFormatException e) {
+                // Ignore
+            }
+        }
+        return 0;
+    }
+    
+    /**
+     * Get a long value at the specified index
+     * @param index the index
+     * @return the long value or 0 if not found
+     */
+    default long getLongValue(int index) {
+        if (index < 0 || index >= size()) {
+            return 0L;
+        }
+        
+        Object obj = get(index);
+        if (obj instanceof Number) {
+            return ((Number) obj).longValue();
+        } else if (obj instanceof String) {
+            try {
+                return Long.parseLong((String) obj);
+            } catch (NumberFormatException e) {
+                // Ignore
+            }
+        }
+        return 0L;
+    }
+    
+    /**
+     * Get a double value at the specified index
+     * @param index the index
+     * @return the double value or 0 if not found
+     */
+    default double getDoubleValue(int index) {
+        if (index < 0 || index >= size()) {
+            return 0.0;
+        }
+        
+        Object obj = get(index);
+        if (obj instanceof Number) {
+            return ((Number) obj).doubleValue();
+        } else if (obj instanceof String) {
+            try {
+                return Double.parseDouble((String) obj);
+            } catch (NumberFormatException e) {
+                // Ignore
+            }
+        }
+        return 0.0;
+    }
+    
+    /**
+     * Get a string value at the specified index
+     * @param index the index
+     * @return the string value or null if not found
+     */
+    default String getString(int index) {
+        if (index < 0 || index >= size()) {
+            return null;
+        }
+        
+        Object obj = get(index);
+        return obj != null ? obj.toString() : null;
+    }
+
+    
+    default String toJSONString() {
+        return JSON.toJSONString(this);
+    }
+
+    //@Override
+    //default boolean containsAll(Collection<?> c) {
+    //    if (c == null || c.isEmpty()) {
+    //        return true;
+    //    }
+    //    return super.containsAll(c);
+    //}
+    //
+    //@Override
+    //default boolean addAll(Collection<?> c) {
+    //    if (c == null || c.isEmpty()) {
+    //        return true;
+    //    }
+    //    return super.addAll(c);
+    //}
+    //
+    //@Override
+    //default boolean addAll(int index, Collection<?> c) {
+    //    if (c == null || c.isEmpty()) {
+    //        return true;
+    //    }
+    //
+    //    int sz = size();
+    //    if (index < 0 || index >= sz) {
+    //        index += sz;
+    //    }
+    //
+    //    return super.addAll(index, c);
+    //}
+    //
+    //@Override
+    //default boolean removeAll(Collection<?> c) {
+    //    if (c == null || c.isEmpty()) {
+    //        return true;
+    //    }
+    //    return super.removeAll(c);
+    //}
+    //
+    //@Override
+    //default boolean retainAll(Collection<?> c) {
+    //    if (c == null || c.isEmpty()) {
+    //        return true;
+    //    }
+    //    return super.retainAll(c);
+    //}
+    //
+    //
+    //@Override
+    //default Object get(int index) {
+    //    int sz = size();
+    //    if (index < 0 || index >= sz) {
+    //        index += sz;
+    //    }
+    //
+    //    return super.get(index);
+    //}
+    //
+    //@Override
+    //default Object set(int index, Object element) {
+    //    int sz = size();
+    //    if (index < 0 || index >= sz) {
+    //        index += sz;
+    //    }
+    //
+    //    return super.set(index, element);
+    //}
+    //
+    //@Override
+    //default void add(int index, Object element) {
+    //    int sz = size();
+    //    if (index < 0 || index >= sz) {
+    //        index += sz;
+    //    }
+    //
+    //    super.add(index, element);
+    //}
+    //
+    //@Override
+    //default Object remove(int index) {
+    //    int sz = size();
+    //    if (index < 0 && index >= -sz) {
+    //        index += sz;
+    //    }
+    //    if (index < 0 || index >= sz) {
+    //        return null;
+    //    }
+    //
+    //    return super.remove(index);
+    //}
+    //
+    //@Override
+    //default ListIterator<Object> listIterator(int index) {
+    //    int sz = size();
+    //    if (index < 0 && index >= -sz) {
+    //        index += sz;
+    //    }
+    //
+    //    return super.listIterator(index);
+    //}
+    //
+    //@Override
+    //default List<Object> subList(int fromIndex, int toIndex) {
+    //    int sz = size();
+    //    if (fromIndex < 0 && fromIndex >= -sz) {
+    //        fromIndex += sz;
+    //    }
+    //    if (toIndex < 0 && toIndex >= -sz) {
+    //        toIndex += sz;
+    //    }
+    //
+    //    return super.subList(fromIndex, toIndex);
+    //}
+
+}
\ No newline at end of file
diff --git a/APIJSONORM/src/main/java/apijson/JSONMap.java b/APIJSONORM/src/main/java/apijson/JSONMap.java
new file mode 100755
index 000000000..29d88f756
--- /dev/null
+++ b/APIJSONORM/src/main/java/apijson/JSONMap.java
@@ -0,0 +1,810 @@
+/*Copyright (C) 2020 Tencent.  All rights reserved.
+
+This source code is licensed under the Apache License Version 2.0.*/
+
+
+package apijson;
+
+import java.util.*;
+
+
+/**use this class instead of com.alibaba.fastjson.JSONMap
+ * @author Lemon
+ * @see #put
+ * @see #puts
+ * @see #putsAll
+ */
+//default class JSONMap<M, L> extends LinkedHashMap<String, Object> {
+public interface JSONMap<M extends Map<String, Object>, L extends List<Object>> extends Map<String, Object> {
+	static final String TAG = "JSONMap";
+
+	// 只能是 static public Map<String, Object> map = new LinkedHashMap<>();
+
+	///**ordered
+	// */
+	//default JSONMap() {
+	//	super();
+	//}
+	///**transfer Object to JSONMap
+	// * @param object
+	// * @see {@link #JSONMap(Object)}
+	// */
+	//default JSONMap(Object object) {
+	//	this();
+	//	if (object instanceof Map) {
+	//		@SuppressWarnings("unchecked")
+	//		Map<String, Object> map = (Map<String, Object>) object;
+	//		putAll(map);
+	//	} else if (object != null) {
+	//		String json = JSON.toJSONString(object);
+	//		if (json != null) {
+	//			Map<String, Object> map = JSON.parseObject(json);
+	//			if (map != null) {
+	//				putAll(map);
+	//			}
+	//		}
+	//	}
+	//}
+	///**parse JSONMap<M, L> with JSON String
+	// * @param json
+	// * @see {@link #JSONMap(String)}
+	// */
+	//default JSONMap(String json) {
+	//	this();
+	//	Map<String, Object> map = JSON.parseObject(json);
+	//	if (map != null) {
+	//		putAll(map);
+	//	}
+	//}
+	///**transfer com.alibaba.fastjson.JSONMap<M, L> to JSONMap
+	// * @param object
+	// * @see {@link #putsAll(Map<? extends String, ? extends Object>)}
+	// */
+	//default JSONMap(Map<String, Object> object) {
+	//	this();
+	//	putsAll(object);
+	//}
+
+	//public static JSONMap<M, L> valueOf(Object obj) {
+	//	JSONMap<M, L> req = new JSONMap() {};
+	//	Map<String, Object> m = JSON.parseObject(obj);
+	//	if (m != null && ! m.isEmpty()) {
+	//		req.map.putAll(m);
+	//	}
+	//	return req;
+	//}
+
+	//judge <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+	String KEY_ARRAY = "[]";
+
+	/**判断是否为Array的key
+	 * @param key
+	 * @return
+	 */
+	public static boolean isArrayKey(String key) {
+		return key != null && key.endsWith(KEY_ARRAY);
+	}
+	/**判断是否为对应Table的key
+	 * @param key
+	 * @return
+	 */
+	public static boolean isTableKey(String key) {
+		return StringUtil.isBigName(key);
+	}
+	/**判断是否为对应Table数组的 key
+	 * @param key
+	 * @return
+	 */
+	public static boolean isTableArray(String key) {
+		return isArrayKey(key) && isTableKey(key.substring(0, key.length() - KEY_ARRAY.length()));
+	}
+	//judge >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+	//JSONObject内关键词 key <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+
+	public static String KEY_ID = "id";
+	public static String KEY_ID_IN = KEY_ID + "{}";
+	public static String KEY_USER_ID = "userId";
+	public static String KEY_USER_ID_IN = KEY_USER_ID + "{}";
+
+	/**set "id":id in Table layer
+	 * @param id
+	 * @return
+	 */
+	default JSONMap<M, L> setId(Long id) {
+		return puts(KEY_ID, id);
+	}
+	/**set "id{}":[] in Table layer
+	 * @param list
+	 * @return
+	 */
+	default JSONMap<M, L> setIdIn(List<Object> list) {
+		return puts(KEY_ID_IN, list);
+	}
+
+	/**set "userId":userId in Table layer
+	 * @param id
+	 * @return
+	 */
+	default JSONMap<M, L> setUserId(Long id) {
+		return puts(KEY_USER_ID, id);
+	}
+	/**set "userId{}":[] in Table layer
+	 * @param list
+	 * @return
+	 */
+	default JSONMap<M, L> setUserIdIn(List<Object> list) {
+		return puts(KEY_USER_ID_IN, list);
+	}
+
+
+	int CACHE_ALL = 0;
+	int CACHE_ROM = 1;
+	int CACHE_RAM = 2;
+
+	String CACHE_ALL_STRING = "ALL";
+	String CACHE_ROM_STRING = "ROM";
+	String CACHE_RAM_STRING = "RAM";
+
+
+	//@key关键字都放这个类 <<<<<<<<<<<<<<<<<<<<<<
+	String KEY_TRY = "@try"; //尝试，忽略异常
+	String KEY_CATCH = "@catch"; //TODO 捕捉到异常后，处理方式  null-不处理；DEFAULT-返回默认值；ORIGIN-返回请求里的原始值
+	String KEY_DROP = "@drop"; //丢弃，不返回，TODO 应该通过 fastjson 的 ignore 之类的机制来处理，避免导致下面的对象也不返回
+	//	String KEY_KEEP = "@keep"; //一定会返回，为 null 或 空对象时，会使用默认值(非空)，解决其它对象因为不关联的第一个对为空导致也不返回
+	String KEY_DEFULT = "@default"; //TODO 自定义默认值 { "@default":true }，@default 可完全替代 @keep
+	String KEY_NULL = "@null"; //值为 null 的键值对 "@null":"tag,pictureList"，允许 is NULL 条件判断， SET tag = NULL 修改值为 NULL 等
+	String KEY_CAST = "@cast"; //类型转换 cast(date AS DATE)
+
+	String KEY_ROLE = "@role"; //角色，拥有对某些数据的某些操作的权限
+	String KEY_DATABASE = "@database"; //数据库类型，默认为MySQL
+	String KEY_DATASOURCE = "@datasource"; //数据源
+	String KEY_NAMESPACE = "@namespace"; //命名空间，Table 在非默认 namespace 内时需要声明
+	String KEY_CATALOG = "@catalog"; //目录，Table 在非默认 catalog 内时需要声明
+	String KEY_SCHEMA = "@schema"; //数据库，Table 在非默认 schema 内时需要声明
+	String KEY_EXPLAIN = "@explain"; //分析 true/false
+	String KEY_CACHE = "@cache"; //缓存 RAM/ROM/ALL
+	String KEY_COLUMN = "@column"; //查询的Table字段或SQL函数
+	String KEY_FROM = "@from"; //FROM语句
+	String KEY_COMBINE = "@combine"; //条件组合，每个条件key前面可以放&,|,!逻辑关系  "id!{},&sex,!name&$"
+	String KEY_GROUP = "@group"; //分组方式
+	String KEY_HAVING = "@having"; //聚合函数条件，一般和@group一起用
+	String KEY_HAVING_AND = "@having&"; //聚合函数条件，一般和@group一起用
+	String KEY_SAMPLE = "@sample"; //取样方式
+	String KEY_LATEST = "@latest"; //最近方式
+	String KEY_PARTITION = "@partition"; //分区方式
+	String KEY_FILL = "@fill"; //填充方式
+	String KEY_ORDER = "@order"; //排序方式
+	String KEY_KEY = "@key"; // key 映射，year:left(date,4);name_tag:(name,tag)
+	String KEY_RAW = "@raw"; // 自定义原始 SQL 片段
+	String KEY_JSON = "@json"; //SQL Server 把字段转为 JSON 输出
+	String KEY_METHOD = "@method"; // json 对象配置操作方法
+	String KEY_GET = "@get"; // json 对象配置操作方法
+	String KEY_GETS = "@gets"; // json 对象配置操作方法
+	String KEY_HEAD = "@head"; // json 对象配置操作方法
+	String KEY_HEADS = "@heads"; // json 对象配置操作方法
+	String KEY_POST = "@post"; // json 对象配置操作方法
+	String KEY_PUT = "@put"; // json 对象配置操作方法
+	String KEY_DELETE = "@delete"; // json 对象配置操作方法
+
+	List<String> TABLE_KEY_LIST = new ArrayList<>(Arrays.asList(
+			KEY_ROLE, 
+			KEY_DATABASE, 
+			KEY_DATASOURCE,
+			KEY_NAMESPACE,
+			KEY_CATALOG,
+			KEY_SCHEMA,
+			KEY_EXPLAIN,
+			KEY_CACHE,
+			KEY_COLUMN,
+			KEY_FROM,
+			KEY_NULL,
+			KEY_CAST,
+			KEY_COMBINE,
+			KEY_GROUP,
+			KEY_HAVING,
+			KEY_HAVING_AND,
+			KEY_SAMPLE,
+			KEY_LATEST,
+			KEY_PARTITION,
+			KEY_FILL,
+			KEY_ORDER,
+			KEY_KEY,
+			KEY_RAW,
+			KEY_JSON,
+			KEY_METHOD,
+			KEY_GET,
+			KEY_GETS,
+			KEY_HEAD,
+			KEY_HEADS,
+			KEY_POST,
+			KEY_PUT,
+			KEY_DELETE
+	));
+
+	//@key关键字都放这个类 >>>>>>>>>>>>>>>>>>>>>>
+
+
+	/**set try, ignore exceptions
+	 * @param tri
+	 * @return this
+	 */
+	default JSONMap<M, L> setTry(Boolean tri) {
+		return puts(KEY_TRY, tri);
+	}
+
+	/**set catch
+	 * @param isCatch
+	 * @return this
+	 */
+	default JSONMap<M, L> setCatch(String isCatch) {
+		return puts(KEY_CATCH, isCatch);
+	}
+	/**set drop, data dropped will not return
+	 * @param drop
+	 * @return this
+	 */
+	default JSONMap<M, L> setDrop(Boolean drop) {
+		return puts(KEY_DROP, drop);
+	}
+
+	/**set if has default
+	 * @param hasDefault
+	 * @return this
+	 */
+	default JSONMap<M, L> setDefault(Boolean hasDefault) {
+		return puts(KEY_DEFULT, hasDefault);
+	}
+
+
+	/**set role of request sender
+	 * @param role
+	 * @return this
+	 */
+	default JSONMap<M, L> setRole(String role) {
+		return puts(KEY_ROLE, role);
+	}
+	/**set database where table was puts
+	 * @param database
+	 * @return this
+	 */
+	default JSONMap<M, L> setDatabase(String database) {
+		return puts(KEY_DATABASE, database);
+	}
+	/**set datasource where table was puts
+	 * @param datasource
+	 * @return this
+	 */
+	default JSONMap<M, L> setDatasource(String datasource) {
+		return puts(KEY_DATASOURCE, datasource);
+	}
+	/**set namespace where table was puts
+	 * @param namespace
+	 * @return this
+	 */
+	default JSONMap<M, L> setNamespace(String namespace) {
+		return puts(KEY_NAMESPACE, namespace);
+	}
+	/**set catalog where table was puts
+	 * @param catalog
+	 * @return this
+	 */
+	default JSONMap<M, L> setCatalog(String catalog) {
+		return puts(KEY_CATALOG, catalog);
+	}
+	/**set schema where table was puts
+	 * @param schema
+	 * @return this
+	 */
+	default JSONMap<M, L> setSchema(String schema) {
+		return puts(KEY_SCHEMA, schema);
+	}
+	/**set if return explain informations
+	 * @param explain
+	 * @return
+	 */
+	default JSONMap<M, L> setExplain(Boolean explain) {
+		return puts(KEY_EXPLAIN, explain);
+	}
+	/**set cache type
+	 * @param cache
+	 * @return
+	 * @see {@link #CACHE_ALL}
+	 * @see {@link #CACHE_RAM}
+	 * @see {@link #CACHE_ROM}
+	 */
+	default JSONMap<M, L> setCache(Integer cache) {
+		return puts(KEY_CACHE, cache);
+	}
+	/**set cache type
+	 * @param cache
+	 * @return
+	 * @see {@link #CACHE_ALL_STRING}
+	 * @see {@link #CACHE_RAM_STRING}
+	 * @see {@link #CACHE_ROM_STRING}
+	 */
+	default JSONMap<M, L> setCache(String cache) {
+		return puts(KEY_CACHE, cache);
+	}
+
+	/**set keys need to be returned
+	 * @param keys  key0, key1, key2 ...
+	 * @return {@link #setColumn(String)}
+	 */
+	default JSONMap<M, L> setColumn(String... keys) {
+		return setColumn(StringUtil.get(keys, true));
+	}
+	/**set keys need to be returned
+	 * @param keys  "key0,key1,key2..."
+	 * @return
+	 */
+	default JSONMap<M, L> setColumn(String keys) {
+		return puts(KEY_COLUMN, keys);
+	}
+
+	/**set keys whose value is null
+	 * @param keys  key0, key1, key2 ...
+	 * @return {@link #setNull(String)}
+	 */
+	default JSONMap<M, L> setNull(String... keys) {
+		return setNull(StringUtil.get(keys, true));
+	}
+	/**set keys whose value is null
+	 * @param keys  "key0,key1,key2..."
+	 * @return
+	 */
+	default JSONMap<M, L> setNull(String keys) {
+		return puts(KEY_NULL, keys);
+	}
+	
+	/**set keys and types whose value should be cast to type, cast(value AS DATE)
+	 * @param keyTypes  key0:type0, key1:type1, key2:type2 ...
+	 * @return {@link #setCast(String)}
+	 */
+	default JSONMap<M, L> setCast(String... keyTypes) {
+		return setCast(StringUtil.get(keyTypes, true));
+	}
+	/**set keys and types whose value should be cast to type, cast(value AS DATE)
+	 * @param keyTypes  "key0:type0,key1:type1,key2:type2..."
+	 * @return
+	 */
+	default JSONMap<M, L> setCast(String keyTypes) {
+		return puts(KEY_CAST, keyTypes);
+	}
+
+	/**set combination of keys for conditions
+	 * @param keys  key0,&key1,|key2,!key3 ...  TODO or key0> | (key1{} & !key2)...
+	 * @return {@link #setColumn(String)}
+	 */
+	default JSONMap<M, L> setCombine(String... keys) {
+		return setCombine(StringUtil.get(keys, true));
+	}
+	/**set combination of keys for conditions
+	 * @param keys  key0,&key1,|key2,!key3 ...  TODO or key0> | (key1{} & !key2)...
+	 * @return
+	 */
+	default JSONMap<M, L> setCombine(String keys) {
+		return puts(KEY_COMBINE, keys);
+	}
+
+	/**set keys for group by
+	 * @param keys key0, key1, key2 ...
+	 * @return {@link #setGroup(String)}
+	 */
+	default JSONMap<M, L> setGroup(String... keys) {
+		return setGroup(StringUtil.get(keys, true));
+	}
+	/**set keys for group by
+	 * @param keys  "key0,key1,key2..."
+	 * @return
+	 */
+	default JSONMap<M, L> setGroup(String keys) {
+		return puts(KEY_GROUP, keys);
+	}
+
+	/**set keys for having
+	 * @param keys count(key0) > 1, sum(key1) <= 5, function2(key2) ? value2 ...
+	 * @return {@link #setHaving(String)}
+	 */
+	default JSONMap<M, L> setHaving(String... keys) {
+		return setHaving(StringUtil.get(keys, true));
+	}
+	/**set keys for having
+	 * @param keys  "key0,key1,key2..."
+	 * @return
+	 */
+	default JSONMap<M, L> setHaving(String keys) {
+		return setHaving(keys, false);
+	}
+	/**set keys for having
+	 * @param keys  "key0,key1,key2..."
+	 * @return
+	 */
+	default JSONMap<M, L> setHaving(String keys, boolean isAnd) {
+		return puts(isAnd ? KEY_HAVING_AND : KEY_HAVING, keys);
+	}
+
+	/**set keys for sample by
+	 * @param keys  key0, key1, key2 ...
+	 * @return {@link #setSample(String)}
+	 */
+	default JSONMap<M, L> setSample(String... keys) {
+		return setSample(StringUtil.get(keys, true));
+	}
+	/**set keys for sample by
+	 * @param keys  "key0,key1,key2..."
+	 * @return
+	 */
+	default JSONMap<M, L> setSample(String keys) {
+		return puts(KEY_SAMPLE, keys);
+	}
+
+	/**set keys for latest on
+	 * @param keys  key0, key1, key2 ...
+	 * @return {@link #setLatest(String)}
+	 */
+	default JSONMap<M, L> setLatest(String... keys) {
+		return setLatest(StringUtil.get(keys, true));
+	}
+	/**set keys for latest on
+	 * @param keys  "key0,key1,key2..."
+	 * @return
+	 */
+	default JSONMap<M, L> setLatest(String keys) {
+		return puts(KEY_LATEST, keys);
+	}
+
+	/**set keys for partition by
+	 * @param keys  key0, key1, key2 ...
+	 * @return {@link #setPartition(String)}
+	 */
+	default JSONMap<M, L> setPartition(String... keys) {
+		return setPartition(StringUtil.get(keys, true));
+	}
+	/**set keys for partition by
+	 * @param keys  key0, key1, key2 ...
+	 * @return
+	 */
+	default JSONMap<M, L> setPartition(String keys) {
+		return puts(KEY_PARTITION, keys);
+	}
+
+	/**set keys for fill(key): fill(null), fill(linear), fill(prev)
+	 * @param keys  key0, key1, key2 ...
+	 * @return {@link #setFill(String)}
+	 */
+	default JSONMap<M, L> setFill(String... keys) {
+		return setFill(StringUtil.get(keys, true));
+	}
+	/**set keys for fill(key): fill(null), fill(linear), fill(prev)
+	 * @param keys  key0, key1, key2 ...
+	 * @return
+	 */
+	default JSONMap<M, L> setFill(String keys) {
+		return puts(KEY_FILL, keys);
+	}
+
+	/**set keys for order by
+	 * @param keys  key0, key1+, key2- ...
+	 * @return {@link #setOrder(String)}
+	 */
+	default JSONMap<M, L> setOrder(String... keys) {
+		return setOrder(StringUtil.get(keys, true));
+	}
+	/**set keys for order by
+	 * @param keys  "key0,key1+,key2-..."
+	 * @return
+	 */
+	default JSONMap<M, L> setOrder(String keys) {
+		return puts(KEY_ORDER, keys);
+	}
+
+	/**set key map
+	 * @param keyMap  "name_tag:(name,tag);year:left(date,1,5)..."
+	 * @return
+	 */
+	default JSONMap<M, L> setKey(String keyMap) {
+		return puts(KEY_KEY, keyMap);
+	}
+
+	/**set keys to raw
+	 * @param keys  "key0,key1,key2..."
+	 * @return
+	 */
+	default JSONMap<M, L> setRaw(String keys) {
+		return puts(KEY_RAW, keys);
+	}
+
+	/**set keys to cast to json
+	 * @param keys  "key0,key1,key2..."
+	 * @return
+	 */
+	default JSONMap<M, L> setJson(String keys) {
+		return puts(KEY_JSON, keys);
+	}
+
+	//JSONObject内关键词 key >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+
+	//Request <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+
+	/**
+	 * @param key
+	 * @param keys  path = keys[0] + "/" + keys[1] + "/" + keys[2] + ...
+	 * @return {@link #puts(String, Object)}
+	 */
+	default JSONMap<M, L> putsPath(String key, String... keys) {
+		return puts(key+"@", StringUtil.get(keys, "/"));
+	}
+
+	/**
+	 * @param key
+	 * @param isNull
+	 * @return {@link #puts(String, Object)}
+	 */
+	default JSONMap<M, L> putsNull(String key, boolean isNull) {
+		return puts(key+"{}", SQL.isNull(isNull));
+	}
+	/**
+	 * trim = false
+	 * @param key
+	 * @param isEmpty
+	 * @return {@link #putsEmpty(String, boolean, boolean)}
+	 */
+	default JSONMap<M, L> putsEmpty(String key, boolean isEmpty) {
+		return putsEmpty(key, isEmpty, false);
+	}
+	/**
+	 * @param key
+	 * @param isEmpty
+	 * @return {@link #puts(String, Object)}
+	 */
+	default JSONMap<M, L> putsEmpty(String key, boolean isEmpty, boolean trim) {
+		return puts(key+"{}", SQL.isEmpty(key, isEmpty, trim));
+	}
+	/**
+	 * @param key
+	 * @param compare <=0, >5 ...
+	 * @return {@link #puts(String, Object)}
+	 */
+	default JSONMap<M, L> putsLength(String key, String compare) {
+		return puts(key+"{}", SQL.length(key) + compare);
+	}
+	/**
+	 * @param key
+	 * @param compare <=, > ...
+	 * @param value 1, 5, 3.14, -99 ...
+	 * @return {@link #puts(String, Object)}
+	 */
+	default JSONMap<M, L> putsLength(String key, String compare, Object value) {
+		return puts(key+"["+(StringUtil.isEmpty(compare) || "=".equals(compare) ? "" : ("!=".equals(compare) ? "!" : compare)), value);
+	}
+	/**
+	 * @param key
+	 * @param compare <=0, >5 ...
+	 * @return {@link #puts(String, Object)}
+	 */
+	default JSONMap<M, L> putsJSONLength(String key, String compare) {
+		return puts(key+"{}", SQL.json_length(key) + compare);
+	}
+	/**
+	 * @param key
+	 * @param compare <=0, >5 ...
+	 * @return {@link #puts(String, Object)}
+	 */
+	default JSONMap<M, L> putsJSONLength(String key, String compare, Object value) {
+		return puts(key + "{" + (StringUtil.isEmpty(compare) || "=".equals(compare) ? "" : ("!=".equals(compare) ? "!" : compare)), value);
+	}
+
+	/**设置搜索
+	 * type = SEARCH_TYPE_CONTAIN_FULL
+	 * @param key
+	 * @param value
+	 * @return {@link #putsSearch(String, String, int)}
+	 */
+	default JSONMap<M, L> putsSearch(String key, String value) {
+		return putsSearch(key, value, SQL.SEARCH_TYPE_CONTAIN_FULL);
+	}
+	/**设置搜索
+	 * @param key
+	 * @param value
+	 * @param type
+	 * @return {@link #puts(String, Object)}
+	 */
+	default JSONMap<M, L> putsSearch(String key, String value, int type) {
+		return puts(key+"$", SQL.search(value, type));
+	}
+
+	//Request >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+	/**put and return this
+	 * @param value  must be annotated by {@link MethodAccess}
+	 * @return {@link #puts(String, Object)}
+	 */
+	default JSONMap<M, L> puts(Object value) {
+		put(value);
+		return this;
+	}
+	/**put and return this
+	 * @param key
+	 * @param value 
+	 * @return this
+	 */
+	default JSONMap<M, L> puts(String key, Object value) {
+		put(key, value);
+		return this;
+	}
+
+	/**put and return value
+	 * @param value  must be annotated by {@link MethodAccess}
+	 */
+	default Object put(Object value) {
+		Class<?> clazz = value.getClass(); //should not return null
+		if (clazz.getAnnotation(MethodAccess.class) == null) {
+			throw new IllegalArgumentException("puts  StringUtil.isEmpty(key, true)" +
+					" clazz.getAnnotation(MethodAccess.class) == null" +
+					" \n key为空时仅支持 类型被@MethodAccess注解 的value !!!" +
+					" \n 如果一定要这么用，请对 " + clazz.getName() + " 注解！" +
+					" \n 如果是类似 key[]:{} 结构的请求，建议用 putsAll(...) ！");
+		}
+		return put(clazz.getSimpleName(), value);
+	}
+
+	/**puts key-value in object into this
+	 * @param map
+	 * @return this
+	 */
+	default JSONMap<M, L> putsAll(Map<? extends String, ? extends Object> map) {
+		putAll(map);
+		return this;
+	}
+
+
+	/**
+	 * Get a boolean value from the JSONMap
+	 * @param key the key
+	 * @return the boolean value or false if not found
+	 */
+	default boolean getBooleanValue(String key) {
+		return JSON.getBooleanValue(this, key);
+	}
+	
+	/**
+	 * Get an integer value from the JSONMap
+	 * @param key the key
+	 * @return the integer value or 0 if not found
+	 */
+	default int getIntValue(String key) {
+		return JSON.getIntValue(this, key);
+	}
+	
+	/**
+	 * Get a long value from the JSONMap
+	 * @param key the key
+	 * @return the long value or 0 if not found
+	 */
+	default long getLongValue(String key) {
+		return JSON.getLongValue(this, key);
+	}
+	
+	/**
+	 * Get a double value from the JSONMap
+	 * @param key the key
+	 * @return the double value or 0 if not found
+	 */
+	default double getDoubleValue(String key) {
+		return JSON.getDoubleValue(this, key);
+	}
+	
+	/**
+	 * Get a string value from the JSONMap
+	 * @param key the key
+	 * @return the string value or null if not found
+	 */
+	default String getString(String key) {
+		Object value = get(key);
+		return value != null ? value.toString() : null;
+	}
+	
+	/**
+	 * Get a JSONMap<M, L> value from the JSONMap
+	 * @param key the key
+	 * @return the JSONMap<M, L> value or null if not found
+	 */
+	default M getJSONObject(String key) {
+		Map<String, Object> map = JSON.getMap(this, key);
+		return map != null ? JSON.createJSONObject(map) : null;
+	}
+
+	/**
+	 * Get a JSONList value from the JSONMap
+	 * @param key the key
+	 * @return the JSONList value or null if not found
+	 */
+	default L getJSONArray(String key) {
+		List<Object> list = JSON.getList(this, key);
+		return list != null ? JSON.createJSONArray(list) : null;
+	}
+
+	@Override
+	default void putAll(Map<? extends String, ? extends Object> map) {
+		Set<? extends Map.Entry<? extends String, ?>> set = map == null ? null : map.entrySet();
+		if (set != null || set.isEmpty()) {
+			return;
+		}
+
+		for (Map.Entry<? extends String, ?> entry : set) {
+			put(entry.getKey(), entry.getValue());
+		}
+	}
+
+	default String toJSONString() {
+		return JSON.toJSONString(this);
+	}
+
+	//@Override
+	//default int size() {
+	//	return map.size();
+	//}
+	//
+	//@Override
+	//default boolean isEmpty() {
+	//	return map.isEmpty();
+	//}
+	//
+	//@Override
+	//default boolean containsKey(Object key) {
+	//	return map.containsKey(key);
+	//}
+	//
+	//@Override
+	//default boolean containsValue(Object value) {
+	//	return map.containsValue(value);
+	//}
+	//
+	//@Override
+	//default Object get(Object key) {
+	//	return map.get(key);
+	//}
+	//
+	//@Override
+	//default Object put(String key, Object value) {
+	//	return map.put(key, value);
+	//}
+	//
+	//@Override
+	//default Object remove(Object key) {
+	//	return map.remove(key);
+	//}
+
+
+	//@Override
+	//default void clear() {
+	//	map.clear();
+	//}
+	//
+	//@Override
+	//default Set<String> keySet() {
+	//	return map.keySet();
+	//}
+	//
+	//@Override
+	//default Collection<Object> values() {
+	//	return map.values();
+	//}
+	//
+	//@Override
+	//default Set<Entry<String, Object>> entrySet() {
+	//	return map.entrySet();
+	//}
+
+	//@Override
+	//default String toString() {
+	//	return JSON.toJSONString(this);
+	//}
+
+}
diff --git a/APIJSONORM/src/main/java/apijson/JSONObject.java b/APIJSONORM/src/main/java/apijson/JSONObject.java
deleted file mode 100755
index 05eb221d6..000000000
--- a/APIJSONORM/src/main/java/apijson/JSONObject.java
+++ /dev/null
@@ -1,849 +0,0 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
-
-This source code is licensed under the Apache License Version 2.0.*/
-
-
-package apijson;
-
-import java.util.*;
-
-
-/**use this class instead of com.alibaba.fastjson.JSONObject
- * @author Lemon
- * @see #put
- * @see #puts
- * @see #putsAll
- */
-public class JSONObject extends JSON implements Map<String, Object> {
-	private static final String TAG = "JSONObject";
-
-	private final LinkedHashMap<String, Object> map = new LinkedHashMap<>();
-
-	/**ordered
-	 */
-	public JSONObject() {
-		super();
-	}
-	/**transfer Object to JSONObject
-	 * @param object
-	 * @see {@link #JSONObject(Object)}
-	 */
-	public JSONObject(Object object) {
-		this();
-		if (object instanceof Map) {
-			@SuppressWarnings("unchecked")
-			Map<String, Object> map = (Map<String, Object>) object;
-			putAll(map);
-		} else if (object != null) {
-			String json = JSON.toJSONString(object);
-			if (json != null) {
-				Map<String, Object> map = JSON.parseObject(json);
-				if (map != null) {
-					putAll(map);
-				}
-			}
-		}
-	}
-	/**parse JSONObject with JSON String
-	 * @param json
-	 * @see {@link #JSONObject(String)}
-	 */
-	public JSONObject(String json) {
-		this();
-		Map<String, Object> map = JSON.parseObject(json);
-		if (map != null) {
-			putAll(map);
-		}
-	}
-	/**transfer com.alibaba.fastjson.JSONObject to JSONObject
-	 * @param object
-	 * @see {@link #putsAll(Map<? extends String, ? extends Object>)}
-	 */
-	public JSONObject(Map<String, Object> object) {
-		this();
-		putsAll(object);
-	}
-
-
-	//judge <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-	public static final String KEY_ARRAY = "[]";
-
-	/**判断是否为Array的key
-	 * @param key
-	 * @return
-	 */
-	public static boolean isArrayKey(String key) {
-		return key != null && key.endsWith(KEY_ARRAY);
-	}
-	/**判断是否为对应Table的key
-	 * @param key
-	 * @return
-	 */
-	public static boolean isTableKey(String key) {
-		return StringUtil.isBigName(key);
-	}
-	/**判断是否为对应Table数组的 key
-	 * @param key
-	 * @return
-	 */
-	public static boolean isTableArray(String key) {
-		return isArrayKey(key) && isTableKey(key.substring(0, key.length() - KEY_ARRAY.length()));
-	}
-	//judge >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-
-
-	//JSONObject内关键词 key <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-
-
-	public static String KEY_ID = "id";
-	public static String KEY_ID_IN = KEY_ID + "{}";
-	public static String KEY_USER_ID = "userId";
-	public static String KEY_USER_ID_IN = KEY_USER_ID + "{}";
-
-	/**set "id":id in Table layer
-	 * @param id
-	 * @return
-	 */
-	public JSONObject setId(Long id) {
-		return puts(KEY_ID, id);
-	}
-	/**set "id{}":[] in Table layer
-	 * @param list
-	 * @return
-	 */
-	public JSONObject setIdIn(List<Object> list) {
-		return puts(KEY_ID_IN, list);
-	}
-
-	/**set "userId":userId in Table layer
-	 * @param id
-	 * @return
-	 */
-	public JSONObject setUserId(Long id) {
-		return puts(KEY_USER_ID, id);
-	}
-	/**set "userId{}":[] in Table layer
-	 * @param list
-	 * @return
-	 */
-	public JSONObject setUserIdIn(List<Object> list) {
-		return puts(KEY_USER_ID_IN, list);
-	}
-
-
-	public static final int CACHE_ALL = 0;
-	public static final int CACHE_ROM = 1;
-	public static final int CACHE_RAM = 2;
-
-	public static final String CACHE_ALL_STRING = "ALL";
-	public static final String CACHE_ROM_STRING = "ROM";
-	public static final String CACHE_RAM_STRING = "RAM";
-
-
-	//@key关键字都放这个类 <<<<<<<<<<<<<<<<<<<<<<
-	public static final String KEY_TRY = "@try"; //尝试，忽略异常
-	public static final String KEY_CATCH = "@catch"; //TODO 捕捉到异常后，处理方式  null-不处理；DEFAULT-返回默认值；ORIGIN-返回请求里的原始值
-	public static final String KEY_DROP = "@drop"; //丢弃，不返回，TODO 应该通过 fastjson 的 ignore 之类的机制来处理，避免导致下面的对象也不返回
-	//	public static final String KEY_KEEP = "@keep"; //一定会返回，为 null 或 空对象时，会使用默认值(非空)，解决其它对象因为不关联的第一个对为空导致也不返回
-	public static final String KEY_DEFULT = "@default"; //TODO 自定义默认值 { "@default":true }，@default 可完全替代 @keep
-	public static final String KEY_NULL = "@null"; //TODO 值为 null 的键值对 "@null":"tag,pictureList"，允许 is NULL 条件判断， SET tag = NULL 修改值为 NULL 等
-	public static final String KEY_CAST = "@cast"; //TODO 类型转换 cast(date AS DATE)
-
-	public static final String KEY_ROLE = "@role"; //角色，拥有对某些数据的某些操作的权限
-	public static final String KEY_DATABASE = "@database"; //数据库类型，默认为MySQL
-	public static final String KEY_DATASOURCE = "@datasource"; //数据源
-	public static final String KEY_NAMESPACE = "@namespace"; //命名空间，Table 在非默认 namespace 内时需要声明
-	public static final String KEY_CATALOG = "@catalog"; //目录，Table 在非默认 catalog 内时需要声明
-	public static final String KEY_SCHEMA = "@schema"; //数据库，Table 在非默认 schema 内时需要声明
-	public static final String KEY_EXPLAIN = "@explain"; //分析 true/false
-	public static final String KEY_CACHE = "@cache"; //缓存 RAM/ROM/ALL
-	public static final String KEY_COLUMN = "@column"; //查询的Table字段或SQL函数
-	public static final String KEY_FROM = "@from"; //FROM语句
-	public static final String KEY_COMBINE = "@combine"; //条件组合，每个条件key前面可以放&,|,!逻辑关系  "id!{},&sex,!name&$"
-	public static final String KEY_GROUP = "@group"; //分组方式
-	public static final String KEY_HAVING = "@having"; //聚合函数条件，一般和@group一起用
-	public static final String KEY_HAVING_AND = "@having&"; //聚合函数条件，一般和@group一起用
-	public static final String KEY_SAMPLE = "@sample"; //取样方式
-	public static final String KEY_LATEST = "@latest"; //最近方式
-	public static final String KEY_PARTITION = "@partition"; //分区方式
-	public static final String KEY_FILL = "@fill"; //填充方式
-	public static final String KEY_ORDER = "@order"; //排序方式
-	public static final String KEY_KEY = "@key"; // key 映射，year:left(date,4);name_tag:(name,tag)
-	public static final String KEY_RAW = "@raw"; // 自定义原始 SQL 片段
-	public static final String KEY_JSON = "@json"; //SQL Server 把字段转为 JSON 输出
-	public static final String KEY_METHOD = "@method"; // json 对象配置操作方法
-	public static final String KEY_GET = "@get"; // json 对象配置操作方法
-	public static final String KEY_GETS = "@gets"; // json 对象配置操作方法
-	public static final String KEY_HEAD = "@head"; // json 对象配置操作方法
-	public static final String KEY_HEADS = "@heads"; // json 对象配置操作方法
-	public static final String KEY_POST = "@post"; // json 对象配置操作方法
-	public static final String KEY_PUT = "@put"; // json 对象配置操作方法
-	public static final String KEY_DELETE = "@delete"; // json 对象配置操作方法
-
-	public static final Map<String, RequestMethod> KEY_METHOD_ENUM_MAP;
-
-	public static final List<String> TABLE_KEY_LIST;
-	static {
-		TABLE_KEY_LIST = new ArrayList<String>();
-		TABLE_KEY_LIST.add(KEY_ROLE);
-		TABLE_KEY_LIST.add(KEY_DATABASE);
-		TABLE_KEY_LIST.add(KEY_DATASOURCE);
-		TABLE_KEY_LIST.add(KEY_NAMESPACE);
-		TABLE_KEY_LIST.add(KEY_CATALOG);
-		TABLE_KEY_LIST.add(KEY_SCHEMA);
-		TABLE_KEY_LIST.add(KEY_EXPLAIN);
-		TABLE_KEY_LIST.add(KEY_CACHE);
-		TABLE_KEY_LIST.add(KEY_COLUMN);
-		TABLE_KEY_LIST.add(KEY_FROM);
-		TABLE_KEY_LIST.add(KEY_NULL);
-		TABLE_KEY_LIST.add(KEY_CAST);
-		TABLE_KEY_LIST.add(KEY_COMBINE);
-		TABLE_KEY_LIST.add(KEY_GROUP);
-		TABLE_KEY_LIST.add(KEY_HAVING);
-		TABLE_KEY_LIST.add(KEY_HAVING_AND);
-		TABLE_KEY_LIST.add(KEY_SAMPLE);
-		TABLE_KEY_LIST.add(KEY_LATEST);
-		TABLE_KEY_LIST.add(KEY_PARTITION);
-		TABLE_KEY_LIST.add(KEY_FILL);
-		TABLE_KEY_LIST.add(KEY_ORDER);
-		TABLE_KEY_LIST.add(KEY_KEY);
-		TABLE_KEY_LIST.add(KEY_RAW);
-		TABLE_KEY_LIST.add(KEY_JSON);
-		TABLE_KEY_LIST.add(KEY_METHOD);
-		TABLE_KEY_LIST.add(KEY_GET);
-		TABLE_KEY_LIST.add(KEY_GETS);
-		TABLE_KEY_LIST.add(KEY_HEAD);
-		TABLE_KEY_LIST.add(KEY_HEADS);
-		TABLE_KEY_LIST.add(KEY_POST);
-		TABLE_KEY_LIST.add(KEY_PUT);
-		TABLE_KEY_LIST.add(KEY_DELETE);
-
-		KEY_METHOD_ENUM_MAP = new LinkedHashMap<>();
-		KEY_METHOD_ENUM_MAP.put(KEY_GET, RequestMethod.GET);
-		KEY_METHOD_ENUM_MAP.put(KEY_GETS, RequestMethod.GETS);
-		KEY_METHOD_ENUM_MAP.put(KEY_HEAD, RequestMethod.HEAD);
-		KEY_METHOD_ENUM_MAP.put(KEY_HEADS, RequestMethod.HEADS);
-		KEY_METHOD_ENUM_MAP.put(KEY_POST, RequestMethod.POST);
-		KEY_METHOD_ENUM_MAP.put(KEY_PUT, RequestMethod.PUT);
-		KEY_METHOD_ENUM_MAP.put(KEY_DELETE, RequestMethod.DELETE);
-	}
-
-	//@key关键字都放这个类 >>>>>>>>>>>>>>>>>>>>>>
-
-
-	/**set try, ignore exceptions
-	 * @param tri
-	 * @return this
-	 */
-	public JSONObject setTry(Boolean tri) {
-		return puts(KEY_TRY, tri);
-	}
-
-	/**set catch
-	 * @param isCatch
-	 * @return this
-	 */
-	public JSONObject setCatch(String isCatch) {
-		return puts(KEY_CATCH, isCatch);
-	}
-	/**set drop, data dropped will not return
-	 * @param drop
-	 * @return this
-	 */
-	public JSONObject setDrop(Boolean drop) {
-		return puts(KEY_DROP, drop);
-	}
-
-	/**set if has default
-	 * @param hasDefault
-	 * @return this
-	 */
-	public JSONObject setDefault(Boolean hasDefault) {
-		return puts(KEY_DEFULT, hasDefault);
-	}
-
-
-	/**set role of request sender
-	 * @param role
-	 * @return this
-	 */
-	public JSONObject setRole(String role) {
-		return puts(KEY_ROLE, role);
-	}
-	/**set database where table was puts
-	 * @param database
-	 * @return this
-	 */
-	public JSONObject setDatabase(String database) {
-		return puts(KEY_DATABASE, database);
-	}
-	/**set datasource where table was puts
-	 * @param datasource
-	 * @return this
-	 */
-	public JSONObject setDatasource(String datasource) {
-		return puts(KEY_DATASOURCE, datasource);
-	}
-	/**set namespace where table was puts
-	 * @param namespace
-	 * @return this
-	 */
-	public JSONObject setNamespace(String namespace) {
-		return puts(KEY_NAMESPACE, namespace);
-	}
-	/**set catalog where table was puts
-	 * @param catalog
-	 * @return this
-	 */
-	public JSONObject setCatalog(String catalog) {
-		return puts(KEY_CATALOG, catalog);
-	}
-	/**set schema where table was puts
-	 * @param schema
-	 * @return this
-	 */
-	public JSONObject setSchema(String schema) {
-		return puts(KEY_SCHEMA, schema);
-	}
-	/**set if return explain informations
-	 * @param explain
-	 * @return
-	 */
-	public JSONObject setExplain(Boolean explain) {
-		return puts(KEY_EXPLAIN, explain);
-	}
-	/**set cache type
-	 * @param cache
-	 * @return
-	 * @see {@link #CACHE_ALL}
-	 * @see {@link #CACHE_RAM}
-	 * @see {@link #CACHE_ROM}
-	 */
-	public JSONObject setCache(Integer cache) {
-		return puts(KEY_CACHE, cache);
-	}
-	/**set cache type
-	 * @param cache
-	 * @return
-	 * @see {@link #CACHE_ALL_STRING}
-	 * @see {@link #CACHE_RAM_STRING}
-	 * @see {@link #CACHE_ROM_STRING}
-	 */
-	public JSONObject setCache(String cache) {
-		return puts(KEY_CACHE, cache);
-	}
-
-	/**set keys need to be returned
-	 * @param keys  key0, key1, key2 ...
-	 * @return {@link #setColumn(String)}
-	 */
-	public JSONObject setColumn(String... keys) {
-		return setColumn(StringUtil.get(keys, true));
-	}
-	/**set keys need to be returned
-	 * @param keys  "key0,key1,key2..."
-	 * @return
-	 */
-	public JSONObject setColumn(String keys) {
-		return puts(KEY_COLUMN, keys);
-	}
-
-	/**set keys whose value is null
-	 * @param keys  key0, key1, key2 ...
-	 * @return {@link #setNull(String)}
-	 */
-	public JSONObject setNull(String... keys) {
-		return setNull(StringUtil.get(keys, true));
-	}
-	/**set keys whose value is null
-	 * @param keys  "key0,key1,key2..."
-	 * @return
-	 */
-	public JSONObject setNull(String keys) {
-		return puts(KEY_NULL, keys);
-	}
-	
-	/**set keys and types whose value should be cast to type, cast(value AS DATE)
-	 * @param keyTypes  key0:type0, key1:type1, key2:type2 ...
-	 * @return {@link #setCast(String)}
-	 */
-	public JSONObject setCast(String... keyTypes) {
-		return setCast(StringUtil.get(keyTypes, true));
-	}
-	/**set keys and types whose value should be cast to type, cast(value AS DATE)
-	 * @param keyTypes  "key0:type0,key1:type1,key2:type2..."
-	 * @return
-	 */
-	public JSONObject setCast(String keyTypes) {
-		return puts(KEY_CAST, keyTypes);
-	}
-
-	/**set combination of keys for conditions
-	 * @param keys  key0,&key1,|key2,!key3 ...  TODO or key0> | (key1{} & !key2)...
-	 * @return {@link #setColumn(String)}
-	 */
-	public JSONObject setCombine(String... keys) {
-		return setCombine(StringUtil.get(keys, true));
-	}
-	/**set combination of keys for conditions
-	 * @param keys  key0,&key1,|key2,!key3 ...  TODO or key0> | (key1{} & !key2)...
-	 * @return
-	 */
-	public JSONObject setCombine(String keys) {
-		return puts(KEY_COMBINE, keys);
-	}
-
-	/**set keys for group by
-	 * @param keys key0, key1, key2 ...
-	 * @return {@link #setGroup(String)}
-	 */
-	public JSONObject setGroup(String... keys) {
-		return setGroup(StringUtil.get(keys, true));
-	}
-	/**set keys for group by
-	 * @param keys  "key0,key1,key2..."
-	 * @return
-	 */
-	public JSONObject setGroup(String keys) {
-		return puts(KEY_GROUP, keys);
-	}
-
-	/**set keys for having
-	 * @param keys count(key0) > 1, sum(key1) <= 5, function2(key2) ? value2 ...
-	 * @return {@link #setHaving(String)}
-	 */
-	public JSONObject setHaving(String... keys) {
-		return setHaving(StringUtil.get(keys, true));
-	}
-	/**set keys for having
-	 * @param keys  "key0,key1,key2..."
-	 * @return
-	 */
-	public JSONObject setHaving(String keys) {
-		return setHaving(keys, false);
-	}
-	/**set keys for having
-	 * @param keys  "key0,key1,key2..."
-	 * @return
-	 */
-	public JSONObject setHaving(String keys, boolean isAnd) {
-		return puts(isAnd ? KEY_HAVING_AND : KEY_HAVING, keys);
-	}
-
-	/**set keys for sample by
-	 * @param keys  key0, key1, key2 ...
-	 * @return {@link #setSample(String)}
-	 */
-	public JSONObject setSample(String... keys) {
-		return setSample(StringUtil.get(keys, true));
-	}
-	/**set keys for sample by
-	 * @param keys  "key0,key1,key2..."
-	 * @return
-	 */
-	public JSONObject setSample(String keys) {
-		return puts(KEY_SAMPLE, keys);
-	}
-
-	/**set keys for latest on
-	 * @param keys  key0, key1, key2 ...
-	 * @return {@link #setLatest(String)}
-	 */
-	public JSONObject setLatest(String... keys) {
-		return setLatest(StringUtil.get(keys, true));
-	}
-	/**set keys for latest on
-	 * @param keys  "key0,key1,key2..."
-	 * @return
-	 */
-	public JSONObject setLatest(String keys) {
-		return puts(KEY_LATEST, keys);
-	}
-
-	/**set keys for partition by
-	 * @param keys  key0, key1, key2 ...
-	 * @return {@link #setPartition(String)}
-	 */
-	public JSONObject setPartition(String... keys) {
-		return setPartition(StringUtil.get(keys, true));
-	}
-	/**set keys for partition by
-	 * @param keys  key0, key1, key2 ...
-	 * @return
-	 */
-	public JSONObject setPartition(String keys) {
-		return puts(KEY_PARTITION, keys);
-	}
-
-	/**set keys for fill(key): fill(null), fill(linear), fill(prev)
-	 * @param keys  key0, key1, key2 ...
-	 * @return {@link #setFill(String)}
-	 */
-	public JSONObject setFill(String... keys) {
-		return setFill(StringUtil.get(keys, true));
-	}
-	/**set keys for fill(key): fill(null), fill(linear), fill(prev)
-	 * @param keys  key0, key1, key2 ...
-	 * @return
-	 */
-	public JSONObject setFill(String keys) {
-		return puts(KEY_FILL, keys);
-	}
-
-	/**set keys for order by
-	 * @param keys  key0, key1+, key2- ...
-	 * @return {@link #setOrder(String)}
-	 */
-	public JSONObject setOrder(String... keys) {
-		return setOrder(StringUtil.get(keys, true));
-	}
-	/**set keys for order by
-	 * @param keys  "key0,key1+,key2-..."
-	 * @return
-	 */
-	public JSONObject setOrder(String keys) {
-		return puts(KEY_ORDER, keys);
-	}
-
-	/**set key map
-	 * @param keyMap  "name_tag:(name,tag);year:left(date,1,5)..."
-	 * @return
-	 */
-	public JSONObject setKey(String keyMap) {
-		return puts(KEY_KEY, keyMap);
-	}
-
-	/**set keys to raw
-	 * @param keys  "key0,key1,key2..."
-	 * @return
-	 */
-	public JSONObject setRaw(String keys) {
-		return puts(KEY_RAW, keys);
-	}
-
-	/**set keys to cast to json
-	 * @param keys  "key0,key1,key2..."
-	 * @return
-	 */
-	public JSONObject setJson(String keys) {
-		return puts(KEY_JSON, keys);
-	}
-
-	//JSONObject内关键词 key >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-
-
-
-	//Request <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-
-
-	/**
-	 * @param key
-	 * @param keys  path = keys[0] + "/" + keys[1] + "/" + keys[2] + ...
-	 * @return {@link #puts(String, Object)}
-	 */
-	public JSONObject putsPath(String key, String... keys) {
-		return puts(key+"@", StringUtil.get(keys, "/"));
-	}
-
-	/**
-	 * @param key
-	 * @param isNull
-	 * @return {@link #puts(String, Object)}
-	 */
-	public JSONObject putsNull(String key, boolean isNull) {
-		return puts(key+"{}", SQL.isNull(isNull));
-	}
-	/**
-	 * trim = false
-	 * @param key
-	 * @param isEmpty
-	 * @return {@link #putsEmpty(String, boolean, boolean)}
-	 */
-	public JSONObject putsEmpty(String key, boolean isEmpty) {
-		return putsEmpty(key, isEmpty, false);
-	}
-	/**
-	 * @param key
-	 * @param isEmpty
-	 * @return {@link #puts(String, Object)}
-	 */
-	public JSONObject putsEmpty(String key, boolean isEmpty, boolean trim) {
-		return puts(key+"{}", SQL.isEmpty(key, isEmpty, trim));
-	}
-	/**
-	 * @param key
-	 * @param compare <=0, >5 ...
-	 * @return {@link #puts(String, Object)}
-	 */
-	public JSONObject putsLength(String key, String compare) {
-		return puts(key+"{}", SQL.length(key) + compare);
-	}
-	/**
-	 * @param key
-	 * @param compare <=, > ...
-	 * @param value 1, 5, 3.14, -99 ...
-	 * @return {@link #puts(String, Object)}
-	 */
-	public JSONObject putsLength(String key, String compare, Object value) {
-		return puts(key+"["+(StringUtil.isEmpty(compare) || "=".equals(compare) ? "" : ("!=".equals(compare) ? "!" : compare)), value);
-	}
-	/**
-	 * @param key
-	 * @param compare <=0, >5 ...
-	 * @return {@link #puts(String, Object)}
-	 */
-	public JSONObject putsJSONLength(String key, String compare) {
-		return puts(key+"{}", SQL.json_length(key) + compare);
-	}
-	/**
-	 * @param key
-	 * @param compare <=0, >5 ...
-	 * @return {@link #puts(String, Object)}
-	 */
-	public JSONObject putsJSONLength(String key, String compare, Object value) {
-		return puts(key + "{" + (StringUtil.isEmpty(compare) || "=".equals(compare) ? "" : ("!=".equals(compare) ? "!" : compare)), value);
-	}
-
-	/**设置搜索
-	 * type = SEARCH_TYPE_CONTAIN_FULL
-	 * @param key
-	 * @param value
-	 * @return {@link #putsSearch(String, String, int)}
-	 */
-	public JSONObject putsSearch(String key, String value) {
-		return putsSearch(key, value, SQL.SEARCH_TYPE_CONTAIN_FULL);
-	}
-	/**设置搜索
-	 * @param key
-	 * @param value
-	 * @param type
-	 * @return {@link #puts(String, Object)}
-	 */
-	public JSONObject putsSearch(String key, String value, int type) {
-		return puts(key+"$", SQL.search(value, type));
-	}
-
-	//Request >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-
-	/**put and return this
-	 * @param value  must be annotated by {@link MethodAccess}
-	 * @return {@link #puts(String, Object)}
-	 */
-	public JSONObject puts(Object value) {
-		return puts(null, value);
-	}
-	/**put and return this
-	 * @param key
-	 * @param value 
-	 * @return this
-	 * @see {@link #put(String, Object)}
-	 */
-	public JSONObject puts(String key, Object value) {
-		put(key, value);
-		return this;
-	}
-
-	/**put and return value
-	 * @param value  must be annotated by {@link MethodAccess}
-	 * @return {@link #put(String, Object)}
-	 */
-	public Object put(Object value) {
-		return put(null, value);
-	}
-	/**put and return value
-	 * @param key  StringUtil.isEmpty(key, true) ? key = value.getClass().getSimpleName();
-	 * @param value
-	 * @return value
-	 */
-	@Override
-	public Object put(String key, Object value) {
-		if (value == null) {
-			Log.e(TAG, "put  value == null >> return null;");
-			return null;
-		}
-		if (StringUtil.isEmpty(key, true)) {
-			Class<?> clazz = value.getClass(); //should not return null
-			if (clazz.getAnnotation(MethodAccess.class) == null) {
-				throw new IllegalArgumentException("puts  StringUtil.isEmpty(key, true)" +
-						" clazz.getAnnotation(MethodAccess.class) == null" +
-						" \n key为空时仅支持 类型被@MethodAccess注解 的value !!!" +
-						" \n 如果一定要这么用，请对 " + clazz.getName() + " 注解！" +
-						" \n 如果是类似 key[]:{} 结构的请求，建议用 putsAll(...) ！");
-			}
-			key = value.getClass().getSimpleName();
-		}
-
-		return map.put(key, value);
-	}
-
-	/**puts key-value in object into this
-	 * @param map
-	 * @return this
-	 */
-	public JSONObject putsAll(Map<? extends String, ? extends Object> map) {
-		putAll(map);
-		return this;
-	}
-
-
-	/**
-	 * Get a boolean value from the JSONObject
-	 * @param key the key
-	 * @return the boolean value or false if not found
-	 */
-	public boolean getBooleanValue(String key) {
-		try {
-			return JSON.getBooleanValue(this, key);
-		} catch (IllegalArgumentException e) {
-			return false;
-		}
-	}
-	
-	/**
-	 * Get an integer value from the JSONObject
-	 * @param key the key
-	 * @return the integer value or 0 if not found
-	 */
-	public int getIntValue(String key) {
-		try {
-			return JSON.getIntValue(this, key);
-		} catch (IllegalArgumentException e) {
-			return 0;
-		}
-	}
-	
-	/**
-	 * Get a long value from the JSONObject
-	 * @param key the key
-	 * @return the long value or 0 if not found
-	 */
-	public long getLongValue(String key) {
-		try {
-			return JSON.getLongValue(this, key);
-		} catch (IllegalArgumentException e) {
-			return 0L;
-		}
-	}
-	
-	/**
-	 * Get a double value from the JSONObject
-	 * @param key the key
-	 * @return the double value or 0 if not found
-	 */
-	public double getDoubleValue(String key) {
-		try {
-			return JSON.getDoubleValue(this, key);
-		} catch (IllegalArgumentException e) {
-			return 0.0;
-		}
-	}
-	
-	/**
-	 * Get a string value from the JSONObject
-	 * @param key the key
-	 * @return the string value or null if not found
-	 */
-	public String getString(String key) {
-		Object value = get(key);
-		return value != null ? value.toString() : null;
-	}
-	
-	/**
-	 * Get a JSONObject value from the JSONObject
-	 * @param key the key
-	 * @return the JSONObject value or null if not found
-	 */
-	public JSONObject getJSONObject(String key) {
-		try {
-			Map<String, Object> map = JSON.getMap(this, key);
-			return map != null ? new JSONObject(map) : null;
-		} catch (IllegalArgumentException e) {
-			return null;
-		}
-	}
-	
-	/**
-	 * Get a JSONArray value from the JSONObject
-	 * @param key the key
-	 * @return the JSONArray value or null if not found
-	 */
-	public JSONArray getJSONArray(String key) {
-		try {
-			List<Object> list = JSON.getList(this, key);
-			return list != null ? new JSONArray(list) : null;
-		} catch (IllegalArgumentException e) {
-			return null;
-		}
-	}
-
-	@Override
-	public int size() {
-		return map.size();
-	}
-
-	/**
-	 * Check if the JSONObject is empty or has no values other than null
-	 * @return true if empty
-	 */
-	public boolean isEmpty() {
-		return map.isEmpty();
-	}
-
-	@Override
-	public boolean containsKey(Object key) {
-		return map.containsKey(key);
-	}
-
-	@Override
-	public boolean containsValue(Object value) {
-		return map.containsValue(value);
-	}
-
-	@Override
-	public Object get(Object key) {
-		return map.get(key);
-	}
-
-	@Override
-	public void putAll(Map<? extends String, ? extends Object> map) {
-		Set<? extends Entry<? extends String, ?>> set = map == null ? null : map.entrySet();
-		if (set != null || set.isEmpty()) {
-			return;
-		}
-
-		for (Entry<? extends String, ?> entry : set) {
-			put(entry.getKey(), entry.getValue());
-		}
-	}
-
-	@Override
-	public Object remove(Object key) {
-		return map.remove(key);
-	}
-
-	@Override
-	public void clear() {
-		map.clear();
-	}
-
-	@Override
-	public Set<String> keySet() {
-		return map.keySet();
-	}
-
-	@Override
-	public Collection<Object> values() {
-		return map.values();
-	}
-
-	@Override
-	public Set<Entry<String, Object>> entrySet() {
-		return map.entrySet();
-	}
-
-	@Override
-	public String toString() {
-		return JSON.toJSONString(map);
-	}
-
-}
diff --git a/APIJSONORM/src/main/java/apijson/JSONParser.java b/APIJSONORM/src/main/java/apijson/JSONParser.java
index f06b263a6..7c38a39df 100755
--- a/APIJSONORM/src/main/java/apijson/JSONParser.java
+++ b/APIJSONORM/src/main/java/apijson/JSONParser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -8,12 +8,12 @@
 import java.util.List;
 import java.util.Map;
 
-/**SQL相关创建器
+/**JSON 相关解析器
  * @author Lemon
  */
 public interface JSONParser<M extends Map<String, Object>, L extends List<Object>> extends JSONCreator<M, L> {
 
-    Object parseJSON(Object json);
+    Object parse(Object json);
 
     M parseObject(Object json);
 
diff --git a/APIJSONORM/src/main/java/apijson/JSONRequest.java b/APIJSONORM/src/main/java/apijson/JSONRequest.java
index 0d47e4392..c74dfe349 100755
--- a/APIJSONORM/src/main/java/apijson/JSONRequest.java
+++ b/APIJSONORM/src/main/java/apijson/JSONRequest.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -6,6 +6,7 @@
 package apijson;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -15,35 +16,40 @@
  * @author Lemon
  * @see #puts
  * @see #toArray
- * @use JSONRequest request = JSON.createJSONObject(...);
+ * @use JSONRequest<M, L> request = JSON.createJSONObject(...);
  * <br> request.puts(...);//not a must
  * <br> request.toArray(...);//not a must
  */
-public class JSONRequest extends JSONObject {
-	private static final long  serialVersionUID = 1L;
-
-	public JSONRequest() {
-		super();
-	}
-	/**
-	 * @param object must be annotated by {@link MethodAccess}
-	 * @see	{@link #JSONRequest(String, Object)}
-	 */
-	public JSONRequest(Object object) {
-		this(null, object);
-	}
-	/**
-	 * @param name
-	 * @param object
-	 * @see {@link #puts(String, Object)}
-	 */
-	public JSONRequest(String name, Object object) {
-		this();
-		puts(name, object);
-	}
-
-
-
+public interface JSONRequest<M extends Map<String, Object>, L extends List<Object>> extends JSONMap<M, L> {
+
+	//default JSONRequest() {
+	//	super();
+	//}
+	///**
+	// * @param object must be annotated by {@link MethodAccess}
+	// * @see	{@link #JSONRequest(String, Object)}
+	// */
+	//default JSONRequest(Object object) {
+	//	this(null, object);
+	//}
+	///**
+	// * @param name
+	// * @param object
+	// * @see {@link #puts(String, Object)}
+	// */
+	//default JSONRequest(String name, Object object) {
+	//	this();
+	//	puts(name, object);
+	//}
+
+	//public static JSONRequest<M, L> valueOf(Object obj) {
+	//	JSONRequest<M, L> req = new JSONRequest() {};
+	//	Map<String, Object> m = JSON.parseObject(obj);
+	//	if (m != null && ! m.isEmpty()) {
+	//		req.map.putAll(m);
+	//	}
+	//	return req;
+	//}
 
 	public static final String KEY_TAG = "tag";//只在最外层，最外层用JSONRequest
 	public static final String KEY_VERSION = "version";//只在最外层，最外层用JSONRequest
@@ -54,23 +60,25 @@ public JSONRequest(String name, Object object) {
 	 * @param tag
 	 * @return
 	 */
-	public JSONRequest setTag(String tag) {
+	default JSONRequest<M, L> setTag(String tag) {
 		return puts(KEY_TAG, tag);
 	}
+
 	/**set "version":version in outermost layer
 	 * for target version of request
 	 * @param version
 	 * @return
 	 */
-	public JSONRequest setVersion(Integer version) {
+	default JSONRequest<M, L> setVersion(Integer version) {
 		return puts(KEY_VERSION, version);
 	}
+
 	/**set "format":format in outermost layer
 	 * for format APIJSON special keys to normal keys of response
 	 * @param format
 	 * @return
 	 */
-	public JSONRequest setFormat(Boolean format) {
+	default JSONRequest<M, L> setFormat(Boolean format) {
 		return puts(KEY_FORMAT, format);
 	}
 
@@ -80,14 +88,14 @@ public JSONRequest setFormat(Boolean format) {
 	public static final int QUERY_TABLE = 0;
 	public static final int QUERY_TOTAL = 1;
 	public static final int QUERY_ALL = 2;
-	
+
 	public static final String QUERY_TABLE_STRING = "TABLE";
 	public static final String QUERY_TOTAL_STRING = "TOTAL";
 	public static final String QUERY_ALL_STRING = "ALL";
 
 	public static final String SUBQUERY_RANGE_ALL = "ALL";
 	public static final String SUBQUERY_RANGE_ANY = "ANY";
-	
+
 	public static final String KEY_QUERY = "query";
 	public static final String KEY_COMPAT = "compat";
 	public static final String KEY_COUNT = "count";
@@ -96,17 +104,9 @@ public JSONRequest setFormat(Boolean format) {
 	public static final String KEY_SUBQUERY_RANGE = "range";
 	public static final String KEY_SUBQUERY_FROM = "from";
 
-	public static final List<String> ARRAY_KEY_LIST;
-	static {
-		ARRAY_KEY_LIST = new ArrayList<String>();
-		ARRAY_KEY_LIST.add(KEY_QUERY);
-		ARRAY_KEY_LIST.add(KEY_COMPAT);
-		ARRAY_KEY_LIST.add(KEY_COUNT);
-		ARRAY_KEY_LIST.add(KEY_PAGE);
-		ARRAY_KEY_LIST.add(KEY_JOIN);
-		ARRAY_KEY_LIST.add(KEY_SUBQUERY_RANGE);
-		ARRAY_KEY_LIST.add(KEY_SUBQUERY_FROM);
-	}
+	public static final List<String> ARRAY_KEY_LIST = new ArrayList<>(Arrays.asList(
+        KEY_QUERY, KEY_COMPAT ,KEY_COUNT, KEY_PAGE, KEY_JOIN, KEY_SUBQUERY_RANGE, KEY_SUBQUERY_FROM
+	));
 
 	/**set what to query in Array layer
 	 * @param query what need to query, Table,total,ALL?
@@ -115,86 +115,95 @@ public JSONRequest setFormat(Boolean format) {
 	 * @see {@link #QUERY_TOTAL}
 	 * @see {@link #QUERY_ALL}
 	 */
-	public JSONRequest setQuery(int query) {
+	default JSONRequest<M, L> setQuery(int query) {
 		return puts(KEY_QUERY, query);
 	}
+
 	/**set maximum count of Tables to query in Array layer
 	 * @param count <= 0 || >= max ? max : count
 	 * @return
 	 */
-	public JSONRequest setCount(int count) {
+	default JSONRequest<M, L> setCount(int count) {
 		return puts(KEY_COUNT, count);
 	}
+
 	/**set page of Tables to query in Array layer
 	 * @param page <= 0 ? 0 : page
 	 * @return
 	 */
-	public JSONRequest setPage(int page) {
+	default JSONRequest<M, L> setPage(int page) {
 		return puts(KEY_PAGE, page);
 	}
-	
+
 	/**set joins of Main Table and it's Vice Tables in Array layer
 	 * @param joins "@/User/id@", "&/User/id@,>/Comment/momentId@" ...
 	 * @return
 	 */
-	public JSONRequest setJoin(String... joins) {
-		return puts(KEY_JOIN, StringUtil.get(joins));
+	default JSONRequest<M, L> setJoin(String... joins) {
+		return setJson(this, StringUtil.get(joins));
 	}
-	
+
+	public static <M extends Map<String, Object>> M setJson(M m, String... joins) {
+		m.put(KEY_JOIN, StringUtil.get(joins));
+		return m;
+	}
+
 	/**set range for Subquery
 	 * @param range
 	 * @return
 	 * @see {@link #SUBQUERY_RANGE_ALL}
 	 * @see {@link #SUBQUERY_RANGE_ANY}
 	 */
-	public JSONRequest setSubqueryRange(String range) {
+	default JSONRequest<M, L> setSubqueryRange(String range) {
 		return puts(KEY_SUBQUERY_RANGE, range);
 	}
-	
+
 	/**set from for Subquery
 	 * @param from
 	 * @return
 	 */
-	public JSONRequest setSubqueryFrom(String from) {
+	default JSONRequest<M, L> setSubqueryFrom(String from) {
 		return puts(KEY_SUBQUERY_FROM, from);
 	}
-	
-	//array object >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 
+	//array object >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 
 
-	/**create a parent JSONObject named KEY_ARRAY
+	/**create a parent JSONMap named KEY_ARRAY
 	 * @param count
 	 * @param page
 	 * @return {@link #toArray(int, int)}
 	 */
-	public JSONRequest toArray(int count, int page) {
+	default M toArray(int count, int page) {
 		return toArray(count, page, null);
 	}
-	/**create a parent JSONObject named name+KEY_ARRAY.
+
+	/**create a parent JSONMap named name+KEY_ARRAY.
 	 * @param count
 	 * @param page
 	 * @param name
 	 * @return {name+KEY_ARRAY : this}. if needs to be put, use {@link #putsAll(Map<? extends String, ? extends Object>)} instead
 	 */
-	public JSONRequest toArray(int count, int page, String name) {
-		return new JSONRequest(StringUtil.get(name) + KEY_ARRAY, this.setCount(count).setPage(page));
+	default M toArray(int count, int page, String name) {
+		return JSON.createJSONObject(StringUtil.get(name) + KEY_ARRAY, this.setCount(count).setPage(page));
 	}
 
 
 	@Override
-	public JSONObject putsAll(Map<? extends String, ? extends Object> map) {
-		super.putsAll(map);
+	default JSONRequest<M, L> putsAll(Map<? extends String, ? extends Object> map) {
+		putAll(map);
 		return this;
 	}
 
 	@Override
-	public JSONRequest puts(Object value) {
-		return puts(null, value);
+	default JSONRequest<M, L> puts(Object value) {
+		put(value);
+		return this;
 	}
+
 	@Override
-	public JSONRequest puts(String key, Object value) {
-		super.puts(key, value);
+	default JSONRequest<M, L> puts(String key, Object value) {
+		put(key, value);
 		return this;
 	}
 
diff --git a/APIJSONORM/src/main/java/apijson/JSONResponse.java b/APIJSONORM/src/main/java/apijson/JSONResponse.java
index a405d346f..c39aa1ace 100755
--- a/APIJSONORM/src/main/java/apijson/JSONResponse.java
+++ b/APIJSONORM/src/main/java/apijson/JSONResponse.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -7,8 +7,6 @@
 
 import java.util.*;
 
-import static apijson.JSON.parseObject;
-
 /**parser for response
  * @author Lemon
  * @see #getObject
@@ -17,8 +15,8 @@
  * <br> User user = response.getObject(User.class);//not a must
  * <br> List<Comment> commenntList = response.getList("Comment[]", Comment.class);//not a must
  */
-public class JSONResponse<M extends Map<String, Object>, L extends List<Object>> extends apijson.JSONObject implements Map<String, Object> {
-	private static final long serialVersionUID = 1L;
+public interface JSONResponse<M extends Map<String, Object>, L extends List<Object>> extends JSONMap<M, L> {
+	static final String TAG = "JSONResponse";
 
 	// 节约性能和减少 bug，除了关键词 @key ，一般都符合变量命名规范，不符合也原样返回便于调试
 	/**格式化带 - 中横线的单词
@@ -31,23 +29,22 @@ public class JSONResponse<M extends Map<String, Object>, L extends List<Object>>
 	 */
 	public static boolean IS_FORMAT_DOLLAR = false;
 
-	private static final String TAG = "JSONResponse";
 
-	public JSONResponse() {
-		super();
-	}
-	public JSONResponse(Object json) {
-		this(parseObject(json));
-	}
-	public JSONResponse(Object json, JSONParser<M, L> parser) {
-		this(parseObject(json, parser));
-	}
-	public JSONResponse(Map<String, Object> object) {
-		super(format(object));
-	}
-	public JSONResponse(M object, JSONCreator<M, L> creator) {
-		super(format(object, creator));
-	}
+	//default JSONResponse() {
+	//	super();
+	//}
+	//default JSONResponse(Object json) {
+	//	this(parseObject(json));
+	//}
+	//default JSONResponse(Object json, JSONParser<M, L> parser) {
+	//	this(parseObject(json, parser));
+	//}
+	//default JSONResponse(Map<String, Object> object) {
+	//	super(format(object));
+	//}
+	//default JSONResponse(M object, JSONCreator<M, L> creator) {
+	//	super(format(object, creator));
+	//}
 
 	//状态信息，非GET请求获得的信息<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 
@@ -85,9 +82,9 @@ public JSONResponse(M object, JSONCreator<M, L> creator) {
 	/**获取状态
 	 * @return
 	 */
-	public int getCode() {
+	default int getCode() {
 		try {
-			return getIntValue(KEY_CODE);
+			return JSON.getIntValue(this, KEY_CODE);
 		} catch (Exception e) {
 			//empty
 		}
@@ -107,8 +104,8 @@ public static int getCode(Map<String, Object> reponse) {
 	/**获取状态描述
 	 * @return
 	 */
-	public String getMsg() {
-		return getString(KEY_MSG);
+	default String getMsg() {
+		return JSON.getString(this, KEY_MSG);
 	}
 	/**获取状态描述
 	 * @param response
@@ -120,9 +117,9 @@ public static String getMsg(Map<String, Object> response) {
 	/**获取id
 	 * @return
 	 */
-	public long getId() {
+	default long getId() {
 		try {
-			return getLongValue(KEY_ID);
+			return JSON.getLongValue(this, KEY_ID);
 		} catch (Exception e) {
 			//empty
 		}
@@ -131,9 +128,9 @@ public long getId() {
 	/**获取数量
 	 * @return
 	 */
-	public int getCount() {
+	default int getCount() {
 		try {
-			return getIntValue(KEY_COUNT);
+			return JSON.getIntValue(this, KEY_COUNT);
 		} catch (Exception e) {
 			//empty
 		}
@@ -142,9 +139,9 @@ public int getCount() {
 	/**获取总数
 	 * @return
 	 */
-	public int getTotal() {
+	default int getTotal() {
 		try {
-			return getIntValue(KEY_TOTAL);
+			return JSON.getIntValue(this, KEY_TOTAL);
 		} catch (Exception e) {
 			//empty
 		}
@@ -155,7 +152,7 @@ public int getTotal() {
 	/**是否成功
 	 * @return
 	 */
-	public boolean isSuccess() {
+	default boolean isSuccess() {
 		return isSuccess(getCode());
 	}
 	/**是否成功
@@ -177,17 +174,13 @@ public static boolean isSuccess(JSONResponse<?, ?> response) {
 	 * @return
 	 */
 	public static boolean isSuccess(Map<String, Object> response) {
-        try {
-            return response != null && isSuccess(JSON.getIntValue(response, KEY_CODE));
-        } catch (IllegalArgumentException e) {
-            return false;
-        }
+		return response != null && isSuccess(JSON.getIntValue(response, KEY_CODE));
     }
 
 	/**校验服务端是否存在table
 	 * @return
 	 */
-	public boolean isExist() {
+	default boolean isExist() {
 		return isExist(getCount());
 	}
 	/**校验服务端是否存在table
@@ -204,21 +197,18 @@ public static boolean isExist(int count) {
 	public static boolean isExist(JSONResponse<?, ?> response) {
 		return response != null && response.isExist();
 	}
-
-	/**获取内部的JSONResponse
-	 * @param key
-	 * @return
-	 */
-	public JSONResponse<M, L> getJSONResponse(String key) {
-		return getObject(key, JSONResponse.class, null);
+	public static boolean isExist(Map<String, Object> response) {
+		return response != null && isExist(JSON.getIntValue(response, KEY_COUNT));
 	}
+
 	/**获取内部的JSONResponse
 	 * @param key
 	 * @return
 	 */
-	public JSONResponse<M, L> getJSONResponse(String key, JSONParser<M, L> parser) {
-		return getObject(key, JSONResponse.class, parser);
+	default JSONResponse<M, L> getJSONResponse(String key) {
+		return getObject(key, JSONResponse.class);
 	}
+
 	//cannot get javaBeanDeserizer
 	//	/**获取内部的JSONResponse
 	//	 * @param response
@@ -236,32 +226,16 @@ public JSONResponse<M, L> getJSONResponse(String key, JSONParser<M, L> parser) {
 	 * @param clazz
 	 * @return
 	 */
-	public <T> T getObject(Class<T> clazz) {
-		return getObject(clazz == null ? "" : clazz.getSimpleName(), clazz, (JSONParser<M, L>) DEFAULT_JSON_PARSER);
-	}
-	/**
-	 * key = clazz.getSimpleName()
-	 * @param clazz
-	 * @return
-	 */
-	public <T> T getObject(Class<T> clazz, JSONParser<M, L> parser) {
-		return getObject(clazz == null ? "" : clazz.getSimpleName(), clazz, parser);
+	default <T> T getObject(Class<T> clazz) {
+		return getObject(clazz == null ? "" : clazz.getSimpleName(), clazz);
 	}
 	/**
 	 * @param key
 	 * @param clazz
 	 * @return
 	 */
-	public <T> T getObject(String key, Class<T> clazz) {
-		return getObject(this, key, clazz, (JSONParser<M, L>) DEFAULT_JSON_PARSER);
-	}
-	/**
-	 * @param key
-	 * @param clazz
-	 * @return
-	 */
-	public <T> T getObject(String key, Class<T> clazz, JSONParser<M, L> parser) {
-		return getObject(this, key, clazz, parser);
+	default <T> T getObject(String key, Class<T> clazz) {
+		return getObject(this, key, clazz);
 	}
 	/**
 	 * @param object
@@ -269,64 +243,47 @@ public <T> T getObject(String key, Class<T> clazz, JSONParser<M, L> parser) {
 	 * @param clazz
 	 * @return
 	 */
-	public static <T, M extends Map<String, Object>, L extends List<Object>> T getObject(
-			Map<String, Object> object, String key, Class<T> clazz, JSONParser<M, L> parser) {
-		return toObject(object == null ? null : JSON.get(object, formatObjectKey(key)), clazz, parser);
+	public static <T> T getObject(
+			Map<String, Object> object, String key, Class<T> clazz) {
+		return toObject(object == null ? null : JSON.get(object, formatObjectKey(key)), clazz);
 	}
 
 	/**
 	 * @param clazz
 	 * @return
 	 */
-	public <T> T toObject(Class<T> clazz) {
-		return toObject(clazz, null);
-	}
-	/**
-	 * @param clazz
-	 * @return
-	 */
-	public <T> T toObject(Class<T> clazz, JSONParser<M, L> parser) {
-		return toObject(this, clazz, parser);
+	default <T> T toObject(Class<T> clazz) {
+		return toObject(this, clazz);
 	}
+
 	/**
 	 * @param object
 	 * @param clazz
 	 * @return
 	 */
 	public static <T, M extends Map<String, Object>, L extends List<Object>> T toObject(
-			Map<String, Object> object, Class<T> clazz, JSONParser<M, L> parser) {
-		return parseObject(object, clazz, parser);
+			Map<String, Object> object, Class<T> clazz) {
+		return JSON.parseObject(object, clazz);
 	}
 
 
 
-
-	/**
-	 * key = KEY_ARRAY
-	 * @param clazz
-	 * @return
-	 */
-	public <T> List<T> getList(Class<T> clazz, JSONParser<M, List<Object>> parser) {
-		return getList(KEY_ARRAY, clazz, parser);
-	}
 	/**
 	 * arrayObject = this
 	 * @param key
-	 * @param clazz
 	 * @return
 	 */
-	public <T> List<T> getList(String key, Class<T> clazz, JSONParser<M, List<Object>> parser) {
-		return getList(this, key, clazz, parser);
+	default <T> List<T> getList(String key) {
+		return JSON.getList(this, key);
 	}
 
 	/**
 	 * key = KEY_ARRAY
 	 * @param object
-	 * @param clazz
 	 * @return
 	 */
-	public static <T, M extends Map<String, Object>> List<T> getList(Map<String, Object> object, Class<T> clazz, JSONParser<M, List<Object>> parser) {
-		return getList(object, KEY_ARRAY, clazz, parser);
+	public static <T> List<T> getList(Map<String, Object> object) {
+		return JSON.getList(object, KEY_ARRAY);
 	}
 	/**
 	 * @param object
@@ -334,29 +291,29 @@ public static <T, M extends Map<String, Object>> List<T> getList(Map<String, Obj
 	 * @param clazz
 	 * @return
 	 */
-	public static <T, M extends Map<String, Object>> List<T> getList(Map<String, Object> object, String key, Class<T> clazz, JSONParser<M, List<Object>> parser) {
-		return object == null ? null : JSON.parseArray(JSON.getString(object, formatArrayKey(key)), clazz, parser);
+	public static <T, M extends Map<String, Object>> List<T> getList(Map<String, Object> object, String key, Class<T> clazz) {
+		return object == null ? null : JSON.parseArray(JSON.getString(object, formatArrayKey(key)), clazz);
 	}
 
 	/**
 	 * key = KEY_ARRAY
 	 * @return
 	 */
-	public JSONArray getArray() {
+	default <L extends List<Object>> L getArray() {
 		return getArray(KEY_ARRAY);
 	}
 	/**
 	 * @param key
 	 * @return
 	 */
-	public JSONArray getArray(String key) {
+	default <L extends List<Object>> L getArray(String key) {
 		return getArray(this, key);
 	}
 	/**
 	 * @param object
 	 * @return
 	 */
-	public static JSONArray getArray(Map<String, Object> object) {
+	public static <L extends List<Object>> L getArray(Map<String, Object> object) {
 		return getArray(object, KEY_ARRAY);
 	}
 	/**
@@ -365,7 +322,7 @@ public static JSONArray getArray(Map<String, Object> object) {
 	 * @param key
 	 * @return
 	 */
-	public static JSONArray getArray(Map<String, Object> object, String key) {
+	public static <L extends List<Object>> L getArray(Map<String, Object> object, String key) {
 		return object == null ? null : JSON.get(object, formatArrayKey(key));
 	}
 
@@ -373,40 +330,21 @@ public static JSONArray getArray(Map<String, Object> object, String key) {
 	//	/**
 	//	 * @return
 	//	 */
-	//	public JSONRequest format() {
+	//	default JSONRequest format() {
 	//		return format(this);
 	//	}
 	/**格式化key名称
 	 * @param object
 	 * @return
 	 */
-	public static JSONObject format(final Map<String, Object> object) {
-		//		return format(object, JSON.DEFAULT_JSON_CREATOR);
-		JSONObject obj = new JSONObject(object);
-		return format(obj, new JSONCreator<JSONObject, JSONArray>() {
-			@Override
-			public JSONObject createJSONObject() {
-				return new JSONObject();
-			}
-
-			@Override
-			public JSONArray createJSONArray() {
-				return new JSONArray();
-			}
-		});
-	}
-	/**格式化key名称
-	 * @param object
-	 * @return
-	 */
-	public static <M extends Map<String, Object>, L extends List<Object>> M format(final M object, @NotNull JSONCreator<M, L> creator) {
+	public static <M extends Map<String, Object>, L extends List<Object>> M format(final M object) {
 		//太长查看不方便，不如debug	 Log.i(TAG, "format  object = \n" + JSON.toJSONString(object));
 		if (object == null || object.isEmpty()) {
 			Log.i(TAG, "format  object == null || object.isEmpty() >> return object;");
 			return object;
 		}
 
-		M formatedObject = creator.createJSONObject();
+		M formatedObject = JSON.createJSONObject();
 
 		Set<String> set = object.keySet();
 		if (set != null) {
@@ -415,11 +353,11 @@ public static <M extends Map<String, Object>, L extends List<Object>> M format(f
 			for (String key : set) {
 				value = object.get(key);
 
-				if (value instanceof List<?>) {//JSONArray，遍历来format内部项
-					formatedObject.put(formatArrayKey(key), format((L) value, creator));
+				if (value instanceof List<?>) {//JSONList，遍历来format内部项
+					formatedObject.put(formatArrayKey(key), format((L) value));
 				}
 				else if (value instanceof Map<?, ?>) {//JSONRequest，往下一级提取
-					formatedObject.put(formatObjectKey(key), format((M) value, creator));
+					formatedObject.put(formatObjectKey(key), format((M) value));
 				}
 				else {//其它Object，直接填充
 					formatedObject.put(formatOtherKey(key), value);
@@ -435,45 +373,30 @@ else if (value instanceof Map<?, ?>) {//JSONRequest，往下一级提取
 	 * @param array
 	 * @return
 	 */
-	public static JSONArray format(final List<Object> array) {
-		//		return format(array, JSON.DEFAULT_JSON_CREATOR);
-		JSONArray arr = new JSONArray(array);
-		return format(arr, new JSONCreator<JSONObject, JSONArray>() {
-			@Override
-			public JSONObject createJSONObject() {
-				return new JSONObject();
-			}
-
-			@Override
-			public JSONArray createJSONArray() {
-				return new JSONArray();
-			}
-		});
-	}
-	public static <M extends Map<String, Object>, L extends List<Object>> L format(final L array, @NotNull JSONCreator<M, L> creator) {
+	public static <M extends Map<String, Object>, L extends List<Object>> L format(final L array) {
 		//太长查看不方便，不如debug	 Log.i(TAG, "format  array = \n" + JSON.toJSONString(array));
 		if (array == null || array.isEmpty()) {
 			Log.i(TAG, "format  array == null || array.isEmpty() >> return array;");
 			return array;
 		}
-		L formatedArray = creator.createJSONArray();
+		L formattedArray = JSON.createJSONArray();
 
 		Object value;
 		for (int i = 0; i < array.size(); i++) {
 			value = array.get(i);
-			if (value instanceof List<?>) {//JSONArray，遍历来format内部项
-				formatedArray.add(format((L) value, creator));
+			if (value instanceof List<?>) {//JSONList，遍历来format内部项
+				formattedArray.add(format((L) value));
 			}
 			else if (value instanceof Map<?, ?>) {//JSONRequest，往下一级提取
-				formatedArray.add(format((M) value, creator));
+				formattedArray.add(format((M) value));
 			}
 			else {//其它Object，直接填充
-				formatedArray.add(value);
+				formattedArray.add(value);
 			}
 		}
 
-		//太长查看不方便，不如debug	 Log.i(TAG, "format  return formatedArray = " + JSON.toJSONString(formatedArray));
-		return formatedArray;
+		//太长查看不方便，不如debug	 Log.i(TAG, "format  return formattedArray = " + JSON.toJSONString(formattedArray));
+		return formattedArray;
 	}
 
 
@@ -492,7 +415,7 @@ public static String getTableName(String fullName) {
 	 * @return {@link #formatKey(String, boolean, boolean, boolean, boolean, boolean, Boolean)} formatColon = true, formatAt = true, formatHyphen = true, firstCase = true
 	 */
 	public static String getVariableName(String fullName) {
-		if (isArrayKey(fullName)) {
+		if (JSONMap.isArrayKey(fullName)) {
 			fullName = StringUtil.addSuffix(fullName.substring(0, fullName.length() - 2), "list");
 		}
 		return formatKey(fullName, true, true, true, true, false, true);
@@ -503,7 +426,7 @@ public static String getVariableName(String fullName) {
 	 * @return {@link #formatKey(String, boolean, boolean, boolean, boolean, boolean, Boolean)} formatColon = false, formatAt = true, formatHyphen = true, firstCase = true
 	 */
 	public static String formatArrayKey(String key) {
-		if (isArrayKey(key)) {
+		if (JSONMap.isArrayKey(key)) {
 			key = StringUtil.addSuffix(key.substring(0, key.length() - 2), "list");
 		}
 		int index = key == null ? -1 : key.indexOf(":");
diff --git a/APIJSONORM/src/main/java/apijson/Log.java b/APIJSONORM/src/main/java/apijson/Log.java
index bd091c4e3..ba1a03bd5 100755
--- a/APIJSONORM/src/main/java/apijson/Log.java
+++ b/APIJSONORM/src/main/java/apijson/Log.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -14,7 +14,7 @@ public class Log {
 
 	public static boolean DEBUG = true;
 
-	public static final String VERSION = "8.0.0";
+	public static final String VERSION = "8.0.2";
 	public static final String KEY_SYSTEM_INFO_DIVIDER = "\n---|-----APIJSON SYSTEM INFO-----|---\n";
 
 	public static final String OS_NAME;
diff --git a/APIJSONORM/src/main/java/apijson/MethodAccess.java b/APIJSONORM/src/main/java/apijson/MethodAccess.java
index 31d45843e..1804f7a7b 100755
--- a/APIJSONORM/src/main/java/apijson/MethodAccess.java
+++ b/APIJSONORM/src/main/java/apijson/MethodAccess.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/NotNull.java b/APIJSONORM/src/main/java/apijson/NotNull.java
index d10a93691..1265ccac7 100755
--- a/APIJSONORM/src/main/java/apijson/NotNull.java
+++ b/APIJSONORM/src/main/java/apijson/NotNull.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/RequestMethod.java b/APIJSONORM/src/main/java/apijson/RequestMethod.java
index 875200b7a..27e4cab64 100755
--- a/APIJSONORM/src/main/java/apijson/RequestMethod.java
+++ b/APIJSONORM/src/main/java/apijson/RequestMethod.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/SQL.java b/APIJSONORM/src/main/java/apijson/SQL.java
index 110ae3d47..868f0d2aa 100755
--- a/APIJSONORM/src/main/java/apijson/SQL.java
+++ b/APIJSONORM/src/main/java/apijson/SQL.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/StringUtil.java b/APIJSONORM/src/main/java/apijson/StringUtil.java
index 13b0ff214..179161005 100755
--- a/APIJSONORM/src/main/java/apijson/StringUtil.java
+++ b/APIJSONORM/src/main/java/apijson/StringUtil.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java
index 76d6a4520..42831775b 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -35,7 +35,7 @@ public abstract class AbstractFunctionParser<T, M extends Map<String, Object>, L
      */
     public static boolean ENABLE_SCRIPT_FUNCTION = true;
 
-	// <methodName, JSONObject>
+	// <methodName, JSONMap>
 	// <isContain, <arguments:"array,key", tag:null, methods:null>>
     public static Map<String, ScriptExecutor<?, ? extends Map<String, Object>, ? extends List<Object>>> SCRIPT_EXECUTOR_MAP;
 	public static Map<String, Map<String, Object>> FUNCTION_MAP;
@@ -234,7 +234,7 @@ public String getArgStr(String path) {
 		return JSON.toJSONString(obj);
 	}
 
-	/**根据路径取 JSONObject 值
+	/**根据路径取 JSONMap 值
 	 * @param path
 	 * @return
 	 */
@@ -242,7 +242,7 @@ public Map<String, Object> getArgObj(String path) {
 		return getArgVal(path, Map.class);
 	}
 
-	/**根据路径取 JSONArray 值
+	/**根据路径取 JSONList 值
 	 * @param path
 	 * @return
 	 */
@@ -488,7 +488,8 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> Object
      * @throws Exception
      */
 	@SuppressWarnings({"unchecked", "rawtypes"})
-	public static <T, M extends Map<String, Object>, L extends List<Object>> Object invoke(@NotNull AbstractFunctionParser<T, M, L> parser, @NotNull String methodName
+	public static <T, M extends Map<String, Object>, L extends List<Object>> Object invoke(
+			@NotNull AbstractFunctionParser<T, M, L> parser, @NotNull String methodName
             , @NotNull Class<?>[] parameterTypes, @NotNull Object[] args, String returnType
             , Map<String, Object> current, ScriptExecutor scriptExecutor) throws Exception {
         if (scriptExecutor != null) {
@@ -638,12 +639,12 @@ else if (v instanceof Number) {
 				else if (v instanceof String) {
 					types[i] = String.class;
 				}
-				else if (v instanceof Map) { // 泛型兼容？ // JSONObject
+				else if (v instanceof Map) { // 泛型兼容？ // JSONMap
 					types[i] = Map.class;
 					//性能比较差
                     //values[i] = TypeUtils.cast(v, Map.class, ParserConfig.getGlobalInstance());
 				}
-				else if (v instanceof Collection) { // 泛型兼容？ // JSONArray
+				else if (v instanceof Collection) { // 泛型兼容？ // JSONList
 					types[i] = List.class;
 					//性能比较差
 					List list = new ArrayList<>((Collection) v);
@@ -651,14 +652,15 @@ else if (v instanceof Collection) { // 泛型兼容？ // JSONArray
 				}
 				else {
 					throw new UnsupportedDataTypeException(keys[i] + ":value 中value不合法！远程函数 key():"
-                            + function + " 中的 arg 对应的值类型只能是 [Boolean, Number, String, JSONObject, JSONArray] 中的一种！");
+                            + function + " 中的 arg 对应的值类型只能是 [Boolean, Number, String, JSONMap, JSONList] 中的一种！");
 				}
 			}
 		}
 		else {
+			Class<? extends Map> cls = JSON.createJSONObject().getClass();
 			types = new Class<?>[length + 1];
 			//types[0] = Object.class; // 泛型擦除 JSON.JSON_OBJECT_CLASS;
-			types[0] = JSON.JSON_OBJECT_CLASS;
+			types[0] = cls;
 
 			values = new Object[length + 1];
 			values[0] = request;
@@ -725,7 +727,7 @@ public static String extractSchema(String sch, String table) {
 	 * @return
 	 */
 	public static String getFunction(String method, String[] keys) {
-		String f = method + "(JSONObject request";
+		String f = method + "(JSONMap request";
 
 		if (keys != null) {
 			for (int i = 0; i < keys.length; i++) {
@@ -892,7 +894,7 @@ public String toFunctionCallString(boolean useValue, String quote) {
 	 * @throws Exception
 	 */
 	public <V> V getArgVal(@NotNull M req, String key, Class<V> clazz) throws Exception {
-		// Convert to JSONObject for backward compatibility, replace with proper implementation later
+		// Convert to JSONMap for backward compatibility, replace with proper implementation later
 		return getArgVal(req, key, clazz, false);
 	}
 
@@ -905,7 +907,7 @@ public <V> V getArgVal(@NotNull M req, String key, Class<V> clazz) throws Except
 	 * @throws Exception 
 	 */
 	public <V> V getArgVal(String key, Class<V> clazz, boolean defaultValue) throws Exception {
-		Object obj = parser != null && apijson.JSONObject.isArrayKey(key) ? AbstractParser.getValue(request, key.split("\\,")) : request.get(key);
+		Object obj = parser != null && JSONMap.isArrayKey(key) ? AbstractParser.getValue(request, key.split("\\,")) : request.get(key);
 		
 		if (clazz == null) {
 			return (V) obj;
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java
index 9bca5becb..4d56499a0 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -17,9 +17,9 @@
 import java.util.Map.Entry;
 
 import static apijson.JSON.*;
-import static apijson.JSONObject.KEY_COMBINE;
-import static apijson.JSONObject.KEY_DROP;
-import static apijson.JSONObject.KEY_TRY;
+import static apijson.JSONMap.KEY_COMBINE;
+import static apijson.JSONMap.KEY_DROP;
+import static apijson.JSONMap.KEY_TRY;
 import static apijson.JSONRequest.*;
 import static apijson.RequestMethod.POST;
 import static apijson.RequestMethod.PUT;
@@ -79,7 +79,7 @@ public AbstractObjectParser(@NotNull M request, String parentPath, SQLConfig<T,
 		this.arrayTable = arrayConfig == null ? null : arrayConfig.getTable();
 		this.joinList = arrayConfig == null ? null : arrayConfig.getJoinList();
 
-		this.isTable = isTable; // apijson.JSONObject.isTableKey(table);
+		this.isTable = isTable; // apijson.JSONMap.isTableKey(table);
 		this.isArrayMainTable = isArrayMainTable; // isSubquery == false && this.isTable && this.type == SQLConfig.TYPE_ITEM_CHILD_0 && RequestMethod.isGetMethod(method, true);
 		//		this.isReuse = isReuse; // isArrayMainTable && arrayConfig != null && arrayConfig.getPosition() > 0;
 
@@ -100,7 +100,7 @@ public AbstractObjectParser(@NotNull M request, String parentPath, SQLConfig<T,
 		}
 
         if (isTable) {
-            String raw = getString(request, apijson.JSONObject.KEY_RAW);
+            String raw = getString(request, JSONMap.KEY_RAW);
             String[] rks = StringUtil.split(raw);
             rawKeyList = rks == null || rks.length <= 0 ? null : Arrays.asList(rks);
         }
@@ -240,10 +240,10 @@ public AbstractObjectParser<T, M, L> parse(String name, boolean isReuse) throws
 						}
 						// Arrays.asList() 返回值不支持 add 方法！
 						whereList = new ArrayList<String>(Arrays.asList(combine != null ? combine : new String[]{}));
-						whereList.add(apijson.JSONObject.KEY_ID);
-						whereList.add(apijson.JSONObject.KEY_ID_IN);
-						//						whereList.add(apijson.JSONObject.KEY_USER_ID);
-						//						whereList.add(apijson.JSONObject.KEY_USER_ID_IN);
+						whereList.add(JSONMap.KEY_ID);
+						whereList.add(JSONMap.KEY_ID_IN);
+						//						whereList.add(apijson.JSONMap.KEY_USER_ID);
+						//						whereList.add(apijson.JSONMap.KEY_USER_ID_IN);
 					}
 					// 条件>>>>>>>>>>>>>>>>>>>
 
@@ -256,7 +256,10 @@ public AbstractObjectParser<T, M, L> parse(String name, boolean isReuse) throws
 							break;
 						}
 
-						String key = entry == null ? null : entry.getKey();
+						// key 可能为 JSONList，需要进行手动转换（fastjson 为低版本时允许自动转换，如 1.2.21）
+						// 例如 request json为 "{[]:{"page": 2, "table1":{}}}"
+						Object field = entry == null ? null : entry.getKey();
+						String key = field instanceof Map ? toJSONString(field) : field.toString();
 						Object value = key == null ? null : entry.getValue();
 						if (value == null) {
 							continue;
@@ -268,7 +271,7 @@ public AbstractObjectParser<T, M, L> parse(String name, boolean isReuse) throws
 
 						Object obj = key.endsWith("@") ? request.get(key) : null;
 						if (obj instanceof Map<?, ?>) {
-							((Map<String, Object>) obj).put(apijson.JSONObject.KEY_METHOD, GET);
+							((Map<String, Object>) obj).put(JSONMap.KEY_METHOD, GET);
 						}
 
 						try {
@@ -299,7 +302,7 @@ else if (value instanceof Map<?, ?>) {  // JSONRequest，往下一级提取
 								}
 							}
 							else if ((_method == POST || _method == PUT) && value instanceof List<?>
-									&& apijson.JSONObject.isTableArray(key)) {  // L，批量新增或修改，往下一级提取
+									&& JSONMap.isTableArray(key)) {  // L，批量新增或修改，往下一级提取
 								onTableArrayParse(key, (L) value);
 							}
 							else if (_method == PUT && value instanceof List<?> && (whereList == null || whereList.contains(key) == false)
@@ -326,38 +329,38 @@ else if (_method == PUT && value instanceof List<?> && (whereList == null || whe
 
 					String db = parser.getGlobalDatabase();
 					if (db != null) {
-						sqlRequest.putIfAbsent(apijson.JSONObject.KEY_DATABASE, db);
+						sqlRequest.putIfAbsent(JSONMap.KEY_DATABASE, db);
 					}
 
 					String ds = parser.getGlobalDatasource();
 					if (ds != null) {
-						sqlRequest.putIfAbsent(apijson.JSONObject.KEY_DATASOURCE, ds);
+						sqlRequest.putIfAbsent(JSONMap.KEY_DATASOURCE, ds);
 					}
 
 					String ns = parser.getGlobalNamespace();
 					if (ns != null) {
-						sqlRequest.putIfAbsent(apijson.JSONObject.KEY_NAMESPACE, ns);
+						sqlRequest.putIfAbsent(JSONMap.KEY_NAMESPACE, ns);
 					}
 
 					String cl = parser.getGlobalCatalog();
 					if (cl != null) {
-						sqlRequest.putIfAbsent(apijson.JSONObject.KEY_CATALOG, cl);
+						sqlRequest.putIfAbsent(JSONMap.KEY_CATALOG, cl);
 					}
 
 					String sch = parser.getGlobalSchema();
 					if (sch != null) {
-						sqlRequest.putIfAbsent(apijson.JSONObject.KEY_SCHEMA, sch);
+						sqlRequest.putIfAbsent(JSONMap.KEY_SCHEMA, sch);
 					}
 
 					if (isSubquery == false) { // 解决 SQL 语法报错，子查询不能 EXPLAIN
 						Boolean exp = parser.getGlobalExplain();
 						if (sch != null) {
-							sqlRequest.putIfAbsent(apijson.JSONObject.KEY_EXPLAIN, exp);
+							sqlRequest.putIfAbsent(JSONMap.KEY_EXPLAIN, exp);
 						}
 
 						String cache = parser.getGlobalCache();
 						if (cache != null) {
-							sqlRequest.putIfAbsent(apijson.JSONObject.KEY_CACHE, cache);
+							sqlRequest.putIfAbsent(JSONMap.KEY_CACHE, cache);
 						}
 					}
 				}
@@ -416,7 +419,7 @@ public boolean onParse(@NotNull String key, @NotNull Object value) throws Except
 					for (Entry<String, Object> e : set) {
 						String k = e == null ? null : e.getKey();
 						Object v = k == null ? null : e.getValue();
-						if (v instanceof Map<?, ?> && apijson.JSONObject.isTableKey(k)) {
+						if (v instanceof Map<?, ?> && JSONMap.isTableKey(k)) {
 							from = k;
 							arrObj = (M) v;
 							break;
@@ -467,9 +470,9 @@ else if (value instanceof String) { // //key{}@ getRealKey, 引用赋值路径
 					}
 
 					// 非查询关键词 @key 不影响查询，直接跳过
-					if (isTable && (key.startsWith("@") == false || apijson.JSONObject.TABLE_KEY_LIST.contains(key))) {
+					if (isTable && (key.startsWith("@") == false || JSONMap.TABLE_KEY_LIST.contains(key))) {
 						Log.e(TAG, "onParse  isTable && (key.startsWith(@) == false"
-								+ " || apijson.JSONObject.TABLE_KEY_LIST.contains(key)) >>  return null;");
+								+ " || apijson.JSONMap.TABLE_KEY_LIST.contains(key)) >>  return null;");
 						// FIXME getCache() != null 时 return true，解决 RIGHT/OUTER/FOREIGN JOIN 主表无数据导致副表数据也不返回
 						return false; // 获取不到就不用再做无效的 query 了。不考虑 Table:{Table:{}} 嵌套
 					}
@@ -490,9 +493,9 @@ else if (value instanceof String) { // //key{}@ getRealKey, 引用赋值路径
 //					Log.d(TAG, "onParse  targetPath.equals(target)  >>");
 //
 //					//非查询关键词 @key 不影响查询，直接跳过
-//					if (isTable && (key.startsWith("@") == false || apijson.JSONObject.TABLE_KEY_LIST.contains(key))) {
+//					if (isTable && (key.startsWith("@") == false || apijson.JSONMap.TABLE_KEY_LIST.contains(key))) {
 //						Log.e(TAG, "onParse  isTable && (key.startsWith(@) == false"
-//								+ " || apijson.JSONObject.TABLE_KEY_LIST.contains(key)) >>  return null;");
+//								+ " || apijson.JSONMap.TABLE_KEY_LIST.contains(key)) >>  return null;");
 //						return false;//获取不到就不用再做无效的query了。不考虑 Table:{Table:{}}嵌套
 //					} else {
 //						Log.d(TAG, "onParse  isTable(table) == false >> return true;");
@@ -547,7 +550,7 @@ else if (isPlus) {
 				functionMap.put(type, map);
 			}
 		}
-		else if (isTable && key.startsWith("@") && apijson.JSONObject.TABLE_KEY_LIST.contains(key) == false) {
+		else if (isTable && key.startsWith("@") && JSONMap.TABLE_KEY_LIST.contains(key) == false) {
             customMap.put(key, value);
 		}
 		else {
@@ -575,7 +578,7 @@ public Object onChildParse(int index, String key, M value, Object cache) throws
 		Object child;
 		boolean isEmpty;
 
-		if (apijson.JSONObject.isArrayKey(key)) { // APIJSON Array
+		if (JSONMap.isArrayKey(key)) { // APIJSON Array
 			if (isMain) {
 				throw new IllegalArgumentException(parentPath + "/" + key + ":{} 不合法！"
 						+ "数组 []:{} 中第一个 key:{} 必须是主表 TableKey:{} ！不能为 arrayKey[]:{} ！");
@@ -612,7 +615,7 @@ public Object onChildParse(int index, String key, M value, Object cache) throws
 			}
 		}
 		else { //APIJSON Object
-			boolean isTableKey = apijson.JSONObject.isTableKey(Pair.parseEntry(key, true).getKey());
+			boolean isTableKey = JSONMap.isTableKey(Pair.parseEntry(key, true).getKey());
 			if (type == TYPE_ITEM && isTableKey == false) {
 				throw new IllegalArgumentException(parentPath + "/" + key + ":{} 不合法！"
 						+ "数组 []:{} 中每个 key:{} 都必须是表 TableKey:{} 或 数组 arrayKey[]:{} ！");
@@ -672,8 +675,8 @@ public void onPUTArrayParse(@NotNull String key, @NotNull L array) throws Except
 
 		//GET <<<<<<<<<<<<<<<<<<<<<<<<<
 		M rq = JSON.createJSONObject();
-		rq.put(apijson.JSONObject.KEY_ID, request.get(apijson.JSONObject.KEY_ID));
-		rq.put(apijson.JSONObject.KEY_COLUMN, realKey);
+		rq.put(JSONMap.KEY_ID, request.get(JSONMap.KEY_ID));
+		rq.put(JSONMap.KEY_COLUMN, realKey);
 		M rp = parseResponse(RequestMethod.GET, table, null, rq, null, false);
 		//GET >>>>>>>>>>>>>>>>>>>>>>>>>
 
@@ -682,7 +685,7 @@ public void onPUTArrayParse(@NotNull String key, @NotNull L array) throws Except
 		Object target = rp == null ? null : rp.get(realKey);
 		if (target instanceof String) {
 			try {
-				target = parseJSON((String) target);
+				target = JSON.parse(target);
 			} catch (Throwable e) {
 				if (Log.DEBUG) {
 					Log.e(TAG, "try {\n" +
@@ -765,7 +768,7 @@ public void onPUTArrayParse(@NotNull String key, @NotNull L array) throws Except
 
 	@Override
 	public void onTableArrayParse(String key, L valueArray) throws Exception {
-		String childKey = key.substring(0, key.length() - apijson.JSONObject.KEY_ARRAY.length());
+		String childKey = key.substring(0, key.length() - JSONMap.KEY_ARRAY.length());
 
 		int allCount = 0;
 		L ids = JSON.createJSONArray();
@@ -804,8 +807,7 @@ public void onTableArrayParse(String key, L valueArray) throws Exception {
 			}
 
             Object id = item.get(idKey);
-			M req = JSON.createJSONObject();
-			req.put(childKey, item);
+			M req = JSON.createJSONObject(childKey, item);
 
             M result = null;
             try {
@@ -890,16 +892,17 @@ public void onTableArrayParse(String key, L valueArray) throws Exception {
 	public M parseResponse(RequestMethod method, String table, String alias
             , M request, List<Join<T, M, L>> joinList, boolean isProcedure) throws Exception {
 		SQLConfig<T, M, L> config = newSQLConfig(method, table, alias, request, joinList, isProcedure)
-				.setParser(parser)
+				.setParser(getParser())
 				.setObjectParser(this);
 		return parseResponse(config, isProcedure);
 	}
 	@Override
 	public M parseResponse(SQLConfig<T, M, L> config, boolean isProcedure) throws Exception {
+		parser = getParser();
 		if (parser.getSQLExecutor() == null) {
 			parser.createSQLExecutor();
 		}
-		if (parser != null && config.gainParser() == null) {
+		if (config.gainParser() == null) {
 			config.setParser(parser);
 		}
 		return parser.getSQLExecutor().execute(config, isProcedure);
@@ -908,7 +911,7 @@ public M parseResponse(SQLConfig<T, M, L> config, boolean isProcedure) throws Ex
 
 	@Override
 	public SQLConfig<T, M, L> newSQLConfig(boolean isProcedure) throws Exception {
-		String raw = Log.DEBUG == false || sqlRequest == null ? null : getString(sqlRequest, apijson.JSONObject.KEY_RAW);
+		String raw = Log.DEBUG == false || sqlRequest == null ? null : getString(sqlRequest, JSONMap.KEY_RAW);
 		String[] keys = raw == null ? null : StringUtil.split(raw);
 		if (keys != null && keys.length > 0) {
 			boolean allow = AbstractSQLConfig.ALLOW_MISSING_KEY_4_COMBINE;
@@ -926,7 +929,7 @@ public SQLConfig<T, M, L> newSQLConfig(boolean isProcedure) throws Exception {
 				}
 
 				if (parser instanceof AbstractParser) {
-					((AbstractParser) parser).putWarnIfNeed(apijson.JSONObject.KEY_RAW, msg);
+					((AbstractParser) parser).putWarnIfNeed(JSONMap.KEY_RAW, msg);
 				}
 				break;
 			}
@@ -1168,7 +1171,9 @@ else if (isArrayMainTable && position > 0) {  // 数组主表使用专门的缓
                 // APP JOIN 副表时副表返回了这个字段   rawList = (List<JSONRequest>) result.remove(AbstractSQLExecutor.KEY_RAW_LIST);
                 String arrayPath = parentPath.substring(0, parentPath.lastIndexOf("[]") + 2);
 
-                if (isSimpleArray == false) {
+                if (isSimpleArray) {
+					parser.putQueryResult(arrayPath, rawList); // 从数组外部引用该数组内值需要
+				} else {
                     long startTime = System.currentTimeMillis();
 
                     for (int i = 1; i < rawList.size(); i++) {  // 从 1 开始，0 已经处理过
@@ -1193,7 +1198,7 @@ else if (isArrayMainTable && position > 0) {  // 数组主表使用专门的缓
             if (isSubquery == false && result != null) {
                 parser.putQueryResult(path, result);  // 解决获取关联数据时requestObject里不存在需要的关联数据
 
-                if (isSimpleArray && rawList != null) {
+                if (isSimpleArray) { // FIXME 改为从缓存获取，而不是 result 查
                     result.put(AbstractSQLExecutor.KEY_RAW_LIST, rawList);
                 }
             }
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
index f2401eeae..cd0b2c7b8 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -28,8 +28,8 @@
 import apijson.orm.exception.UnsupportedDataTypeException;
 
 import static apijson.JSON.*;
-import static apijson.JSONObject.KEY_COMBINE;
-import static apijson.JSONObject.KEY_EXPLAIN;
+import static apijson.JSONMap.*;
+import static apijson.JSONRequest.*;
 import static apijson.RequestMethod.CRUD;
 import static apijson.RequestMethod.GET;
 
@@ -37,9 +37,9 @@
  * @author Lemon
  */
 public abstract class AbstractParser<T, M extends Map<String, Object>, L extends List<Object>>
-		implements Parser<T, M, L>, ParserCreator<T, M, L>, VerifierCreator<T, M, L>, SQLCreator<T, M, L> {
+		implements Parser<T, M, L> {
 	protected static final String TAG = "AbstractParser";
-	
+
 	/**
 	 * JSON 对象、数组对应的数据源、版本、角色、method等
 	 */
@@ -62,6 +62,12 @@ public abstract class AbstractParser<T, M extends Map<String, Object>, L extends
 	 */
 	public static boolean IS_PRINT_REQUEST_ENDTIME_LOG = false;
 
+	/**
+	 * 可以通过切换该变量来控制返回 trace:stack 字段，如果是 gson 则不设置为 false，避免序列化报错。
+	 * 与 {@link Log#DEBUG} 任何一个为 true 返回 trace:stack 字段。
+	 */
+	public static boolean IS_RETURN_STACK_TRACE = true;
+
 
 	/**
 	 * 分页页码是否从 1 开始，默认为从 0 开始
@@ -411,7 +417,6 @@ public AbstractParser<T, M, L> setNeedVerifyContent(boolean needVerifyContent) {
 		return this;
 	}
 
-
 	protected SQLExecutor<T, M, L> sqlExecutor;
 	protected Verifier<T, M, L> verifier;
 	protected Map<String, Object> queryResultMap;//path-result
@@ -420,8 +425,8 @@ public AbstractParser<T, M, L> setNeedVerifyContent(boolean needVerifyContent) {
 	public SQLExecutor<T, M, L> getSQLExecutor() {
 		if (sqlExecutor == null) {
 			sqlExecutor = createSQLExecutor();
-			sqlExecutor.setParser(this);
 		}
+		sqlExecutor.setParser(this);
 		return sqlExecutor;
 	}
 	@Override
@@ -429,9 +434,25 @@ public Verifier<T, M, L> getVerifier() {
 		if (verifier == null) {
 			verifier = createVerifier().setVisitor(getVisitor());
 		}
+		verifier.setParser(this);
 		return verifier;
 	}
 
+	/**解析请求JSONObject
+	 * @param request => URLDecoder.decode(request, UTF_8);
+	 * @return
+	 * @throws Exception
+	 */
+	public static <M extends Map<String, Object>> M parseRequest(String request) throws Exception {
+		try {
+			M req = JSON.parseObject(request);
+			Objects.requireNonNull(req);
+			return req;
+		} catch (Throwable e) {
+			throw new UnsupportedEncodingException("JSON格式不合法！" + e.getMessage() + "! " + request);
+		}
+	}
+
 	/**解析请求json并获取对应结果
 	 * @param request
 	 * @return
@@ -461,7 +482,7 @@ public M parseResponse(String request) {
 				+ requestMethod + "/parseResponse  request = \n" + request + "\n\n");
 
 		try {
-			requestObject = (M) JSON.parseObject(request);
+			requestObject = JSON.parseObject(request);
 			if (requestObject == null) {
 				throw new UnsupportedEncodingException("JSON格式不合法！");
 			}
@@ -488,12 +509,19 @@ public M parseResponse(M request) {
 
 		requestObject = request;
 		try {
-			setVersion(getIntValue(requestObject, apijson.JSONRequest.KEY_VERSION));
-			requestObject.remove(apijson.JSONRequest.KEY_VERSION);
+			setGlobalFormat(getBoolean(requestObject, KEY_FORMAT));
+			requestObject.remove(KEY_FORMAT);
+		} catch (Exception e) {
+			return extendErrorResult(requestObject, e, requestMethod, getRequestURL(), isRoot);
+		}
+
+		try {
+			setVersion(getIntValue(requestObject, KEY_VERSION));
+			requestObject.remove(KEY_VERSION);
 
 			if (getMethod() != RequestMethod.CRUD) {
-				setTag(getString(requestObject, apijson.JSONRequest.KEY_TAG));
-				requestObject.remove(apijson.JSONRequest.KEY_TAG);
+				setTag(getString(requestObject, KEY_TAG));
+				requestObject.remove(KEY_TAG);
 			}
 		} catch (Exception e) {
 			return extendErrorResult(requestObject, e, requestMethod, getRequestURL(), isRoot);
@@ -517,40 +545,37 @@ public M parseResponse(M request) {
 		//必须在parseCorrectRequest后面，因为parseCorrectRequest可能会添加 @role
 		if (isNeedVerifyRole() && globalRole == null) {
 			try {
-				setGlobalRole(getString(requestObject, apijson.JSONObject.KEY_ROLE));
-				requestObject.remove(apijson.JSONObject.KEY_ROLE);
+				setGlobalRole(getString(requestObject, KEY_ROLE));
+				requestObject.remove(KEY_ROLE);
 			} catch (Exception e) {
 				return extendErrorResult(requestObject, e, requestMethod, getRequestURL(), isRoot);
 			}
 		}
 
 		try {
-			setGlobalDatabase(getString(requestObject, apijson.JSONObject.KEY_DATABASE));
-			setGlobalDatasource(getString(requestObject, apijson.JSONObject.KEY_DATASOURCE));
-			setGlobalNamespace(getString(requestObject, apijson.JSONObject.KEY_NAMESPACE));
-			setGlobalCatalog(getString(requestObject, apijson.JSONObject.KEY_CATALOG));
-			setGlobalSchema(getString(requestObject, apijson.JSONObject.KEY_SCHEMA));
-
-			setGlobalExplain(getBoolean(requestObject, apijson.JSONObject.KEY_EXPLAIN));
-			setGlobalCache(getString(requestObject, apijson.JSONObject.KEY_CACHE));
-			setGlobalFormat(getBoolean(requestObject, apijson.JSONRequest.KEY_FORMAT));
-
-			requestObject.remove(apijson.JSONObject.KEY_DATABASE);
-			requestObject.remove(apijson.JSONObject.KEY_DATASOURCE);
-			requestObject.remove(apijson.JSONObject.KEY_NAMESPACE);
-			requestObject.remove(apijson.JSONObject.KEY_CATALOG);
-			requestObject.remove(apijson.JSONObject.KEY_SCHEMA);
-
-			requestObject.remove(apijson.JSONObject.KEY_EXPLAIN);
-			requestObject.remove(apijson.JSONObject.KEY_CACHE);
-			requestObject.remove(apijson.JSONRequest.KEY_FORMAT);
+			setGlobalDatabase(getString(requestObject, KEY_DATABASE));
+			setGlobalDatasource(getString(requestObject, KEY_DATASOURCE));
+			setGlobalNamespace(getString(requestObject, KEY_NAMESPACE));
+			setGlobalCatalog(getString(requestObject, KEY_CATALOG));
+			setGlobalSchema(getString(requestObject, KEY_SCHEMA));
+
+			setGlobalExplain(getBoolean(requestObject, KEY_EXPLAIN));
+			setGlobalCache(getString(requestObject, KEY_CACHE));
+
+			requestObject.remove(KEY_DATABASE);
+			requestObject.remove(KEY_DATASOURCE);
+			requestObject.remove(KEY_NAMESPACE);
+			requestObject.remove(KEY_CATALOG);
+			requestObject.remove(KEY_SCHEMA);
+
+			requestObject.remove(KEY_EXPLAIN);
+			requestObject.remove(KEY_CACHE);
 		} catch (Exception e) {
 			return extendErrorResult(requestObject, e, requestMethod, getRequestURL(), isRoot);
 		}
 
 		final String requestString = JSON.toJSONString(request);//request传进去解析后已经变了
 
-
 		queryResultMap = new HashMap<String, Object>();
 
 		Exception error = null;
@@ -575,24 +600,22 @@ public M parseResponse(M request) {
 
 		requestObject = error == null ? extendSuccessResult(requestObject, warn, isRoot) : extendErrorResult(requestObject, error, requestMethod, getRequestURL(), isRoot);
 
-		M res = (globalFormat != null && globalFormat) && JSONResponse.isSuccess(requestObject) ? JSONResponse.format(requestObject, new JSONCreator<M, List<Object>>() {
-			@Override
-			public M createJSONObject() {
-				return JSON.createJSONObject();
-			}
+		// FIXME 暂时先直接移除，后续排查是在哪里 put 进来
+		requestObject.remove(KEY_DATABASE);
+		requestObject.remove(KEY_DATASOURCE);
+		requestObject.remove(KEY_NAMESPACE);
+		requestObject.remove(KEY_CATALOG);
+		requestObject.remove(KEY_SCHEMA);
 
-			@Override
-			public List<Object> createJSONArray() {
-				return JSON.createJSONArray();
-			}
-		}) : requestObject;
+		M res = (globalFormat != null && globalFormat) && JSONResponse.isSuccess(requestObject) ? JSONResponse.format(requestObject) : requestObject;
 
 		long endTime = System.currentTimeMillis();
 		long duration = endTime - startTime;
 
 		res.putIfAbsent("time", endTime);
 		if (Log.DEBUG) {
-			res.put("sql:generate|cache|execute|maxExecute", getSQLExecutor().getGeneratedSQLCount() + "|" + getSQLExecutor().getCachedSQLCount() + "|" + getSQLExecutor().getExecutedSQLCount() + "|" + getMaxSQLCount());
+			sqlExecutor = getSQLExecutor();
+			res.put("sql:generate|cache|execute|maxExecute", sqlExecutor.getGeneratedSQLCount() + "|" + sqlExecutor.getCachedSQLCount() + "|" + sqlExecutor.getExecutedSQLCount() + "|" + getMaxSQLCount());
 			res.put("depth:count|max", queryDepth + "|" + getMaxQueryDepth());
 
 			executedSQLDuration += sqlExecutor.getExecutedSQLDuration() + sqlExecutor.getSqlResultDuration();
@@ -605,7 +628,19 @@ public List<Object> createJSONArray() {
                 //        }
                 Throwable t = error instanceof CommonException && error.getCause() != null ? error.getCause() : error;
 				res.put("trace:throw", t.getClass().getName());
-				res.put("trace:stack", t.getStackTrace());
+
+				if (IS_RETURN_STACK_TRACE) {
+					L list = JSON.createJSONArray();
+
+					StackTraceElement[] traces = t.getStackTrace();
+					if (traces != null) { // && traces.length > 0) {
+						for (StackTraceElement trace : traces) {
+							list.add(trace == null ? null : trace.toString());
+						}
+					}
+
+					res.put("trace:stack", list);
+				}
 			}
 		}
 
@@ -623,6 +658,7 @@ public List<Object> createJSONArray() {
 			Log.fd(TAG, requestMethod + "/parseResponse  endTime = " + endTime + ";  duration = " + duration);
 			Log.sl("", '>', "\n\n\n");
 		}
+
 		return res;
 	}
 
@@ -670,31 +706,31 @@ public M parseCorrectRequest(RequestMethod method, String tag, int version, Stri
 
 		return batchVerify(method, tag, version, name, request, maxUpdateCount, creator);
 	}
-	
+
 	/**自动根据 tag 是否为 TableKey 及是否被包含在 object 内来决定是否包装一层，改为 { tag: object, "tag": tag }
 	 * @param object
 	 * @param tag
 	 * @return
 	 */
-	public M wrapRequest(RequestMethod method, String tag, M object, boolean isStructure, JSONCreator<M, L> creator) {
+	public M wrapRequest(RequestMethod method, String tag, M object, boolean isStructure) {
 		boolean putTag = ! isStructure;
 
 		if (object == null || object.containsKey(tag)) { //tag 是 Table 名或 Table[]
 			if (putTag) {
 				if (object == null) {
-					object = creator.createJSONObject();
+					object = JSON.createJSONObject();
 				}
-				object.put(apijson.JSONRequest.KEY_TAG, tag);
+				object.put(KEY_TAG, tag);
 			}
 			return object;
 		}
 
 		boolean isDiffArrayKey = tag.endsWith(":[]");
-		boolean isArrayKey = isDiffArrayKey || apijson.JSONObject.isArrayKey(tag);
+		boolean isArrayKey = isDiffArrayKey || isArrayKey(tag);
 		String key = isArrayKey ? tag.substring(0, tag.length() - (isDiffArrayKey ? 3 : 2)) : tag;
 
 		M target = object;
-		if (apijson.JSONObject.isTableKey(key)) {
+		if (isTableKey(key)) {
 			if (isDiffArrayKey) { //自动为 tag = Comment:[] 的 { ... } 新增键值对为 { "Comment[]":[], "TYPE": { "Comment[]": "OBJECT[]" } ... }
 				if (isStructure && (method == RequestMethod.POST || method == RequestMethod.PUT)) {
 					String arrKey = key + "[]";
@@ -721,18 +757,18 @@ public M wrapRequest(RequestMethod method, String tag, M object, boolean isStruc
 			}
 			else { //自动为 tag = Comment 的 { ... } 包一层为 { "Comment": { ... } }
 				if (isArrayKey == false || RequestMethod.isGetMethod(method, true)) {
-					target = creator.createJSONObject();
+					target = JSON.createJSONObject();
 					target.put(tag, object);
 				}
 				else if (target.containsKey(key) == false) {
-					target = creator.createJSONObject();
+					target = JSON.createJSONObject();
 					target.put(key, object);
 				}
 			}
 		}
 
 		if (putTag) {
-			target.put(apijson.JSONRequest.KEY_TAG, tag);
+			target.put(KEY_TAG, tag);
 		}
 
 		return target;
@@ -991,7 +1027,7 @@ public M newErrorResult(Exception e, boolean isRoot) {
 		  	//      }
 
 		  	String msg = CommonException.getMsg(e);
-			Integer code = CommonException.getCode(e);
+			int code = CommonException.getCode(e);
 
 			return newResult(code, msg, null, isRoot);
 		}
@@ -1069,18 +1105,19 @@ public M getStructure(@NotNull String table, String method, String tag, int vers
 
 			// 获取指定的JSON结构 <<<<<<<<<<<<<<
 			SQLConfig<T, M, L> config = createSQLConfig().setMethod(GET).setTable(table);
+			config.setParser(this);
 			config.setPrepared(false);
 			config.setColumn(Arrays.asList("structure"));
 
 			Map<String, Object> where = new HashMap<String, Object>();
 			where.put("method", method);
-			where.put(apijson.JSONRequest.KEY_TAG, tag);
+			where.put(KEY_TAG, tag);
 
 			if (version > 0) {
-				where.put(apijson.JSONRequest.KEY_VERSION + ">=", version);
+				where.put(KEY_VERSION + ">=", version);
 			}
 			config.setWhere(where);
-			config.setOrder(apijson.JSONRequest.KEY_VERSION + (version > 0 ? "+" : "-"));
+			config.setOrder(KEY_VERSION + (version > 0 ? "+" : "-"));
 			config.setCount(1);
 
 			// too many connections error: 不try-catch，可以让客户端看到是服务器内部异常
@@ -1140,7 +1177,7 @@ public M onObjectParse(final M request, String parentPath, String name
 		String table = entry.getKey(); //Comment
 		// String alias = entry.getValue(); //to
 
-		boolean isTable = apijson.JSONObject.isTableKey(table);
+		boolean isTable = isTableKey(table);
 		boolean isArrayMainTable = isSubquery == false && isTable && type == SQLConfig.TYPE_ITEM_CHILD_0 && arrayConfig != null && RequestMethod.isGetMethod(arrayConfig.getMethod(), true);
 		boolean isReuse = isArrayMainTable && position > 0;
 
@@ -1289,7 +1326,7 @@ public L onArrayParse(M request, String parentPath, String name, boolean isSubqu
 		}
 
 		//不能允许GETS，否则会被通过"[]":{"@role":"ADMIN"},"Table":{},"tag":"Table"绕过权限并能批量查询
-		RequestMethod _method = request.get(apijson.JSONObject.KEY_METHOD) == null ? requestMethod : RequestMethod.valueOf(getString(request, apijson.JSONObject.KEY_METHOD));
+		RequestMethod _method = request.get(KEY_METHOD) == null ? requestMethod : RequestMethod.valueOf(getString(request, KEY_METHOD));
 		if (isSubquery == false && RequestMethod.isGetMethod(_method, true) == false) {
 			throw new UnsupportedOperationException("key[]:{} 只支持 GET, GETS 方法！其它方法不允许传 " + name + ":{} 等这种 key[]:{} 格式！");
 		}
@@ -1373,7 +1410,7 @@ public L onArrayParse(M request, String parentPath, String name, boolean isSubqu
 			if (childKeys == null || childKeys.length <= 0 || request.containsKey(childKeys[0]) == false) {
 				childKeys = null;
 			}
-			else if (childKeys.length == 1 && apijson.JSONObject.isTableKey(childKeys[0])) {  // 可能无需提取，直接返回 rawList 即可
+			else if (childKeys.length == 1 && isTableKey(childKeys[0])) {  // 可能无需提取，直接返回 rawList 即可
 				arrTableKey = childKeys[0];
 			}
 
@@ -1479,26 +1516,26 @@ else if (childKeys.length == 1 && apijson.JSONObject.isTableKey(childKeys[0])) {
 	private static final List<String> JOIN_COPY_KEY_LIST;
 	static {  // TODO 不全
 		JOIN_COPY_KEY_LIST = new ArrayList<String>();
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_ROLE);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_DATABASE);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_NAMESPACE);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_CATALOG);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_SCHEMA);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_DATASOURCE);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_COLUMN);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_NULL);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_CAST);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_COMBINE);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_GROUP);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_HAVING);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_HAVING_AND);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_SAMPLE);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_LATEST);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_PARTITION);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_FILL);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_ORDER);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_KEY);
-		JOIN_COPY_KEY_LIST.add(apijson.JSONObject.KEY_RAW);
+		JOIN_COPY_KEY_LIST.add(KEY_ROLE);
+		JOIN_COPY_KEY_LIST.add(KEY_DATABASE);
+		JOIN_COPY_KEY_LIST.add(KEY_NAMESPACE);
+		JOIN_COPY_KEY_LIST.add(KEY_CATALOG);
+		JOIN_COPY_KEY_LIST.add(KEY_SCHEMA);
+		JOIN_COPY_KEY_LIST.add(KEY_DATASOURCE);
+		JOIN_COPY_KEY_LIST.add(KEY_COLUMN);
+		JOIN_COPY_KEY_LIST.add(KEY_NULL);
+		JOIN_COPY_KEY_LIST.add(KEY_CAST);
+		JOIN_COPY_KEY_LIST.add(KEY_COMBINE);
+		JOIN_COPY_KEY_LIST.add(KEY_GROUP);
+		JOIN_COPY_KEY_LIST.add(KEY_HAVING);
+		JOIN_COPY_KEY_LIST.add(KEY_HAVING_AND);
+		JOIN_COPY_KEY_LIST.add(KEY_SAMPLE);
+		JOIN_COPY_KEY_LIST.add(KEY_LATEST);
+		JOIN_COPY_KEY_LIST.add(KEY_PARTITION);
+		JOIN_COPY_KEY_LIST.add(KEY_FILL);
+		JOIN_COPY_KEY_LIST.add(KEY_ORDER);
+		JOIN_COPY_KEY_LIST.add(KEY_KEY);
+		JOIN_COPY_KEY_LIST.add(KEY_RAW);
 	}
 
 	/**JOIN 多表同时筛选
@@ -1526,7 +1563,39 @@ else if (join != null){
 			throw new UnsupportedDataTypeException(TAG + ".onJoinParse  join 只能是 String 或 Map<String, Object> 类型！");
 		}
 
-		Set<Entry<String, Object>> set = joinMap == null ? null : joinMap.entrySet();
+		List<Entry<String, Object>> slashKeys = new ArrayList<>();
+		List<Entry<String, Object>> nonSlashKeys = new ArrayList<>();
+		Set<Entry<String, Object>> 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<String, Object> e : entries) {
+			String path = e.getKey();
+			if (path != null && path.indexOf("/") > 0) {
+				slashKeys.add(e);  // 以 / 开头的 key，例如 </Table/key@
+			} else {
+				nonSlashKeys.add(e);  // 普通 key，例如 Table: {}
+			}
+		}
+
+		Map<String, Object> whereJoinMap = new LinkedHashMap<>();
+
+		for (Entry<String, Object> 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<Entry<String, Object>> set = joinMap == null ? null : new LinkedHashSet<>(slashKeys);
+
 		if (set == null || set.isEmpty()) {
 			Log.e(TAG, "onJoinParse  set == null || set.isEmpty() >> return null;");
 			return null;
@@ -1559,7 +1628,7 @@ else if (join != null){
 			String tableKey = index < 0 ? path : path.substring(0, index); // User:owner
 			int index2 = tableKey.lastIndexOf("/");
 			String arrKey = index2 < 0 ? null : tableKey.substring(0, index2);
-			if (arrKey != null && apijson.JSONObject.isArrayKey(arrKey) == false) {
+			if (arrKey != null && isArrayKey(arrKey) == false) {
 				throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + " 不是合法的数组 key[] ！" +
 						"@ APP JOIN 最多允许跨 1 层，只能是子数组，且数组对象中不能有 join: value 键值对！");
 			}
@@ -1662,7 +1731,7 @@ else if (join != null){
 
 						apijson.orm.Entry<String, String> te = tk == null || p.substring(ind2 + 1).indexOf("/") >= 0 ? null : Pair.parseEntry(tk, true);
 
-						if (te != null && apijson.JSONObject.isTableKey(te.getKey()) && request.get(tk) instanceof Map<?, ?>) {
+						if (te != null && isTableKey(te.getKey()) && request.get(tk) instanceof Map<?, ?>) {
 							if (isAppJoin) {
 								if (refObj.size() >= 1) {
 									throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":" + e.getKey() + " 中 " + k + " 不合法！"
@@ -1722,9 +1791,15 @@ else if (join != null){
 			j.setAlias(alias);
 
 			M outerObj = (M) JSON.createJSONObject((Map<String, Object>) 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<String, Object>) rawOuter);
+                j.setOuter(outerObj1);
+            }
+
 			if (arrKey != null) {
 				Integer count = getInteger(parentPathObj, apijson.JSONRequest.KEY_COUNT);
 				j.setCount(count == null ? getDefaultQueryCount() : count);
@@ -1827,24 +1902,32 @@ else if (join != null){
 	 * @param pathKeys
 	 * @return
 	 */
-	public static <V extends Object> V getValue(Map<String, Object> parent, String[] pathKeys) {
-		if (parent == null || pathKeys == null || pathKeys.length <= 0) {
+	public static <V extends Object> V getValue(Object parent, String[] pathKeys) {
+		int len = parent == null || pathKeys == null ? 0 : pathKeys.length;
+		if (len <= 0) {
 			Log.w(TAG, "getChild  parent == null || pathKeys == null || pathKeys.length <= 0 >> return parent;");
 			return (V) parent;
 		}
 
-		//逐层到达child的直接容器JSONObject parent
-		int last = pathKeys.length - 1;
-		for (int i = 0; i < last; i++) {//一步一步到达指定位置
-			if (parent == null) {//不存在或路径错误(中间的key对应value不是JSONObject)
+		// 逐层到达child的直接容器JSONObject parent
+		Object v = parent;
+		for (int i = 0; i < len; i++) { // 一步一步到达指定位置
+			if (v == null) { // 不存在或路径错误(中间的key对应value不是JSONObject)
 				break;
 			}
 
 			String k = getDecodedKey(pathKeys[i]);
-			parent = JSON.get(parent, k);
+			try {
+				v = getFromObjOrArr(v, k);
+			} catch (Throwable e) {
+				if (IS_PRINT_BIG_LOG) {
+					e.printStackTrace();
+				}
+				v = null;
+			}
 		}
 
-		return parent == null ? null : (V) parent.get(getDecodedKey(pathKeys[last]));
+		return (V) v;
 	}
 
 
@@ -1950,13 +2033,13 @@ public Object getValueByPath(String valuePath) {
 		}
 
 		//取出key被valuePath包含的result，再从里面获取key对应的value
-		Map<String, Object> parent = null;
+		Object parent = null;
 		String[] keys = null;
 		for (Entry<String, Object> entry : queryResultMap.entrySet()){
 			String path = entry.getKey();
 			if (valuePath.startsWith(path + "/")) {
 				try {
-					parent = (M) entry.getValue();
+					parent = entry.getValue();
 				} catch (Exception e) {
 					Log.e(TAG, "getValueByPath  try { parent = (Map<String>) queryResultMap.get(path); } catch { "
 							+ "\n parent not instanceof Map<String>!");
@@ -1969,39 +2052,13 @@ public Object getValueByPath(String valuePath) {
 			}
 		}
 
-		//逐层到达targetKey的直接容器JSONObject parent
-		int last = keys == null ? -1 : keys.length - 1;
-		if (last >= 1) {
-			for (int i = 0; i < last; i++) {//一步一步到达指定位置parentPath
-				if (parent == null) {//不存在或路径错误(中间的key对应value不是JSONObject)
-					break;
-				}
-
-				String k = getDecodedKey(keys[i]);
-				Object p = parent.get(k);
-				parent = p instanceof Map<?, ?> ? (Map<String, Object>) p : null;
-			}
-		}
-
-		if (parent != null) {
-			Log.i(TAG, "getValueByPath >> get from queryResultMap >> return  parent.get(keys[keys.length - 1]);");
-			target = last < 0 ? parent : parent.get(getDecodedKey(keys[last])); //值为null应该报错NotExistExeption，一般都是id关联，不可为null，否则可能绕过安全机制
-			if (target != null) {
-				Log.i(TAG, "getValueByPath >> getValue >> return target = " + target);
-				return target;
-			}
-		}
-
-
-		//从requestObject中取值
-		target = getValue(requestObject, StringUtil.splitPath(valuePath));
-		if (target != null) {
-			Log.i(TAG, "getValueByPath >> getValue >> return target = " + target);
-			return target;
+		target = getValue(parent, keys); // 逐层到达targetKey的直接容器JSONObject parent
+		if (target == null) { //从requestObject中取值
+			target = getValue(requestObject, StringUtil.splitPath(valuePath));
 		}
 
-		Log.i(TAG, "getValueByPath  return null;");
-		return null;
+		Log.i(TAG, "getValueByPath >> getValue >> return target = " + target);
+		return target;
 	}
 
 	/**解码 引用赋值 路径中的 key，支持把 URL encode 后的值，转为 decode 后的原始值，例如 %2Fuser%2Flist -> /user/list ; %7B%7D -> []
@@ -2089,8 +2146,7 @@ public M executeSQL(SQLConfig<T, M, L> config, boolean isSubquery) throws Except
 				}
 			}
 			else {
-				sqlExecutor = getSQLExecutor();
-				result = sqlExecutor.execute(config, false);
+				result = getSQLExecutor().execute(config, false);
 				// FIXME 改为直接在 sqlExecutor 内加好，最后 Parser<T, M, L> 取结果，可以解决并发执行导致内部计算出错
 //				executedSQLDuration += sqlExecutor.getExecutedSQLDuration() + sqlExecutor.getSqlResultDuration();
 			}
@@ -2213,7 +2269,7 @@ protected void onClose() {
 	}
 
 	private void setOpMethod(Map<String, Object> request, ObjectParser<T, M, L> op, String key) {
-		String _method = key == null ? null : getString(request, apijson.JSONObject.KEY_METHOD);
+		String _method = key == null ? null : getString(request, KEY_METHOD);
 		if (_method != null) {
 			RequestMethod method = RequestMethod.valueOf(_method); // 必须精准匹配，避免缓存命中率低
 			this.setMethod(method);
@@ -2237,6 +2293,18 @@ protected M getRequestStructure(RequestMethod method, String tag, int version) t
 		return object;
 	}
 
+	public static final Map<String, RequestMethod> KEY_METHOD_ENUM_MAP;
+	static {
+		KEY_METHOD_ENUM_MAP = new LinkedHashMap<>();
+		KEY_METHOD_ENUM_MAP.put(KEY_GET, RequestMethod.GET);
+		KEY_METHOD_ENUM_MAP.put(KEY_GETS, RequestMethod.GETS);
+		KEY_METHOD_ENUM_MAP.put(KEY_HEAD, RequestMethod.HEAD);
+		KEY_METHOD_ENUM_MAP.put(KEY_HEADS, RequestMethod.HEADS);
+		KEY_METHOD_ENUM_MAP.put(KEY_POST, RequestMethod.POST);
+		KEY_METHOD_ENUM_MAP.put(KEY_PUT, RequestMethod.PUT);
+		KEY_METHOD_ENUM_MAP.put(KEY_DELETE, RequestMethod.DELETE);
+	}
+
 	protected M batchVerify(RequestMethod method, String tag, int version, String name, @NotNull M request, int maxUpdateCount, SQLCreator<T, M, L> creator) throws Exception {
 		M correctRequest = JSON.createJSONObject();
 		List<String> removeTmpKeys = new ArrayList<>(); // 请求json里面的临时变量,不需要带入后面的业务中,比如 @post、@get等
@@ -2248,14 +2316,14 @@ protected M batchVerify(RequestMethod method, String tag, int version, String na
 
 		for (String key : reqSet) {
 			// key 重复直接抛错(xxx:alias, xxx:alias[])
-			if (correctRequest.containsKey(key) || correctRequest.containsKey(key + apijson.JSONObject.KEY_ARRAY)) {
+			if (correctRequest.containsKey(key) || correctRequest.containsKey(key + KEY_ARRAY)) {
 				throw new IllegalArgumentException("对象名重复,请添加别名区分 ! 重复对象名为: " + key);
 			}
 
-			boolean isPost = apijson.JSONObject.KEY_POST.equals(key);
+			boolean isPost = KEY_POST.equals(key);
 			// @post、@get 等 RequestMethod
 			try {
-				RequestMethod keyMethod = isPost ? RequestMethod.POST : apijson.JSONObject.KEY_METHOD_ENUM_MAP.get(key);
+				RequestMethod keyMethod = isPost ? RequestMethod.POST : KEY_METHOD_ENUM_MAP.get(key);
 				if (keyMethod != null) {
 					// 如果不匹配,异常不处理即可
 					removeTmpKeys.add(key);
@@ -2273,7 +2341,7 @@ protected M batchVerify(RequestMethod method, String tag, int version, String na
 										throw new ConflictException(key + ": value 中 " + tbl + " 已经存在，不能重复！");
 									}
 
-									obj.put(tbl, isPost && apijson.JSONObject.isTableArray(tbl)
+									obj.put(tbl, isPost && isTableArray(tbl)
 											? tbl.substring(0, tbl.length() - 2) + ":[]" : "");
 								}
 							}
@@ -2292,14 +2360,14 @@ protected M batchVerify(RequestMethod method, String tag, int version, String na
 						}
 
 						Map<String, Object> objAttrMap = new HashMap<>();
-						objAttrMap.put(apijson.JSONObject.KEY_METHOD, keyMethod);
+						objAttrMap.put(KEY_METHOD, keyMethod);
 						keyObjectAttributesMap.put(objKey, objAttrMap);
 
 						Object objVal = objEntry.getValue();
 						Map<String, Object> objAttrJson = objVal instanceof Map<?, ?> ? JSON.getMap(obj, objKey) : null;
 						if (objAttrJson == null) {
 							if (objVal instanceof String) {
-								objAttrMap.put(apijson.JSONRequest.KEY_TAG, "".equals(objVal) ? objKey : objVal);
+								objAttrMap.put(KEY_TAG, "".equals(objVal) ? objKey : objVal);
 							}
 							else {
 								throw new IllegalArgumentException(key + ": { " + objKey + ": value 中 value 类型错误，只能是 String 或 Map<String, Object> {} ！");
@@ -2316,14 +2384,14 @@ protected M batchVerify(RequestMethod method, String tag, int version, String na
 								}
 
 								switch (objAttrKey) {
-									case apijson.JSONObject.KEY_DATASOURCE:
-									case apijson.JSONObject.KEY_SCHEMA:
-									case apijson.JSONObject.KEY_DATABASE:
-									case apijson.JSONRequest.KEY_VERSION:
-									case apijson.JSONObject.KEY_ROLE:
+									case KEY_DATASOURCE:
+									case KEY_SCHEMA:
+									case KEY_DATABASE:
+									case KEY_VERSION:
+									case KEY_ROLE:
 										objAttrMap.put(objAttrKey, entry.getValue());
 										break;
-									case apijson.JSONRequest.KEY_TAG:
+									case KEY_TAG:
 										hasTag = true;
 										objAttrMap.put(objAttrKey, entry.getValue());
 										break;
@@ -2333,7 +2401,7 @@ protected M batchVerify(RequestMethod method, String tag, int version, String na
 							}
 
 							if (hasTag == false) {
-								objAttrMap.put(apijson.JSONRequest.KEY_TAG, isPost && apijson.JSONObject.isTableArray(objKey)
+								objAttrMap.put(KEY_TAG, isPost && isTableArray(objKey)
 										? objKey.substring(0, objKey.length() - 2) + ":[]" : objKey);
 							}
 						}
@@ -2352,33 +2420,33 @@ protected M batchVerify(RequestMethod method, String tag, int version, String na
 
 					if (attrMap == null) {
 						// 数组会解析为对象进行校验,做一下兼容
-						if (keyObjectAttributesMap.get(key + apijson.JSONObject.KEY_ARRAY) == null) {
+						if (keyObjectAttributesMap.get(key + KEY_ARRAY) == null) {
 							if (method == RequestMethod.CRUD || key.endsWith("@")) {
-								((Map<String, Object>) obj).put(apijson.JSONObject.KEY_METHOD, GET);
+								((Map<String, Object>) obj).put(KEY_METHOD, GET);
 								Map<String, Object> objAttrMap = new HashMap<>();
-								objAttrMap.put(apijson.JSONObject.KEY_METHOD, GET);
+								objAttrMap.put(KEY_METHOD, GET);
 								keyObjectAttributesMap.put(key, objAttrMap);
 							} else {
-								((Map<String, Object>) obj).put(apijson.JSONObject.KEY_METHOD, method);
+								((Map<String, Object>) obj).put(KEY_METHOD, method);
 								Map<String, Object> objAttrMap = new HashMap<>();
-								objAttrMap.put(apijson.JSONObject.KEY_METHOD, method);
+								objAttrMap.put(KEY_METHOD, method);
 								keyObjectAttributesMap.put(key, objAttrMap);
 							}
 						} else {
-							setRequestAttribute(key, true, apijson.JSONObject.KEY_METHOD, request);
-							setRequestAttribute(key, true, apijson.JSONObject.KEY_DATASOURCE, request);
-							setRequestAttribute(key, true, apijson.JSONObject.KEY_SCHEMA, request);
-							setRequestAttribute(key, true, apijson.JSONObject.KEY_DATABASE, request);
-							setRequestAttribute(key, true, apijson.JSONRequest.KEY_VERSION, request);
-							setRequestAttribute(key, true, apijson.JSONObject.KEY_ROLE, request);
+							setRequestAttribute(key, true, KEY_METHOD, request);
+							setRequestAttribute(key, true, KEY_DATASOURCE, request);
+							setRequestAttribute(key, true, KEY_SCHEMA, request);
+							setRequestAttribute(key, true, KEY_DATABASE, request);
+							setRequestAttribute(key, true, KEY_VERSION, request);
+							setRequestAttribute(key, true, KEY_ROLE, request);
 						}
 					} else {
-						setRequestAttribute(key, false, apijson.JSONObject.KEY_METHOD, request);
-						setRequestAttribute(key, false, apijson.JSONObject.KEY_DATASOURCE, request);
-						setRequestAttribute(key, false, apijson.JSONObject.KEY_SCHEMA, request);
-						setRequestAttribute(key, false, apijson.JSONObject.KEY_DATABASE, request);
-						setRequestAttribute(key, false, apijson.JSONRequest.KEY_VERSION, request);
-						setRequestAttribute(key, false, apijson.JSONObject.KEY_ROLE, request);
+						setRequestAttribute(key, false, KEY_METHOD, request);
+						setRequestAttribute(key, false, KEY_DATASOURCE, request);
+						setRequestAttribute(key, false, KEY_SCHEMA, request);
+						setRequestAttribute(key, false, KEY_DATABASE, request);
+						setRequestAttribute(key, false, KEY_VERSION, request);
+						setRequestAttribute(key, false, KEY_ROLE, request);
 					}
 				}
 
@@ -2391,7 +2459,7 @@ protected M batchVerify(RequestMethod method, String tag, int version, String na
 					RequestMethod  _method;
 					if (obj instanceof Map<?, ?>) {
 						Map<String, Object> tblObj = JSON.getMap(request, key);
-						String mn = tblObj == null ? null : getString(tblObj, apijson.JSONObject.KEY_METHOD);
+						String mn = tblObj == null ? null : getString(tblObj, KEY_METHOD);
 						_method = mn == null ? null : RequestMethod.valueOf(mn);
 						String combine = _method == null ? null : getString(tblObj, KEY_COMBINE);
 						if (combine != null && RequestMethod.isPublicMethod(_method) == false) {
@@ -2404,16 +2472,16 @@ protected M batchVerify(RequestMethod method, String tag, int version, String na
 							if (method == RequestMethod.CRUD) {
 								_method = GET;
 								Map<String, Object> objAttrMap = new HashMap<>();
-								objAttrMap.put(apijson.JSONObject.KEY_METHOD, GET);
+								objAttrMap.put(KEY_METHOD, GET);
 								keyObjectAttributesMap.put(key, objAttrMap);
 							} else {
 								_method = method;
 								Map<String, Object> objAttrMap = new HashMap<>();
-								objAttrMap.put(apijson.JSONObject.KEY_METHOD, method);
+								objAttrMap.put(KEY_METHOD, method);
 								keyObjectAttributesMap.put(key, objAttrMap);
 							}
 						} else {
-							_method = (RequestMethod) attrMap.get(apijson.JSONObject.KEY_METHOD);
+							_method = (RequestMethod) attrMap.get(KEY_METHOD);
 						}
 					}
 
@@ -2474,7 +2542,7 @@ public static <E extends Enum<E>> E getEnum(final Class<E> enumClass, final Stri
     }
 
 	protected void setRequestAttribute(String key, boolean isArray, String attrKey, @NotNull Map<String, Object> request) {
-		Map<String, Object> attrMap = keyObjectAttributesMap.get(isArray ? key + apijson.JSONObject.KEY_ARRAY : key);
+		Map<String, Object> attrMap = keyObjectAttributesMap.get(isArray ? key + KEY_ARRAY : key);
 		Object attrVal = attrMap == null ? null : attrMap.get(attrKey);
 		Map<String, Object> obj = attrVal == null ? null : JSON.get(request, key);
 
@@ -2487,7 +2555,7 @@ protected void setRequestAttribute(String key, boolean isArray, String attrKey,
 	protected String buildTag(Map<String, Object> request, String key, RequestMethod method, String tag) {
 		if (method == RequestMethod.CRUD) {
 			Map<String, Object> attrMap = keyObjectAttributesMap.get(key);
-			Object _tag = attrMap == null ? null : attrMap.get(apijson.JSONRequest.KEY_TAG);
+			Object _tag = attrMap == null ? null : attrMap.get(KEY_TAG);
 			return _tag != null ? _tag.toString() : StringUtil.isEmpty(tag) ? key : tag;
 		} else {
 			if (StringUtil.isEmpty(tag, true)) {
@@ -2501,19 +2569,9 @@ protected String buildTag(Map<String, Object> request, String key, RequestMethod
 	protected M objectVerify(RequestMethod method, String tag, int version, String name, @NotNull M request
 			, int maxUpdateCount, SQLCreator<T, M, L> creator, M object) throws Exception {
 		// 获取指定的JSON结构 >>>>>>>>>>>>>>
-		M target = wrapRequest(method, tag, object, true, new JSONCreator<M, L>() {
-			@Override
-			public M createJSONObject() {
-				return JSON.createJSONObject();
-			}
-
-			@Override
-			public L createJSONArray() {
-				return JSON.createJSONArray();
-			}
-		});
+		M target = wrapRequest(method, tag, object, true);
 		// Map<String, Object> clone 浅拷贝没用，Structure.parse 会导致 structure 里面被清空，第二次从缓存里取到的就是 {}
-		return getVerifier().verifyRequest(method, name, target, request, maxUpdateCount, getGlobalDatabase(), getGlobalSchema(), creator);
+		return getVerifier().setParser(this).verifyRequest(method, name, target, request, maxUpdateCount, getGlobalDatabase(), getGlobalSchema());
 	}
 
 	/***
@@ -2525,7 +2583,7 @@ public L createJSONArray() {
 	public RequestMethod getRealMethod(RequestMethod method, String key, Object value) {
 		if (method == CRUD && (value instanceof Map<?, ?> || value instanceof List<?>)) {
 			Map<String, Object> attrMap = keyObjectAttributesMap.get(key);
-			Object _method = attrMap == null ? null : attrMap.get(apijson.JSONObject.KEY_METHOD);
+			Object _method = attrMap == null ? null : attrMap.get(KEY_METHOD);
 			if (_method instanceof RequestMethod) {
 				return (RequestMethod) _method;
 			}
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
index cc8d72f81..d9e9eb016 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
@@ -1,46 +1,25 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
 
 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.JSONObject.*;
-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.JSONMap.*;
+import static apijson.RequestMethod.*;
+import static apijson.SQL.*;
 
 /**config sql for JSON Request
  * @author Lemon
@@ -190,6 +169,7 @@ public abstract class AbstractSQLConfig<T, M extends Map<String, Object>, L exte
 		DATABASE_LIST.add(DATABASE_QUESTDB);
 		DATABASE_LIST.add(DATABASE_IOTDB);
 		DATABASE_LIST.add(DATABASE_SNOWFLAKE);
+		DATABASE_LIST.add(DATABASE_DATABEND);
 		DATABASE_LIST.add(DATABASE_DATABRICKS);
 		DATABASE_LIST.add(DATABASE_REDIS);
 		DATABASE_LIST.add(DATABASE_MONGODB);
@@ -199,6 +179,7 @@ public abstract class AbstractSQLConfig<T, M extends Map<String, Object>, L exte
 		DATABASE_LIST.add(DATABASE_DUCKDB);
 		DATABASE_LIST.add(DATABASE_SURREALDB);
 		DATABASE_LIST.add(DATABASE_OPENGAUSS);
+		DATABASE_LIST.add(DATABASE_DORIS);
 
 
 		RAW_MAP = new LinkedHashMap<>();  // 保证顺序，避免配置冲突等意外情况
@@ -298,6 +279,7 @@ public abstract class AbstractSQLConfig<T, M extends Map<String, Object>, L exte
 		RAW_MAP.put("BY", "");
 		RAW_MAP.put("DESC", "");
 		RAW_MAP.put("ASC", "");
+		RAW_MAP.put("PRECEDING", ""); // 往前
 		RAW_MAP.put("FOLLOWING", ""); // 往后
 		RAW_MAP.put("BETWEEN", "");
 		RAW_MAP.put("ROWS", "");
@@ -956,7 +938,7 @@ public String getUserIdKey() {
 	private int page; //Table所在页码
 	private int position; //Table在[]中的位置
 	private int query; //apijson.JSONRequest.QUERY
-	private Boolean compat; //apijson.JSONObject.compat  query total
+	private Boolean compat; //apijson.JSONMap.compat  query total
 	private int type; //ObjectParser.type
 	private int cache;
 	private boolean explain;
@@ -1250,6 +1232,14 @@ public static boolean isSnowflake(String db) {
 		return DATABASE_SNOWFLAKE.equals(db);
 	}
 
+	@Override
+	public boolean isDatabend() {
+		return isDatabend(gainSQLDatabase());
+	}
+	public static boolean isDatabend(String db) {
+		return DATABASE_DATABEND.equals(db);
+	}
+
 	@Override
 	public boolean isDatabricks() {
 		return isDatabricks(gainSQLDatabase());
@@ -1379,12 +1369,20 @@ public static boolean isOpenGauss(String db) {
 		return DATABASE_OPENGAUSS.equals(db);
 	}
 
+	@Override
+	public boolean isDoris() {
+		return isDoris(gainSQLDatabase());
+	}
+	public static boolean isDoris(String db) {
+		return DATABASE_DORIS.equals(db);
+	}
+
 	@Override
 	public String getQuote() { // MongoDB  同时支持 `tbl` 反引号 和 "col" 双引号
 		if(isElasticsearch() || isManticore() || isIoTDB() || isSurrealDB()) {
 			return "";
 		}
-		return isMySQL() || isMariaDB() || isTiDB() || isClickHouse() || isTDengine() || isMilvus() ? "`" : "\"";
+		return isMySQL() || isMariaDB() || isTiDB() || isClickHouse() || isTDengine() || isMilvus() || isDoris() ? "`" : "\"";
 	}
 
 	public String quote(String s) {
@@ -1564,7 +1562,7 @@ public String gainGroupString(boolean hasPrefix) {
 					continue;
 				}
 
-				SQLConfig<T, M, L> ocfg = join.getOuterConfig();
+				SQLConfig<T, M, L> ocfg = join.getOnConfig();
 				SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getGroup() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
 
 				if (cfg != null) {
@@ -1579,6 +1577,23 @@ public String gainGroupString(boolean hasPrefix) {
 						first = false;
 					}
 				}
+
+				////先处理左/右关联，内关联忽略
+				//SQLConfig<T, M, L> outerConfig = join.getOuterConfig();
+				//SQLConfig<T, M, L> 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;
+				//	}
+				//}
 			}
 		}
 
@@ -1640,7 +1655,7 @@ public String gainHavingString(boolean hasPrefix) throws Exception {
 					continue;
 				}
 
-				SQLConfig<T, M, L> ocfg = join.getOuterConfig();
+				SQLConfig<T, M, L> ocfg = join.getOnConfig();
 				SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getHaving() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
 
 				if (cfg != null) {
@@ -1753,7 +1768,7 @@ public String gainSampleString(boolean hasPrefix) {
 					continue;
 				}
 
-				SQLConfig<T, M, L> ocfg = join.getOuterConfig();
+				SQLConfig<T, M, L> ocfg = join.getOnConfig();
 				SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getSample() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
 
 				if (cfg != null) {
@@ -1823,7 +1838,7 @@ public String gainLatestString(boolean hasPrefix) {
 					continue;
 				}
 
-				SQLConfig<T, M, L> ocfg = join.getOuterConfig();
+				SQLConfig<T, M, L> ocfg = join.getOnConfig();
 				SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getLatest() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
 
 				if (cfg != null) {
@@ -1888,7 +1903,7 @@ public String gainPartitionString(boolean hasPrefix) {
 					continue;
 				}
 
-				SQLConfig<T, M, L> ocfg = join.getOuterConfig();
+				SQLConfig<T, M, L> ocfg = join.getOnConfig();
 				SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getPartition() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
 
 				if (cfg != null) {
@@ -1953,7 +1968,7 @@ public String gainFillString(boolean hasPrefix) {
 					continue;
 				}
 
-				SQLConfig<T, M, L> ocfg = join.getOuterConfig();
+				SQLConfig<T, M, L> ocfg = join.getOnConfig();
 				SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getFill() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
 
 				if (cfg != null) {
@@ -2019,6 +2034,7 @@ public AbstractSQLConfig<T, M, L> setOrder(String order) {
 	public String gainOrderString(boolean hasPrefix) {
 		//加上子表的 order
 		String joinOrder = "";
+		String joinOuterOrder = "";
 		if (joinList != null) {
 			boolean first = true;
 			for (Join<T, M, L> join : joinList) {
@@ -2026,7 +2042,7 @@ public String gainOrderString(boolean hasPrefix) {
 					continue;
 				}
 
-				SQLConfig<T, M, L> ocfg = join.getOuterConfig();
+				SQLConfig<T, M, L> ocfg = join.getOnConfig();
 				SQLConfig<T, M, L> cfg = (ocfg != null && ocfg.getOrder() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
 
 				if (cfg != null) {
@@ -2179,7 +2195,7 @@ public String gainRawSQL(String key, Object value, boolean throwWhenMissing) thr
 							+ "对应的 " + key + ":value 中 value 值 " + value + " 未在后端 RAW_MAP 中配置 ！");
 				}
 
-				putWarnIfNeed(apijson.JSONObject.KEY_RAW, "@raw:value 的 value 中 "
+				putWarnIfNeed(JSONMap.KEY_RAW, "@raw:value 的 value 中 "
 							+ key + " 不合法！对应的 " + key + ":value 中 value 值 " + value + " 未在后端 RAW_MAP 中配置 ！");
 			}
 			else if (rawSQL.isEmpty()) {
@@ -2335,7 +2351,7 @@ public String gainColumnString(boolean inSQLJoin) throws Exception {
 						continue;
 					}
 
-					SQLConfig<T, M, L> ocfg = join.getOuterConfig();
+					SQLConfig<T, M, L> ocfg = join.getOnConfig();
 					boolean isEmpty = ocfg == null || ocfg.getColumn() == null;
 					boolean isLeftOrRightJoin = join.isLeftOrRightJoin();
 
@@ -2941,28 +2957,28 @@ public AbstractSQLConfig<T, M, L> setCache(String cache) {
 	public static int getCache(String cache) {
 		int cache2;
 		if (cache == null) {
-			cache2 = apijson.JSONObject.CACHE_ALL;
+			cache2 = JSONMap.CACHE_ALL;
 		}
 		else {
 			//			if (isSubquery) {
-			//				throw new IllegalArgumentException("子查询内不支持传 " + apijson.JSONObject.KEY_CACHE + "!");
+			//				throw new IllegalArgumentException("子查询内不支持传 " + apijson.JSONMap.KEY_CACHE + "!");
 			//			}
 
 			switch (cache) {
 			case "0":
-			case apijson.JSONObject.CACHE_ALL_STRING:
-				cache2 = apijson.JSONObject.CACHE_ALL;
+			case JSONMap.CACHE_ALL_STRING:
+				cache2 = JSONMap.CACHE_ALL;
 				break;
 			case "1":
-			case apijson.JSONObject.CACHE_ROM_STRING:
-				cache2 = apijson.JSONObject.CACHE_ROM;
+			case JSONMap.CACHE_ROM_STRING:
+				cache2 = JSONMap.CACHE_ROM;
 				break;
 			case "2":
-			case apijson.JSONObject.CACHE_RAM_STRING:
-				cache2 = apijson.JSONObject.CACHE_RAM;
+			case JSONMap.CACHE_RAM_STRING:
+				cache2 = JSONMap.CACHE_RAM;
 				break;
 			default:
-				throw new IllegalArgumentException(apijson.JSONObject.KEY_CACHE
+				throw new IllegalArgumentException(JSONMap.KEY_CACHE
 						+ ":value 中 value 的值不合法！必须在 [0,1,2] 或 [ALL, ROM, RAM] 内 !");
 			}
 		}
@@ -3719,8 +3735,9 @@ protected String concatJoinWhereString(String whereString) throws Exception {
 			List<Object> pvl = new ArrayList<>(getPreparedValueList());
 
 			SQLConfig<T, M, L> jc;
+			SQLConfig<T, M, L> outerConfig;
 			String js;
-
+			boolean isWsEmpty = StringUtil.isEmpty(ws, true);
 			boolean changed = false;
 			// 各种 JOIN 没办法统一用 & | ！连接，只能按优先级，和 @combine 一样?
 			for (Join<T, M, L> j : joinList) {
@@ -3731,6 +3748,27 @@ 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<Object>());
+					String outerWhere = outerConfig.gainWhereString(false);
+
+					int logic1 = Logic.getType(jt);
+					newWs += " ( "
+							+ gainCondition(
+							Logic.isNot(logic1),
+							ws
+									+ ( isWsEmpty ? "" : (Logic.isAnd(logic1) ? AND : OR) )
+									+ " ( " + outerWhere + " ) "
+					)
+							+ " ) ";
+					newPvl.addAll(pvl);
+					newPvl.addAll(outerConfig.getPreparedValueList());
+
+					changed = true;
 					break;
 
 				case "&": // INNER JOIN: A & B
@@ -3751,7 +3789,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)
@@ -3991,7 +4029,7 @@ else if (isTest()) {
 
 		String sqlKey;
 		if (expression == null) {
-			sqlKey = getSQLKey(key);
+			sqlKey = gainSQLKey(key);
 		}
 		else {
 			// (name,tag) left(date,4) 等
@@ -4001,7 +4039,7 @@ else if (isTest()) {
 
 		return lenFun.isEmpty() ? sqlKey : lenFun + "(" + sqlKey + ")";
 	}
-	public String getSQLKey(String key) {
+	public String gainSQLKey(String key) {
 		String q = getQuote();
 		return (isKeyPrefix() ? q + gainSQLAlias() + q + "." : "") + q + key + q;
 	}
@@ -4556,7 +4594,7 @@ public String gainContainString(String key, String column, Object[] childs, int
 			for (int i = 0; i < childs.length; i++) {
 				Object c = childs[i];
 				if (c instanceof Collection) {
-					throw new IllegalArgumentException(key + ":value 中 value 类型不能为 [JSONArray, Collection] 中的任何一个 ！");
+					throw new IllegalArgumentException(key + ":value 中 value 类型不能为 [JSONList, Collection] 中的任何一个 ！");
 				}
 
 				Object path = "";
@@ -4570,7 +4608,7 @@ public String gainContainString(String key, String column, Object[] childs, int
 					c = ((Map<?, ?>) c).get("value");
 					if (c instanceof Collection || c instanceof Map) {
 						throw new IllegalArgumentException(key + ":{ path:path, value:value } 中 value 类型" +
-								"不能为 [JSONObject, JSONArray, Collection, Map] 中的任何一个 ！");
+								"不能为 [JSONMap, JSONList, Collection, Map] 中的任何一个 ！");
 					}
 				}
 
@@ -4763,7 +4801,7 @@ public static String gainCondition(boolean not, String condition, boolean addOut
 	 * @return
 	 */
 	@NotNull
-	public L newJSONArray(Object obj) {
+	public static <L extends List<Object>> L newJSONArray(Object obj) {
 		L array = JSON.createJSONArray();
 		if (obj != null) {
 			if (obj instanceof Collection) {
@@ -4774,18 +4812,6 @@ public L newJSONArray(Object obj) {
 		}
 		return array;
 	}
-	@NotNull
-	public static <M extends Map<String, Object>, L extends List<Object>> L newJSONArray(Object obj, @NotNull JSONCreator<M, L> creator) {
-		L array = creator.createJSONArray();
-		if (obj != null) {
-			if (obj instanceof Collection) {
-				array.addAll((Collection<?>) obj);
-			} else {
-				array.add(obj);
-			}
-		}
-		return array;
-	}
 
 	//WHERE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 
@@ -4981,16 +5007,16 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> String
 					//When config's database is oracle,Using subquery since Oracle12 below does not support OFFSET FETCH paging syntax.
 					//针对oracle分组后条数的统计
 					if (StringUtil.isNotEmpty(config.getGroup(),true) && RequestMethod.isHeadMethod(config.getMethod(), true)){
-						return explain + "SELECT count(*) FROM (SELECT " + (config.getCache() == apijson.JSONObject.CACHE_RAM
+						return explain + "SELECT count(*) FROM (SELECT " + (config.getCache() == JSONMap.CACHE_RAM
 								? "SQL_NO_CACHE " : "") + column + " FROM " + gainConditionString(tablePath, config) + ") " + config.gainLimitString();
 					}
 
-					String sql = "SELECT " + (config.getCache() == apijson.JSONObject.CACHE_RAM
+					String sql = "SELECT " + (config.getCache() == JSONMap.CACHE_RAM
 							? "SQL_NO_CACHE " : "") + column + " FROM " + gainConditionString(tablePath, config);
 					return explain + config.gainOraclePageSQL(sql);
 				}
 
-				cSql = "SELECT " + (config.getCache() == apijson.JSONObject.CACHE_RAM ? "SQL_NO_CACHE " : "")
+				cSql = "SELECT " + (config.getCache() == JSONMap.CACHE_RAM ? "SQL_NO_CACHE " : "")
 						+ column + " FROM " + gainConditionString(tablePath, config) + config.gainLimitString();
 				cSql = buildWithAsExprSql(config, cSql);
 				if(config.isElasticsearch()) { // elasticSearch 不支持 explain
@@ -5204,7 +5230,7 @@ public String gainJoinString() throws Exception {
 							);
 				}
 
-				SQLConfig<T, M, L> oc = j.getOuterConfig();
+				SQLConfig<T, M, L> oc = j.getOnConfig();
 				String ow = null;
 				if (oc != null) {
 					oc.setPrepared(isPrepared());
@@ -5922,7 +5948,7 @@ else if (w.startsWith("!")) {
 
 					if (key.endsWith("<>") == false && value instanceof Map) { // 只允许常规 Object
 						throw new IllegalArgumentException(table + ":{ " + key + ":value } 中 value 类型错误！除了 key<>:{} 外，不允许 "
-								+ key + " 等其它任何 key 对应 value 的类型为 JSONObject {} !");
+								+ key + " 等其它任何 key 对应 value 的类型为 JSONMap {} !");
 					}
 
 					// 兼容 PUT @combine
@@ -6077,10 +6103,10 @@ else if (w.startsWith("!")) {
 			else if (newHaving instanceof Map<?, ?>) {
 				if (isHavingAnd) {
 					throw new IllegalArgumentException(table + ":{ " + havingKey +  ":value } 里的 value 类型不合法！"
-							+ "@having&:value 中 value 只能是 String，@having:value 中 value 只能是 String 或 JSONObject ！");
+							+ "@having&:value 中 value 只能是 String，@having:value 中 value 只能是 String 或 JSONMap ！");
 				}
 
-				JSONObject havingObj = new JSONObject(newHaving);
+				M havingObj = JSON.createJSONObject((Map<? extends String, ?>) newHaving);
 				Set<Entry<String, Object>> havingSet = havingObj.entrySet();
 				for (Entry<String, Object> entry : havingSet) {
 					String k = entry == null ? null : entry.getKey();
@@ -6110,7 +6136,7 @@ else if (StringUtil.isName(k) == false) {
 			}
 			else if (newHaving != null) {
 				throw new IllegalArgumentException(table + ":{ " + havingKey +  ":value } 里的 value 类型不合法！"
-						+ "@having:value 中 value 只能是 String 或 JSONObject，@having&:value 中 value 只能是 String ！");
+						+ "@having:value 中 value 只能是 String 或 JSONMap，@having&:value 中 value 只能是 String ！");
 			}
 			// @having, @haivng& >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 
@@ -6132,7 +6158,7 @@ else if (keyMap instanceof String) {
 				}
 			}
 			else if (keyMap != null) {
-				throw new UnsupportedDataTypeException("@key:value 中 value 错误，只能是 String, JSONObject 中的一种！");
+				throw new UnsupportedDataTypeException("@key:value 中 value 错误，只能是 String, JSONMap 中的一种！");
 			}
 
 
@@ -6307,13 +6333,22 @@ else if (joinConfig.getDatabase().equals(config.getDatabase()) == false) {
 
 				joinConfig.setMain(false).setKeyPrefix(true);
 
+				if (join.getOn() != null) {
+					SQLConfig<T, M, L> 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<T, M, L> 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);
 				}
 			}
@@ -6324,9 +6359,12 @@ LEFT JOIN ( SELECT count(*)  AS count FROM sys.Comment ) AS Comment ON Comment.m
 			if (RequestMethod.isHeadMethod(method, true)) {
 				List<On> onList = join.getOnList();
 				List<String> column = onList == null ? null : new ArrayList<>(onList.size());
-				if (column != null) {
+				//解决 pg  如果只查询关联键，会报找不到column的错误
+				///* SELECT  count(*)  AS count  FROM sys.Moment AS Moment
+				//			   LEFT JOIN ( SELECT *  FROM sys.Comment ) AS Comment ON Comment.momentId = Moment.id LIMIT 1 OFFSET 0 */
+				if (column != null && joinConfig.isMSQL()) { // 暂时这样兼容 PostgreSQL 等不支持 SELECT 中不包含对应 key 的隐式 ON 关联字段的数据库
 					for (On on : onList) {
-						column.add(on.getKey());
+						column.add(on.getKey()); // TODO PostgreSQL 等需要找到具体的 targetTable 对应 targetKey 来加到 SELECT，比直接 SELECT * 性能更好
 					}
 				}
 
@@ -6373,8 +6411,8 @@ public static String gainRealKey(RequestMethod method, String originKey
 	public static String gainRealKey(RequestMethod method, String originKey
 			, boolean isTableKey, boolean saveLogic, boolean verifyName) throws Exception {
 		Log.i(TAG, "getRealKey  saveLogic = " + saveLogic + "; originKey = " + originKey);
-		if (originKey == null || apijson.JSONObject.isArrayKey(originKey)) {
-			Log.w(TAG, "getRealKey  originKey == null || apijson.JSONObject.isArrayKey(originKey) >>  return originKey;");
+		if (originKey == null || JSONMap.isArrayKey(originKey)) {
+			Log.w(TAG, "getRealKey  originKey == null || apijson.JSONMap.isArrayKey(originKey) >>  return originKey;");
 			return originKey;
 		}
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
index ce64cb3aa..4d6d28c02 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -127,8 +127,6 @@ public M getCacheItem(List<M> list, int position, SQLConfig<T, M, L> config) {
 
 
 
-
-
 	/**移除缓存
 	 * @param sql  key
 	 * @param config
@@ -175,6 +173,9 @@ public M execute(@NotNull SQLConfig<T, M, L> config, boolean unknownType) throws
 			return null;
 		}
 
+		Parser<T, M, L> parser2 = config.gainParser();
+		parser = parser2 != null ? parser2 : getParser();;
+
 		boolean isExplain = config.isExplain();
 		boolean isHead = RequestMethod.isHeadMethod(config.getMethod(), true);
 
@@ -237,7 +238,7 @@ public M execute(@NotNull SQLConfig<T, M, L> config, boolean unknownType) throws
 					}
 
 					// updateCount>0时收集结果。例如更新操作成功时，返回count(affected rows)、id字段
-					result = getParser().newSuccessResult();  // TODO 对 APIAuto 及其它现有的前端/客户端影响比较大，暂时还是返回 code 和 msg，5.0 再移除  JSON.createJSONObject();
+					result = parser.newSuccessResult();  // TODO 对 APIAuto 及其它现有的前端/客户端影响比较大，暂时还是返回 code 和 msg，5.0 再移除  JSON.createJSONObject();
 
 					//id,id{}至少一个会有，一定会返回，不用抛异常来阻止关联写操作时前面错误导致后面无条件执行！
 					result.put(JSONResponse.KEY_COUNT, updateCount);//返回修改的记录数
@@ -293,13 +294,12 @@ public M execute(@NotNull SQLConfig<T, M, L> config, boolean unknownType) throws
 				}
 			}
 
-
 			if (isExplain == false && isHead) {
 				if (rs.next() == false) {
-					return getParser().newErrorResult(new SQLException("数据库错误, rs.next() 失败！"));
+					return parser.newErrorResult(new SQLException("数据库错误, rs.next() 失败！"));
 				}
 
-				result = getParser().newSuccessResult();
+				result = parser.newSuccessResult();
 				// 兼容nosql,比如 elasticSearch-sql
 				if(config.isElasticsearch()) {
 					result.put(JSONResponse.KEY_COUNT, rs.getObject(1));
@@ -1135,7 +1135,7 @@ else if (value instanceof Clob) { //SQL Server TEXT 类型 居然走这个
 		}
 		if (castToJson) {
 			try {
-				value = JSON.parseJSON(value);
+				value = JSON.parse(value);
 			} catch (Exception e) {
 				Log.e(TAG, "getValue  try { value = parseJSON((String) value); } catch (Exception e) { \n" + e.getMessage());
 			}
@@ -1213,14 +1213,15 @@ public PreparedStatement getStatement(@NotNull SQLConfig<T, M, L> config, String
 			sql = config.gainSQL(config.isPrepared());
 		}
 
+		Connection conn = getConnection(config);
 		PreparedStatement statement; //创建Statement对象
 		if (config.getMethod() == RequestMethod.POST && config.getId() == null) { //自增id
 			if (config.isOracle()) {
 				// 解决 oracle 使用自增主键 插入获取不到id问题
 				String[] generatedColumns = {config.getIdKey()};
-				statement = getConnection(config).prepareStatement(sql, generatedColumns);
+				statement = conn.prepareStatement(sql, generatedColumns);
 			} else {
-				statement = getConnection(config).prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
+				statement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
 			}
 		}
 		else if (RequestMethod.isGetMethod(config.getMethod(), true)) {
@@ -1234,13 +1235,13 @@ else if (RequestMethod.isGetMethod(config.getMethod(), true)) {
             if (config.isMySQL() || config.isTiDB() || config.isMariaDB() || config.isOracle() || config.isSQLServer() || config.isDb2()
 					|| config.isPostgreSQL() || config.isCockroachDB() || config.isOpenGauss() || config.isTimescaleDB() || config.isQuestDB()
 			) {
-                statement = getConnection(config).prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
+                statement = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
             } else {
-                statement = getConnection(config).prepareStatement(sql);
+                statement = conn.prepareStatement(sql);
             }
 		}
 		else {
-			statement = getConnection(config).prepareStatement(sql);
+			statement = conn.prepareStatement(sql);
 		}
 
 		List<Object> valueList = config.isPrepared() ? config.getPreparedValueList() : null;
@@ -1265,7 +1266,7 @@ else if (RequestMethod.isGetMethod(config.getMethod(), true)) {
 	}
 
 	public PreparedStatement setArgument(@NotNull SQLConfig<T, M, L> config, @NotNull PreparedStatement statement, int index, Object value) throws SQLException {
-		//JSON.isBooleanOrNumberOrString(v) 解决 PostgreSQL: Can't infer the SQL type to use for an instance of com.alibaba.fastjson.JSONArray
+		//JSON.isBooleanOrNumberOrString(v) 解决 PostgreSQL: Can't infer the SQL type to use for an instance of com.alibaba.fastjson.JSONList
 		if (apijson.JSON.isBoolOrNumOrStr(value)) {
 			statement.setObject(index + 1, value); //PostgreSQL JDBC 不支持隐式类型转换 tinyint = varchar 报错
 		}
@@ -1276,17 +1277,32 @@ public PreparedStatement setArgument(@NotNull SQLConfig<T, M, L> config, @NotNul
 	}
 
 	protected Map<String, Connection> connectionMap = new HashMap<>();
+	public Map<String, Connection> getConnectionMap() {
+		if (connectionMap == null) {
+			connectionMap = new HashMap<>();
+		}
+		return connectionMap;
+	}
+
 	protected Connection connection;
+	@NotNull
+	public Connection getConnection(String key) throws Exception {
+		return getConnectionMap().get(key);
+	}
+	public Connection putConnection(String key, Connection connection) throws Exception {
+		return getConnectionMap().put(key, connection);
+	}
+
 	@NotNull
 	@Override
 	public Connection getConnection(@NotNull SQLConfig<T, M, L> config) throws Exception {
 		String connectionKey = getConnectionKey(config);
-		connection = connectionMap.get(connectionKey);
+		connection = getConnection(connectionKey);
 		if (connection == null || connection.isClosed()) {
 			Log.i(TAG, "select  connection " + (connection == null ? " = null" : ("isClosed = " + connection.isClosed()))) ;
 			// PostgreSQL 不允许 cross-database
 			connection = DriverManager.getConnection(config.gainDBUri(), config.gainDBAccount(), config.gainDBPassword());
-			connectionMap.put(connectionKey, connection);
+			putConnection(connectionKey, connection);
 		}
 
 		// TDengine 驱动内部事务处理方法都是空实现，手动 commit 无效
@@ -1326,7 +1342,7 @@ public void begin(int transactionIsolation) throws SQLException {
 		//		}
 
 		// 将所有连接设置隔离级别，且禁止自动提交，需要以下代码来 commit/rollback
-		Collection<Connection> connections = connectionMap.values();
+		Collection<Connection> connections = connectionMap == null ? null : connectionMap.values();
 		if (connections != null) {
 			for (Connection connection : connections) {
 				try {
@@ -1356,7 +1372,7 @@ public void rollback() throws SQLException {
 //		}
 
 		// 将所有连接进行回滚
-		Collection<Connection> connections = connectionMap.values();
+		Collection<Connection> connections = connectionMap == null ? null : connectionMap.values();
 		if (connections != null) {
 			for (Connection connection : connections) {
 				try {
@@ -1388,7 +1404,7 @@ public void rollback(Savepoint savepoint) throws SQLException {
 //		}
 
 		// 将所有连接进行回滚
-		Collection<Connection> connections = connectionMap.values();
+		Collection<Connection> connections = connectionMap == null ? null : connectionMap.values();
 		if (connections != null) {
 			for (Connection connection : connections) {
 				try {
@@ -1415,7 +1431,7 @@ public void commit() throws SQLException {
 //		}
 		
 		// 将所有连接进行提交
-		Collection<Connection> connections = connectionMap.values();
+		Collection<Connection> connections = connectionMap == null ? null : connectionMap.values();
 		if (connections != null) {
 			for (Connection connection : connections) {
 				try {
@@ -1444,7 +1460,7 @@ public void close() {
 		cachedSQLCount = 0;
 		executedSQLCount = 0;
 
-		if (connectionMap == null) {
+		if (connectionMap == null || connectionMap.isEmpty()) {
 			return;
 		}
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
index 9bf8e64a2..b10828eea 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -224,11 +224,11 @@ public String getVisitorIdKey(SQLConfig<T, M, L> config) {
 
 	@Override
 	public String getIdKey(String database, String schema, String datasource, String table) {
-		return apijson.JSONObject.KEY_ID;
+		return JSONMap.KEY_ID;
 	}
 	@Override
 	public String getUserIdKey(String database, String schema, String datasource, String table) {
-		return apijson.JSONObject.KEY_USER_ID;
+		return JSONMap.KEY_USER_ID;
 	}
 
 	@SuppressWarnings("unchecked")
@@ -313,7 +313,7 @@ public void verifyRole(SQLConfig<T, M, L> config, String table, RequestMethod me
 	 * @param role
 	 * @return
 	 * @throws Exception
-	 * @see {@link apijson.JSONObject#KEY_ROLE}
+	 * @see {@link JSONMap#KEY_ROLE}
 	 */
 	public void verifyAllowRole(SQLConfig<T, M, L> config, String table, RequestMethod method, String role) throws Exception {
 		Log.d(TAG, "verifyAllowRole  table = " + table + "; method = " + method + "; role = " + role);
@@ -344,7 +344,7 @@ public void verifyAllowRole(SQLConfig<T, M, L> config, String table, RequestMeth
 	 * @param role
 	 * @return
 	 * @throws Exception
-	 * @see {@link apijson.JSONObject#KEY_ROLE}
+	 * @see {@link JSONMap#KEY_ROLE}
 	 */
 	public void verifyUseRole(SQLConfig<T, M, L> config, String table, RequestMethod method, String role) throws Exception {
 		Log.d(TAG, "verifyUseRole  table = " + table + "; method = " + method + "; role = " + role);
@@ -533,7 +533,7 @@ public void verifyRepeat(String table, String key, Object value, long exceptId)
 		M tblObj = JSON.createJSONObject();
 		tblObj.put(key, value);
 		if (exceptId > 0) {//允许修改自己的属性为该属性原来的值
-			tblObj.put(apijson.JSONObject.KEY_ID + "!", exceptId);  // FIXME 这里 id 写死了，不支持自定义
+			tblObj.put(JSONMap.KEY_ID + "!", exceptId);  // FIXME 这里 id 写死了，不支持自定义
 		}
 
 		M req = JSON.createJSONObject();
@@ -559,14 +559,13 @@ public void verifyRepeat(String table, String key, Object value, long exceptId)
 	* @param maxUpdateCount
 	* @param database
 	* @param schema
-	* @param creator
 	* @return
 	* @throws Exception
 	*/
 	@Override
 	public M verifyRequest(@NotNull final RequestMethod method, final String name, final M target, final M request, final int maxUpdateCount
-			, final String database, final String schema, final SQLCreator<T, M, L> creator) throws Exception {
-		return verifyRequest(method, name, target, request, maxUpdateCount, database, schema, this, creator);
+			, final String database, final String schema) throws Exception {
+		return verifyRequest(method, name, target, request, maxUpdateCount, database, schema, this, getParser());
 	}
 
 	/**从request提取target指定的内容
@@ -574,14 +573,14 @@ public M verifyRequest(@NotNull final RequestMethod method, final String name, f
 	 * @param name
 	 * @param target
 	 * @param request
-	 * @param creator
+	 * @param parser
 	 * @return
 	 * @throws Exception
 	 */
 	public static <T, M extends Map<String, Object>, L extends List<Object>> M verifyRequest(
 			@NotNull final RequestMethod method, final String name, final M target, final M request
-			, final SQLCreator<T, M, L> creator) throws Exception {
-		return verifyRequest(method, name, target, request, AbstractParser.MAX_UPDATE_COUNT, creator);
+			, @NotNull Parser<T, M, L> parser) throws Exception {
+		return verifyRequest(method, name, target, request, AbstractParser.MAX_UPDATE_COUNT, parser);
 	}
 	/**从request提取target指定的内容
 	 * @param method
@@ -589,15 +588,15 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M verif
 	 * @param target
 	 * @param request
 	 * @param maxUpdateCount
-	 * @param creator
+	 * @param parser
 	 * @return
 	 * @throws Exception
 	 */
 	public static <T, M extends Map<String, Object>, L extends List<Object>> M verifyRequest(
 			@NotNull final RequestMethod method, final String name, final M target, final M request
-            , final int maxUpdateCount, final SQLCreator<T, M, L> creator) throws Exception {
+            , final int maxUpdateCount, @NotNull Parser<T, M, L> parser) throws Exception {
 
-		return verifyRequest(method, name, target, request, maxUpdateCount, null, null, null, creator);
+		return verifyRequest(method, name, target, request, maxUpdateCount, null, null, null, parser);
 	}
 
 	/**从request提取target指定的内容
@@ -609,17 +608,16 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M verif
 	* @param database
 	* @param schema
 	* @param idCallback
-	* @param creator
+	* @param parser
 	* @return
 	* @param <T>
 	* @throws Exception
 	*/
 	public static <T, M extends Map<String, Object>, L extends List<Object>> M verifyRequest(
-			@NotNull final RequestMethod method, final String name, final M target, final M request
-            , final int maxUpdateCount, final String database, final String schema
-            , final IdCallback<T> idCallback, final SQLCreator<T, M, L> creator) throws Exception {
+			@NotNull RequestMethod method, String name, M target, M request, int maxUpdateCount, String database
+			, String schema, IdCallback<T> idCallback, @NotNull Parser<T, M, L> parser) throws Exception {
 
-		return verifyRequest(method, name, target, request, maxUpdateCount, database, schema, null, idCallback, creator);
+		return verifyRequest(method, name, target, request, maxUpdateCount, database, schema, null, idCallback, parser);
 	}
 	/**从request提取target指定的内容
 	* @param method
@@ -631,7 +629,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M verif
 	* @param schema
 	* @param datasource
 	* @param idCallback
-	* @param creator
+	* @param parser
 	* @return
 	* @param <T>
 	* @throws Exception
@@ -639,7 +637,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M verif
 	public static <T, M extends Map<String, Object>, L extends List<Object>> M verifyRequest(
 			@NotNull final RequestMethod method, final String name, final M target, final M request
             , final int maxUpdateCount, final String database, final String schema, final String datasource
-            , final IdCallback<T> idCallback, final SQLCreator<T, M, L> creator) throws Exception {
+            , final IdCallback<T> idCallback, @NotNull Parser<T, M, L> parser) throws Exception {
 		if (ENABLE_VERIFY_CONTENT == false) {
 			throw new UnsupportedOperationException("AbstractVerifier.ENABLE_VERIFY_CONTENT == false" +
                     " 时不支持校验请求传参内容！如需支持则设置 AbstractVerifier.ENABLE_VERIFY_CONTENT = true ！");
@@ -655,14 +653,14 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M verif
 		}
 
 		//已在 Verifier 中处理
-		//		if (get(getString(request, apijson.JSONObject.KEY_ROLE)) == ADMIN) {
+		//		if (get(getString(request, apijson.JSONMap.KEY_ROLE)) == ADMIN) {
 		//			throw new IllegalArgumentException("角色设置错误！不允许在写操作Request中传 " + name +
-		//					":{ " + apijson.JSONObject.KEY_ROLE + ":admin } ！");
+		//					":{ " + apijson.JSONMap.KEY_ROLE + ":admin } ！");
 		//		}
 
 
 		//解析
-		return parse(method, name, target, request, database, schema, idCallback, creator, new OnParseCallback<T, M, L>() {
+		return parse(method, name, target, request, database, schema, idCallback, parser, new OnParseCallback<T, M, L>() {
 
 			@Override
 			public M onParseJSONObject(String key, M tobj, M robj) throws Exception {
@@ -672,10 +670,10 @@ public M onParseJSONObject(String key, M tobj, M robj) throws Exception {
 					if (tobj != null) {//不允许不传Target中指定的Table
 						throw new IllegalArgumentException(method + "请求，请在 " + name + " 内传 " + key + ":{} ！");
 					}
-				} else if (apijson.JSONObject.isTableKey(key)) {
-					String db = getString(request, apijson.JSONObject.KEY_DATABASE);
-					String sh = getString(request, apijson.JSONObject.KEY_SCHEMA);
-					String ds = getString(request, apijson.JSONObject.KEY_DATASOURCE);
+				} else if (JSONMap.isTableKey(key)) {
+					String db = getString(request, JSONMap.KEY_DATABASE);
+					String sh = getString(request, JSONMap.KEY_SCHEMA);
+					String ds = getString(request, JSONMap.KEY_DATASOURCE);
 					if (StringUtil.isEmpty(db, false)) {
 						db = database;
 					}
@@ -687,7 +685,7 @@ public M onParseJSONObject(String key, M tobj, M robj) throws Exception {
 					}
 
 					String idKey = idCallback == null ? null : idCallback.getIdKey(db, sh, ds, key);
-					String finalIdKey = StringUtil.isEmpty(idKey, false) ? apijson.JSONObject.KEY_ID : idKey;
+					String finalIdKey = StringUtil.isEmpty(idKey, false) ? JSONMap.KEY_ID : idKey;
 
 					if (method == RequestMethod.POST) {
 						if (robj.containsKey(finalIdKey)) {
@@ -699,18 +697,18 @@ public M onParseJSONObject(String key, M tobj, M robj) throws Exception {
 							verifyId(method.name(), name, key, robj, finalIdKey, maxUpdateCount, atLeastOne != null ? atLeastOne : IS_UPDATE_MUST_HAVE_ID_CONDITION);
 
 							String userIdKey = idCallback == null ? null : idCallback.getUserIdKey(db, sh, ds, key);
-							String finalUserIdKey = StringUtil.isEmpty(userIdKey, false) ? apijson.JSONObject.KEY_USER_ID : userIdKey;
+							String finalUserIdKey = StringUtil.isEmpty(userIdKey, false) ? JSONMap.KEY_USER_ID : userIdKey;
 							verifyId(method.name(), name, key, robj, finalUserIdKey, maxUpdateCount, false);
 						}
 					}
 				}
 
-				return verifyRequest(method, key, tobj, robj, maxUpdateCount, database, schema, idCallback, creator);
+				return verifyRequest(method, key, tobj, robj, maxUpdateCount, database, schema, idCallback, parser);
 			}
 
 			@Override
 			protected L onParseJSONArray(String key, L tarray, L rarray) throws Exception {
-				if ((method == RequestMethod.POST || method == RequestMethod.PUT) && apijson.JSONObject.isArrayKey(key)) {
+				if ((method == RequestMethod.POST || method == RequestMethod.PUT) && JSONMap.isArrayKey(key)) {
 					if (rarray == null || rarray.isEmpty()) {
 						throw new IllegalArgumentException(method + "请求，请在 " + name + " 内传 " + key + ":[{ ... }] "
 								+ "，批量新增 Table[]:value 中 value 必须是包含表对象的非空数组！其中每个子项 { ... } 都是"
@@ -805,15 +803,15 @@ else if (o instanceof String) {
 	* @param response
 	* @param database
 	* @param schema
-	* @param creator
+	* @param parser
 	* @param callback
 	* @return
 	* @throws Exception
 	*/
 	@Override
 	public M verifyResponse(@NotNull final RequestMethod method, final String name, final M target, final M response
-			, final String database, final String schema, SQLCreator<T, M, L> creator, OnParseCallback<T, M, L> callback) throws Exception {
-		return verifyResponse(method, name, target, response, database, schema, this, creator, callback);
+			, final String database, final String schema, @NotNull Parser<T, M, L> parser, OnParseCallback<T, M, L> callback) throws Exception {
+		return verifyResponse(method, name, target, response, database, schema, this, parser, callback);
 	}
 
 	/**校验并将response转换为指定的内容和结构
@@ -821,14 +819,14 @@ public M verifyResponse(@NotNull final RequestMethod method, final String name,
 	* @param name
 	* @param target
 	* @param response
-	* @param creator
+	* @param parser
 	* @param callback
 	* @return
 	* @throws Exception
 	*/
 	public static <T, M extends Map<String, Object>, L extends List<Object>> M verifyResponse(@NotNull final RequestMethod method, final String name
-			, final M target, final M response, SQLCreator<T, M, L> creator, OnParseCallback<T, M, L> callback) throws Exception {
-		return verifyResponse(method, name, target, response, null, null, null, creator, callback);
+			, final M target, final M response, @NotNull Parser<T, M, L> parser, OnParseCallback<T, M, L> callback) throws Exception {
+		return verifyResponse(method, name, target, response, null, null, null, parser, callback);
 	}
 	/**校验并将response转换为指定的内容和结构
 	* @param method
@@ -838,7 +836,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M verif
 	* @param database
 	* @param schema
 	* @param idKeyCallback
-	* @param creator
+	* @param parser
 	* @param callback
 	* @return
 	* @param <T>
@@ -846,7 +844,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M verif
 	*/
 	public static <T, M extends Map<String, Object>, L extends List<Object>>  M verifyResponse(@NotNull final RequestMethod method
 			, final String name, final M target, final M response, final String database, final String schema
-			, final IdCallback<T> idKeyCallback, SQLCreator<T, M, L> creator, OnParseCallback<T, M, L> callback) throws Exception {
+			, final IdCallback<T> idKeyCallback, @NotNull Parser<T, M, L> parser, OnParseCallback<T, M, L> callback) throws Exception {
 
 		Log.i(TAG, "verifyResponse  method = " + method  + "; name = " + name
 				+ "; target = \n" + JSON.toJSONString(target)
@@ -859,10 +857,10 @@ public static <T, M extends Map<String, Object>, L extends List<Object>>  M veri
 
 		//解析
 		return parse(method, name, target, response, database, schema
-                , idKeyCallback, creator, callback != null ? callback : new OnParseCallback<T, M, L>() {
+                , idKeyCallback, parser, callback != null ? callback : new OnParseCallback<T, M, L>() {
 			@Override
 			protected M onParseJSONObject(String key, M tobj, M robj) throws Exception {
-				return verifyResponse(method, key, tobj, robj, database, schema, idKeyCallback, creator, callback);
+				return verifyResponse(method, key, tobj, robj, database, schema, idKeyCallback, parser, callback);
 			}
 		});
 	}
@@ -873,14 +871,14 @@ protected M onParseJSONObject(String key, M tobj, M robj) throws Exception {
 	 * @param name
 	 * @param target
 	 * @param real
-	 * @param creator
+	 * @param parser
 	 * @param callback
 	 * @return
 	 * @throws Exception
 	 */
 	public static <T, M extends Map<String, Object>, L extends List<Object>> M parse(@NotNull final RequestMethod method
-			, String name, M target, M real, SQLCreator<T, M, L> creator, @NotNull OnParseCallback<T, M, L> callback) throws Exception {
-		return parse(method, name, target, real, null, null, null, creator, callback);
+			, String name, M target, M real, @NotNull Parser<T, M, L> parser, @NotNull OnParseCallback<T, M, L> callback) throws Exception {
+		return parse(method, name, target, real, null, null, null, parser, callback);
 	}
 	/**对request和response不同的解析用callback返回
 	 * @param method
@@ -890,15 +888,15 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M parse
 	 * @param database
 	 * @param schema
 	 * @param idCallback
-	 * @param creator
+	 * @param parser
 	 * @param callback
 	 * @return
 	 * @throws Exception
 	 */
 	public static <T, M extends Map<String, Object>, L extends List<Object>> M parse(
 			@NotNull final RequestMethod method, String name, M target, M real, final String database, final String schema
-            , final IdCallback<T> idCallback, SQLCreator<T, M, L> creator, @NotNull OnParseCallback<T, M, L> callback) throws Exception {
-		return parse(method, name, target, real, database, schema, null, idCallback, creator, callback);
+            , final IdCallback<T> idCallback, @NotNull Parser<T, M, L> parser, @NotNull OnParseCallback<T, M, L> callback) throws Exception {
+		return parse(method, name, target, real, database, schema, null, idCallback, parser, callback);
 	}
 	/**对request和response不同的解析用callback返回
 	 * @param method
@@ -909,14 +907,14 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M parse
 	 * @param schema
 	 * @param datasource
 	 * @param idCallback
-	 * @param creator
+	 * @param parser
 	 * @param callback
 	 * @return
 	 * @throws Exception
 	 */
 	public static <T, M extends Map<String, Object>, L extends List<Object>> M parse(@NotNull final RequestMethod method
 			, String name, M target, M real, final String database, final String schema, final String datasource
-            , final IdCallback<T> idCallback, SQLCreator<T, M, L> creator, @NotNull OnParseCallback<T, M, L> callback) throws Exception {
+            , final IdCallback<T> idCallback, @NotNull Parser<T, M, L> parser, @NotNull OnParseCallback<T, M, L> callback) throws Exception {
 		if (target == null) {
 			return null;
 		}
@@ -937,7 +935,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M parse
 		Object _if = target.get(IF.name());
 		boolean ifIsStr = _if instanceof String && StringUtil.isNotEmpty(_if, true);
 		M ifObj = ifIsStr == false && _if instanceof Map<?,?> ? (M) _if : null;
-//				: (_if instanceof String ? new apijson.JSONObject((String) _if, "" /* "throw new Error('')" */ ) : null);
+//				: (_if instanceof String ? new apijson.JSONMap((String) _if, "" /* "throw new Error('')" */ ) : null);
 		if (ifObj == null && _if != null && ifIsStr == false) {
 //			if (_if instanceof List<?>) {
 //			}
@@ -1006,7 +1004,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M parse
 					}
 					tvalue = callback.onParseJSONArray(key, (L) tvalue, (L) rvalue);
 
-					if ((method == RequestMethod.POST || method == RequestMethod.PUT) && apijson.JSONObject.isArrayKey(key)) {
+					if ((method == RequestMethod.POST || method == RequestMethod.PUT) && JSONMap.isArrayKey(key)) {
 						objKeySet.add(key);
 					}
 				} else { // 其它Object
@@ -1114,7 +1112,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M parse
                             + name + " 里面不允许传 " + rk + ":{} ！");
 				}
 				if ((method == RequestMethod.POST || method == RequestMethod.PUT)
-                        && rv instanceof List<?> && apijson.JSONObject.isArrayKey(rk)) {
+                        && rv instanceof List<?> && JSONMap.isArrayKey(rk)) {
 					throw new UnsupportedOperationException(method + " 请求，" + name + " 里面不允许 "
                             + rk + ":[] 等未定义的 Table[]:[{}] 批量操作键值对！");
 				}
@@ -1131,17 +1129,17 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M parse
 
 		// 校验与修改Request<<<<<<<<<<<<<<<<<
 		// 在tableKeySet校验后操作，避免 导致put/add进去的Table 被当成原Request的内容
-		real = operate(TYPE, type, real, creator);
-		real = operate(VERIFY, verify, real, creator);
-		real = operate(INSERT, insert, real, creator);
-		real = operate(UPDATE, update, real, creator);
-		real = operate(REPLACE, replace, real, creator);
+		real = operate(TYPE, type, real, parser);
+		real = operate(VERIFY, verify, real, parser);
+		real = operate(INSERT, insert, real, parser);
+		real = operate(UPDATE, update, real, parser);
+		real = operate(REPLACE, replace, real, parser);
 		// 校验与修改Request>>>>>>>>>>>>>>>>>
 
 
-		String db = getString(real, apijson.JSONObject.KEY_DATABASE);
-		String sh = getString(real, apijson.JSONObject.KEY_SCHEMA);
-		String ds = getString(real, apijson.JSONObject.KEY_DATASOURCE);
+		String db = getString(real, JSONMap.KEY_DATABASE);
+		String sh = getString(real, JSONMap.KEY_SCHEMA);
+		String ds = getString(real, JSONMap.KEY_DATASOURCE);
 		if (StringUtil.isEmpty(db, false)) {
 			db = database;
 		}
@@ -1152,7 +1150,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M parse
 			ds = datasource;
 		}
 		String idKey = idCallback == null ? null : idCallback.getIdKey(db, sh, ds, name);
-		String finalIdKey = StringUtil.isEmpty(idKey, false) ? apijson.JSONObject.KEY_ID : idKey;
+		String finalIdKey = StringUtil.isEmpty(idKey, false) ? JSONMap.KEY_ID : idKey;
 
 		// TODO 放在operate前？考虑性能、operate修改后再验证的值是否和原来一样
 		// 校验存在<<<<<<<<<<<<<<<<<<<
@@ -1163,7 +1161,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M parse
 			for (String e : exists) {
 				map.put(e,real.get(e));
 			}
-			verifyExist(name, map, exceptId, creator);
+			verifyExist(name, map, exceptId, parser);
 		}
 		// 校验存在>>>>>>>>>>>>>>>>>>>
 
@@ -1176,7 +1174,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M parse
 			for (String u : uniques) {
 				map.put(u, real.get(u));
 			}
-			verifyRepeat(name, map, exceptId, finalIdKey, creator);
+			verifyRepeat(name, map, exceptId, finalIdKey, parser);
 		}
 		// 校验重复>>>>>>>>>>>>>>>>>>>
 
@@ -1184,7 +1182,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M parse
 		String[] partialFails = StringUtil.split(allowPartialUpdateFail);
 		if (partialFails != null && partialFails.length > 0) {
 			for (String key : partialFails) {
-                if (apijson.JSONObject.isArrayKey(key) == false) {
+                if (JSONMap.isArrayKey(key) == false) {
                     throw new IllegalArgumentException("后端 Request 表中 " + ALLOW_PARTIAL_UPDATE_FAIL.name()
                             + ":value 中 " + key + " 不合法！必须以 [] 结尾！");
                 }
@@ -1207,15 +1205,15 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M parse
 		// 校验并配置允许部分批量增删改失败>>>>>>>>>>>>>>>>>>>
 
 
-		String[] nks = ifObj == null ? null : StringUtil.split(getString(real, apijson.JSONObject.KEY_NULL));
+		String[] nks = ifObj == null ? null : StringUtil.split(getString(real, JSONMap.KEY_NULL));
 		Collection<?> nkl = nks == null || nks.length <= 0 ? new HashSet<>() : Arrays.asList(nks);
 
 		Set<Map.Entry<String, Object>> ifSet = ifObj == null ? null : ifObj.entrySet();
 		if (ifIsStr || (ifSet != null && ifSet.isEmpty() == false)) {
 			// 没必要限制，都是后端配置的，安全可控，而且可能确实有特殊需求，需要 id, @column 等
-//			List<String> condKeys = new ArrayList<>(Arrays.asList(apijson.JSONObject.KEY_ID, apijson.JSONObject.KEY_ID_IN
-//					, apijson.JSONObject.KEY_USER_ID, apijson.JSONObject.KEY_USER_ID_IN));
-//			condKeys.addAll(apijson.JSONObject.TABLE_KEY_LIST);
+//			List<String> condKeys = new ArrayList<>(Arrays.asList(apijson.JSONMap.KEY_ID, apijson.JSONMap.KEY_ID_IN
+//					, apijson.JSONMap.KEY_USER_ID, apijson.JSONMap.KEY_USER_ID_IN));
+//			condKeys.addAll(apijson.JSONMap.TABLE_KEY_LIST);
 
 			String preCode = "var curObj = " + JSON.toJSONString(real) + ";";
 
@@ -1284,7 +1282,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> M parse
 					}
 
 					if (nkl.contains(k) || real.get(k) != null) {
-						real = parse(method, name, (M) v, real, database, schema, datasource, idCallback, creator, callback);
+						real = parse(method, name, (M) v, real, database, schema, datasource, idCallback, parser, callback);
 					}
 				}
 			}
@@ -1309,12 +1307,12 @@ public static ScriptEngine getScriptEngine(String lang) {
 	 * @param opt
 	 * @param targetChild
 	 * @param real
-	 * @param creator
+	 * @param parser
 	 * @return
 	 * @throws Exception
 	 */
 	private static <T, M extends Map<String, Object>, L extends List<Object>> M operate(Operation opt, M targetChild
-            , M real, SQLCreator<T, M, L> creator) throws Exception {
+            , M real, @NotNull Parser<T, M, L> parser) throws Exception {
 		if (targetChild == null) {
 			return real;
 		}
@@ -1335,7 +1333,7 @@ private static <T, M extends Map<String, Object>, L extends List<Object>> M oper
 				verifyType(tk, tv, real);
 			}
 			else if (opt == VERIFY) {
-				verifyValue(tk, tv, real, creator);
+				verifyValue(tk, tv, real, parser);
 			}
 			else if (opt == UPDATE) {
 				real.put(tk, tv);
@@ -1409,7 +1407,7 @@ public static void verifyType(@NotNull String tk, @NotNull String tv, Object rv,
 		//这里不抽取 enum，因为 enum 不能满足扩展需求，子类需要可以自定义，而且 URL[] 这种也不符合命名要求，得用 constructor + getter + setter
 		switch (tv) {
 		case "BOOLEAN": //Boolean.parseBoolean(getString(real, tk)); 只会判断null和true
-			if (rv instanceof Boolean == false) { //apijson.JSONObject.getBoolean 可转换Number类型
+			if (rv instanceof Boolean == false) { //apijson.JSONMap.getBoolean 可转换Number类型
 				throw new UnsupportedDataTypeException(tk + ":value 的value不合法！类型必须是 BOOLEAN" + (isInArray ? "[] !" : " !"));
 			}
 			break;
@@ -1429,7 +1427,7 @@ public static void verifyType(@NotNull String tk, @NotNull String tv, Object rv,
 			}
 			break;
 		case "STRING":
-			if (rv instanceof String == false) { //apijson.JSONObject.getString 可转换任何类型
+			if (rv instanceof String == false) { //apijson.JSONMap.getString 可转换任何类型
 				throw new UnsupportedDataTypeException(tk + ":value 的value不合法！" +
                         "类型必须是 STRING" + (isInArray ? "[] !" : " !"));
 			}
@@ -1467,13 +1465,13 @@ public static void verifyType(@NotNull String tk, @NotNull String tv, Object rv,
 			}
 			break;
 		case "OBJECT":
-			if (rv instanceof Map == false) { //apijson.JSONObject.getJSONObject 可转换String类型
+			if (rv instanceof Map == false) { //apijson.JSONMap.getJSONObject 可转换String类型
 				throw new UnsupportedDataTypeException(tk + ":value 的value不合法！" +
                         "类型必须是 OBJECT" + (isInArray ? "[] !" : " !") + " OBJECT 结构为 {} !");
 			}
 			break;
 		case "ARRAY":
-			if (rv instanceof Collection == false) { //apijson.JSONObject.getJSONArray 可转换String类型
+			if (rv instanceof Collection == false) { //apijson.JSONMap.getJSONArray 可转换String类型
 				throw new UnsupportedDataTypeException(tk + ":value 的value不合法！" +
                         "类型必须是 ARRAY" + (isInArray ? "[] !" : " !") + " ARRAY 结构为 [] !");
 			}
@@ -1501,11 +1499,11 @@ public static void verifyType(@NotNull String tk, @NotNull String tv, Object rv,
 	 * @param tk
 	 * @param tv
 	 * @param real
-	 * @param creator
+	 * @param parser
 	 * @throws Exception
 	 */
 	private static <T, M extends Map<String, Object>, L extends List<Object>> void verifyValue(@NotNull String tk
-			, @NotNull Object tv, @NotNull M real, SQLCreator<T, M, L> creator) throws Exception {
+			, @NotNull Object tv, @NotNull M real, @NotNull Parser<T, M, L> parser) throws Exception {
 		if (tv == null) {
 			throw new IllegalArgumentException("operate  operate == VERIFY " + tk + ":" + tv + " ,  >> tv == null!!!");
 		}
@@ -1514,7 +1512,7 @@ private static <T, M extends Map<String, Object>, L extends List<Object>> void v
 		Object rv;
 		Logic logic;
 		if (tk.endsWith("$")) {  // 模糊搜索
-			verifyCondition("$", real, tk, tv, creator);
+			verifyCondition("$", real, tk, tv, parser);
 		}
 		else if (tk.endsWith("~")) {  // 正则匹配
 			logic = new Logic(tk.substring(0, tk.length() - 1));
@@ -1524,17 +1522,7 @@ else if (tk.endsWith("~")) {  // 正则匹配
 				return;
 			}
 
-			L array = AbstractSQLConfig.newJSONArray(tv, new JSONCreator<M, L>() {
-				@Override
-				public M createJSONObject() {
-					return JSON.createJSONObject();
-				}
-
-				@Override
-				public L createJSONArray() {
-					return JSON.createJSONArray();
-				}
-			});
+			L array = AbstractSQLConfig.newJSONArray(tv);
 
 			boolean m;
 			boolean isOr = false;
@@ -1569,7 +1557,7 @@ public L createJSONArray() {
 		}
 		else if (tk.endsWith("{}")) { //rv符合tv条件或在tv内
 			if (tv instanceof String) {//TODO  >= 0, < 10
-				verifyCondition("{}", real, tk, tv, creator);
+				verifyCondition("{}", real, tk, tv, parser);
 			}
 			else if (tv instanceof List<?>) {
 				logic = new Logic(tk.substring(0, tk.length() - 2));
@@ -1619,17 +1607,7 @@ else if (tk.endsWith("<>")) { //rv包含tv内的值
 				throw new UnsupportedDataTypeException("服务器Request表verify配置错误！");
 			}
 
-			L array = AbstractSQLConfig.newJSONArray(tv, new JSONCreator<Map<String, Object>, L>() {
-				@Override
-				public M createJSONObject() {
-					return JSON.createJSONObject();
-				}
-
-				@Override
-				public L createJSONArray() {
-					return JSON.createJSONArray();
-				}
-			});
+			L array = AbstractSQLConfig.newJSONArray(tv);
 
 			boolean isOr = false;
 			for (Object o : array) {
@@ -1701,12 +1679,12 @@ private static boolean verifyRV(String rule,String content) throws UnsupportedDa
 	 * @param real
 	 * @param tk
 	 * @param tv
-	 * @param creator
+	 * @param parser
 	 * @throws Exception
 	 */
 	private static <T, M extends Map<String, Object>, L extends List<Object>> void verifyCondition(
 			@NotNull String funChar, @NotNull M real, @NotNull String tk, @NotNull Object tv
-			, @NotNull SQLCreator<T, M, L> creator) throws Exception {
+			, @NotNull Parser<T, M, L> parser) throws Exception {
 		//不能用Parser, 0 这种不符合 StringUtil.isName !
 		Logic logic = new Logic(tk.substring(0, tk.length() - funChar.length()));
 		String rk = logic.getKey();
@@ -1719,7 +1697,7 @@ private static <T, M extends Map<String, Object>, L extends List<Object>> void v
 			throw new IllegalArgumentException(rk + ":value 中value不合法！value 中不允许有单引号 ' ！");
 		}
 
-		SQLConfig<T, M, L> config = creator.createSQLConfig().setMethod(RequestMethod.GET).setCount(1).setPage(0);
+		SQLConfig<T, M, L> config = parser.createSQLConfig().setMethod(RequestMethod.GET).setCount(1).setPage(0);
 		config.setTest(true);
 		//		config.setTable(Test.class.getSimpleName());
 		//		config.setColumn(rv + logic.getChar() + funChar)
@@ -1727,15 +1705,16 @@ private static <T, M extends Map<String, Object>, L extends List<Object>> void v
 		config.putWhere(rv + logic.getChar() + funChar, tv, false);
 		config.setCount(1);
 
-		SQLExecutor<T, M, L> executor = creator.createSQLExecutor();
-		M result = null;
+		SQLExecutor<T, M, L> executor = parser.createSQLExecutor(); // close 后复用导致不好修复的 NPE getSQLExecutor();
+		executor.setParser(parser);
+		M result;
 		try {
 			result = executor.execute(config, false);
 		} finally {
 			executor.close();
 		}
 
-		if (result != null && JSONResponse.isExist(getIntValue(result, JSONResponse.KEY_COUNT)) == false) {
+		if (result != null && JSONResponse.isExist(result) == false) {
 			throw new IllegalArgumentException(rk + ":value 中value不合法！必须匹配 '" + tk + "': '" + tv + "' ！");
 		}
 	}
@@ -1748,7 +1727,7 @@ private static <T, M extends Map<String, Object>, L extends List<Object>> void v
 	 * @throws Exception
 	 */
 	public static <T, M extends Map<String, Object>, L extends List<Object>>void verifyExist(String table, String key
-			, Object value, long exceptId, @NotNull SQLCreator<T, M, L> creator) throws Exception {
+			, Object value, long exceptId, @NotNull Parser<T, M, L> parser) throws Exception {
 		if (key == null || value == null) {
 			Log.e(TAG, "verifyExist  key == null || value == null >> return;");
 			return;
@@ -1758,7 +1737,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>>void ver
 		}
 		Map<String,Object> map = new HashMap<>();
 		map.put(key,value);
-		verifyExist(table,map,exceptId,creator);
+		verifyExist(table,map,exceptId,parser);
 	}
 
 	/**验证是否存在
@@ -1767,17 +1746,17 @@ public static <T, M extends Map<String, Object>, L extends List<Object>>void ver
 	 * @throws Exception
 	 */
 	public static <T, M extends Map<String, Object>, L extends List<Object>> void verifyExist(String table
-			, Map<String,Object> param, long exceptId, @NotNull SQLCreator<T, M, L> creator) throws Exception {
+			, Map<String,Object> param, long exceptId, @NotNull Parser<T, M, L> parser) throws Exception {
 		if (param.isEmpty()) {
 			Log.e(TAG, "verifyExist is empty >> return;");
 			return;
 		}
 
-		SQLConfig<T, M, L> config = creator.createSQLConfig().setMethod(RequestMethod.HEAD).setCount(1).setPage(0);
+		SQLConfig<T, M, L> config = parser.createSQLConfig().setMethod(RequestMethod.HEAD).setCount(1).setPage(0);
 		config.setTable(table);
 		param.forEach((key,value) -> config.putWhere(key, value, false));
 
-		SQLExecutor<T, M, L> executor = creator.createSQLExecutor();
+		SQLExecutor<T, M, L> executor = parser.getSQLExecutor();
 		try {
 			M result = executor.execute(config, false);
 			if (result == null) {
@@ -1800,8 +1779,8 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> void ve
 	 * @throws Exception
 	 */
 	public static <T, M extends Map<String, Object>, L extends List<Object>> void verifyRepeat(String table, String key
-			, Object value, @NotNull SQLCreator<T, M, L> creator) throws Exception {
-		verifyRepeat(table, key, value, 0, creator);
+			, Object value, @NotNull Parser<T, M, L> parser) throws Exception {
+		verifyRepeat(table, key, value, 0, parser);
 	}
 
 	/**验证是否重复
@@ -1812,8 +1791,8 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> void ve
 	 * @throws Exception
 	 */
 	public static <T, M extends Map<String, Object>, L extends List<Object>> void verifyRepeat(String table, String key
-			, Object value, long exceptId, @NotNull SQLCreator <T, M, L> creator) throws Exception {
-		verifyRepeat(table, key, value, exceptId, null, creator);
+			, Object value, long exceptId, @NotNull Parser<T, M, L> parser) throws Exception {
+		verifyRepeat(table, key, value, exceptId, null, parser);
 	}
 
 	/**验证是否重复
@@ -1823,11 +1802,11 @@ public static <T, M extends Map<String, Object>, L extends List<Object>> void ve
 	 * @param value
 	 * @param exceptId 不包含id
 	 * @param idKey
-	 * @param creator
+	 * @param parser
 	 * @throws Exception
 	 */
 	public static <T, M extends Map<String, Object>, L extends List<Object>>void verifyRepeat(String table, String key
-			, Object value, long exceptId, String idKey, @NotNull SQLCreator<T, M, L> creator) throws Exception {
+			, Object value, long exceptId, String idKey, @NotNull Parser<T, M, L> parser) throws Exception {
 		if (key == null || value == null) {
 			Log.e(TAG, "verifyRepeat  key == null || value == null >> return;");
 			return;
@@ -1837,7 +1816,7 @@ public static <T, M extends Map<String, Object>, L extends List<Object>>void ver
 		}
 		Map<String,Object> map = new HashMap<>();
 		map.put(key,value);
-		verifyRepeat(table,map,exceptId,idKey,creator);
+		verifyRepeat(table, map, exceptId, idKey, parser);
 	}
 
 	/**验证是否重复
@@ -1846,26 +1825,26 @@ public static <T, M extends Map<String, Object>, L extends List<Object>>void ver
 	 * @param param
 	 * @param exceptId 不包含id
 	 * @param idKey
-	 * @param creator
+	 * @param parser
 	 * @throws Exception
 	 */
 	public static <T, M extends Map<String, Object>, L extends List<Object>> void verifyRepeat(String table
-			, Map<String,Object> param, long exceptId, String idKey, @NotNull SQLCreator<T, M, L> creator) throws Exception {
+			, Map<String,Object> param, long exceptId, String idKey, @NotNull Parser<T, M, L> parser) throws Exception {
 		if (param.isEmpty()) {
 			Log.e(TAG, "verifyRepeat is empty >> return;");
 			return;
 		}
 
-		String finalIdKey = StringUtil.isEmpty(idKey, false) ? apijson.JSONObject.KEY_ID : idKey;
+		String finalIdKey = StringUtil.isEmpty(idKey, false) ? JSONMap.KEY_ID : idKey;
 
-		SQLConfig<T, M, L> config = creator.createSQLConfig().setMethod(RequestMethod.HEAD).setCount(1).setPage(0);
+		SQLConfig<T, M, L> config = parser.createSQLConfig().setMethod(RequestMethod.HEAD).setCount(1).setPage(0);
 		config.setTable(table);
 		if (exceptId > 0) { //允许修改自己的属性为该属性原来的值
 			config.putWhere(finalIdKey + "!", exceptId, false);
 		}
 		param.forEach((key,value) -> config.putWhere(key,value, false));
 
-		SQLExecutor<T, M, L> executor = creator.createSQLExecutor();
+		SQLExecutor<T, M, L> executor = parser.getSQLExecutor();
 		try {
 			M result = executor.execute(config, false);
 			if (result == null) {
diff --git a/APIJSONORM/src/main/java/apijson/orm/Entry.java b/APIJSONORM/src/main/java/apijson/orm/Entry.java
index a8aaf7bfd..3e010435b 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Entry.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Entry.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/FunctionParser.java b/APIJSONORM/src/main/java/apijson/orm/FunctionParser.java
index 155d80fae..8af029234 100644
--- a/APIJSONORM/src/main/java/apijson/orm/FunctionParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/FunctionParser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/JSONRequest.java b/APIJSONORM/src/main/java/apijson/orm/JSONRequest.java
index ddc22365c..40bfa147a 100755
--- a/APIJSONORM/src/main/java/apijson/orm/JSONRequest.java
+++ b/APIJSONORM/src/main/java/apijson/orm/JSONRequest.java
@@ -1,23 +1,23 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
 
 package apijson.orm;
 
-import java.util.Map;
+import java.util.*;
 
 import apijson.JSON;
 import apijson.StringUtil;
 
-/**JSONRequest for Server to replace apijson.JSONObject,
- * put JSON.parseObject(value) and not encode in default cases
+/**JSONRequest for Server to replace apijson.JSONMap,
+ * put JSON.parseObject(value) and not encode in public cases
  * @author Lemon
  * @see #put(String, Object)
  */
-public class JSONRequest extends apijson.JSONRequest {
-	private static final long serialVersionUID = 1L;
-	
+public class JSONRequest implements apijson.JSONRequest<LinkedHashMap<String, Object>, ArrayList<Object>> {
+
+	protected Map<String, Object> map = new LinkedHashMap<>();
 	public JSONRequest() {
 		super();
 	}
@@ -27,21 +27,40 @@ public JSONRequest() {
 	 * @param object
 	 */
 	public JSONRequest(Object object) {
-		super(object);
+		super();
+		put(object);
 	}
 	/**
 	 * @param name
 	 * @param object
 	 */
 	public JSONRequest(String name, Object object) {
-		super(name, object);
+		super();
+		put(name, object);
 	}
 
-	
-	
+	///**create a parent JSONMap named KEY_ARRAY
+	// * @param count
+	// * @param page
+	// * @return {@link #toArray(int, int)}
+	// */
+	//public LinkedHashMap<String, Object> toArray(int count, int page) {
+	//	return toArray(count, page, null);
+	//}
+	//
+	///**create a parent JSONMap named name+KEY_ARRAY.
+	// * @param count
+	// * @param page
+	// * @param name
+	// * @return {name+KEY_ARRAY : this}. if needs to be put, use {@link #putsAll(Map<? extends String, ? extends Object>)} instead
+	// */
+	//public LinkedHashMap<String, Object> toArray(int count, int page, String name) {
+	//	return new JSONRequest(StringUtil.get(name) + KEY_ARRAY, this.setCount(count).setPage(page));
+	//}
+
 	@Override
-	public JSONRequest putsAll(Map<? extends String, ? extends Object> map) {
-		super.putsAll(map);
+	public JSONRequest putsAll(Map<? extends String, ? extends Object> m) {
+		putAll(m);
 		return this;
 	}
 
@@ -51,7 +70,8 @@ public JSONRequest putsAll(Map<? extends String, ? extends Object> map) {
 	 */
 	@Override
 	public JSONRequest puts(Object value) {
-		return puts(null, value);
+		put(value);
+		return this;
 	}
 	/**
 	 * @param key
@@ -65,14 +85,7 @@ public JSONRequest puts(String key, Object value) {
 		return this;
 	}
 
-	/**
-	 * @param value
-	 * @return {@link #put(String, Object)}
-	 */
-	@Override
-	public Object put(Object value) {
-		return put(null, value);
-	}
+
 	/**自定义类型必须转为JSONObject或JSONArray，否则RequestParser解析不了
 	 */
 	@Override
@@ -83,15 +96,77 @@ public Object put(String key, Object value) {
 
         Object target = null;
         try {
-            target = JSON.parseJSON(value);
+            target = JSON.parse(value);
         } catch (Exception e) {
-            throw new RuntimeException(e);
+            // nothing
+			e.printStackTrace();
         }
         //		if (target == null) { // "tag":"User" 报错
 		//			return null;
 		//		}
-		return super.put(StringUtil.isNotEmpty(key, true) ? key : value.getClass().getSimpleName() //must handle key here
+		return map.put(StringUtil.isNotEmpty(key, true) ? key : value.getClass().getSimpleName() //must handle key here
 				, target == null ? value : target);
 	}
 
+
+	@Override
+	public int size() {
+		return map.size();
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return map.isEmpty();
+	}
+
+	@Override
+	public boolean containsKey(Object key) {
+		return map.containsKey(key);
+	}
+
+	@Override
+	public boolean containsValue(Object value) {
+		return map.containsValue(value);
+	}
+
+	@Override
+	public Object get(Object key) {
+		return map.get(key);
+	}
+
+	@Override
+	public Object remove(Object key) {
+		return map.remove(key);
+	}
+
+
+	@Override
+	public void clear() {
+		map.clear();
+	}
+
+	@Override
+	public Set<String> keySet() {
+		return map.keySet();
+	}
+
+	@Override
+	public Collection<Object> values() {
+		return map.values();
+	}
+
+	@Override
+	public Set<Entry<String, Object>> entrySet() {
+		return map.entrySet();
+	}
+
+	@Override
+	public String toString() {
+		return JSON.toJSONString(map);
+	}
+
+	public String toJSONString() {
+		return JSON.toJSONString(map);
+	}
+
 }
diff --git a/APIJSONORM/src/main/java/apijson/orm/Join.java b/APIJSONORM/src/main/java/apijson/orm/Join.java
index 39ca09a61..96d5e2ec7 100644
--- a/APIJSONORM/src/main/java/apijson/orm/Join.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Join.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -25,12 +25,14 @@ public class Join<T, M extends Map<String, Object>, L extends List<Object>> {
 	private List<On> onList;  // ON User.id = Moment.userId AND ...
 
 	private M request;  // { "id@":"/Moment/userId" }
-	private M outer;  // "join": { "</User": { "@order":"id-", "@group":"id", "name~":"a", "tag$":"%a%", "@combine": "name~,tag$" } } 中的 </User 对应值
+	private M on;  // "join": { "</User": { "@order":"id-", "@group":"id", "name~":"a", "tag$":"%a%", "@combine": "name~,tag$" } } 中的 </User 对应值
 
+	private M outer; // "join": { "</User": { "key2": value2, "@column": "key2,key3","@group": "key2+" }}
 	private SQLConfig<T, M, L> joinConfig;
 	private SQLConfig<T, M, L> cacheConfig;
-	private SQLConfig<T, M, L> outerConfig;
+	private SQLConfig<T, M, L> onConfig;
 
+	private SQLConfig<T, M, L> 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<T, M, L> getOuterConfig() {
+		return outerConfig;
+	}
+
+	public void setOuterConfig(SQLConfig<T, M, L> outerConfig) {
+		this.outerConfig = outerConfig;
+	}
+
 	public SQLConfig<T, M, L> getJoinConfig() {
 		return joinConfig;
 	}
@@ -97,11 +115,11 @@ public SQLConfig<T, M, L> getCacheConfig() {
 	public void setCacheConfig(SQLConfig<T, M, L> cacheConfig) {
 		this.cacheConfig = cacheConfig;
 	}
-	public SQLConfig<T, M, L> getOuterConfig() {
-		return outerConfig;
+	public SQLConfig<T, M, L> getOnConfig() {
+		return onConfig;
 	}
-	public void setOuterConfig(SQLConfig<T, M, L> outerConfig) {
-		this.outerConfig = outerConfig;
+	public void setOnConfig(SQLConfig<T, M, L> onConfig) {
+		this.onConfig = onConfig;
 	}
 
 	public boolean isOne2One() {
diff --git a/APIJSONORM/src/main/java/apijson/orm/Logic.java b/APIJSONORM/src/main/java/apijson/orm/Logic.java
index bb8e806e6..f860aa9a4 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Logic.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Logic.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/ObjectParser.java b/APIJSONORM/src/main/java/apijson/orm/ObjectParser.java
index 8817886d1..5d207f41a 100755
--- a/APIJSONORM/src/main/java/apijson/orm/ObjectParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/ObjectParser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java b/APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java
index 243acf048..e02fd90f8 100755
--- a/APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java
+++ b/APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/Operation.java b/APIJSONORM/src/main/java/apijson/orm/Operation.java
index 2976d09b0..1c4f2dc5f 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Operation.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Operation.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/Pair.java b/APIJSONORM/src/main/java/apijson/orm/Pair.java
index a4bb22030..7661d07b5 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Pair.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Pair.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -34,8 +34,8 @@ public class Pair extends Entry<String, String> {
 		CLASS_MAP.put(String.class.getSimpleName(), String.class);
 		CLASS_MAP.put(Collection.class.getSimpleName(), Collection.class);//不允许指定<T>
 		CLASS_MAP.put(Map.class.getSimpleName(), Map.class);//不允许指定<T>
-//		CLASS_MAP.put(JSONObject.class.getSimpleName(), JSONObject.class);//必须有，Map中没有getLongValue等方法
-//		CLASS_MAP.put(JSONArray.class.getSimpleName(), JSONArray.class);//必须有，Collection中没有getJSONObject等方法
+//		CLASS_MAP.put(JSONMap.class.getSimpleName(), JSONMap.class);//必须有，Map中没有getLongValue等方法
+//		CLASS_MAP.put(JSONList.class.getSimpleName(), JSONList.class);//必须有，Collection中没有getJSONObject等方法
 	}
 
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/Parser.java b/APIJSONORM/src/main/java/apijson/orm/Parser.java
index dd7a21276..1492dfc11 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Parser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Parser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -15,7 +15,8 @@
 /**解析器
  * @author Lemon
  */
-public interface Parser<T, M extends Map<String, Object>, L extends List<Object>> {
+public interface Parser<T, M extends Map<String, Object>, L extends List<Object>>
+		extends ParserCreator<T, M, L>, VerifierCreator<T, M, L>, SQLCreator<T, M, L> {
 
 	@NotNull
 	Visitor<T> getVisitor();
diff --git a/APIJSONORM/src/main/java/apijson/orm/ParserCreator.java b/APIJSONORM/src/main/java/apijson/orm/ParserCreator.java
index d6eb1c7db..f3f8d375b 100755
--- a/APIJSONORM/src/main/java/apijson/orm/ParserCreator.java
+++ b/APIJSONORM/src/main/java/apijson/orm/ParserCreator.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java
index 44d4264be..5386d160e 100755
--- a/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java
+++ b/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -33,7 +33,9 @@ public interface SQLConfig<T, M extends Map<String, Object>, L extends List<Obje
 	String DATABASE_HIVE = "HIVE"; // https://hive.apache.org
 	String DATABASE_PRESTO = "PRESTO"; // Facebook PrestoDB  https://prestodb.io
 	String DATABASE_TRINO = "TRINO"; // PrestoSQL  https://trino.io
+	String DATABASE_DORIS = "DORIS"; // https://doris.apache.org
 	String DATABASE_SNOWFLAKE = "SNOWFLAKE"; // https://www.snowflake.com
+	String DATABASE_DATABEND = "DATABEND"; // https://www.databend.com
 	String DATABASE_DATABRICKS = "DATABRICKS"; // https://www.databricks.com
 	String DATABASE_CASSANDRA = "CASSANDRA"; // https://cassandra.apache.org
 	String DATABASE_MILVUS = "MILVUS"; // https://milvus.io
@@ -99,6 +101,7 @@ public interface SQLConfig<T, M extends Map<String, Object>, L extends List<Obje
 	boolean isPresto();
 	boolean isTrino();
 	boolean isSnowflake();
+	boolean isDatabend();
 	boolean isDatabricks();
 	boolean isCassandra();
 	boolean isMilvus();
@@ -115,6 +118,7 @@ public interface SQLConfig<T, M extends Map<String, Object>, L extends List<Obje
 	boolean isDuckDB();
 	boolean isSurrealDB();
 	boolean isOpenGauss();
+	boolean isDoris();
 
 
 	// 暂时只兼容以上几种
diff --git a/APIJSONORM/src/main/java/apijson/orm/SQLCreator.java b/APIJSONORM/src/main/java/apijson/orm/SQLCreator.java
index bb5af96d8..77625cfa6 100755
--- a/APIJSONORM/src/main/java/apijson/orm/SQLCreator.java
+++ b/APIJSONORM/src/main/java/apijson/orm/SQLCreator.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java b/APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java
index a4467af8e..6540771d7 100755
--- a/APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java
+++ b/APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/Subquery.java b/APIJSONORM/src/main/java/apijson/orm/Subquery.java
index 20e5cc389..ce6e72445 100644
--- a/APIJSONORM/src/main/java/apijson/orm/Subquery.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Subquery.java
@@ -1,12 +1,10 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
 
 package apijson.orm;
 
-import apijson.JSONField;
-
 import java.util.List;
 import java.util.Map;
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/Verifier.java b/APIJSONORM/src/main/java/apijson/orm/Verifier.java
index 8ee508e11..4b926519a 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Verifier.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Verifier.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -31,7 +31,7 @@ public interface Verifier<T, M extends Map<String, Object>, L extends List<Objec
 	 * @param role
 	 * @return
 	 * @throws Exception 
-	 * @see {@link apijson.JSONObject#KEY_ROLE} 
+	 * @see {@link JSONMap#KEY_ROLE}
 	 */
 	void verifyRole(SQLConfig<T, M, L> config, String table, RequestMethod method, String role) throws Exception;
 
@@ -76,7 +76,7 @@ public interface Verifier<T, M extends Map<String, Object>, L extends List<Objec
 	 * @throws Exception
 	 */
 	M verifyRequest(RequestMethod method, String name, M target, M request,
-			int maxUpdateCount, String globalDatabase, String globalSchema, SQLCreator<T, M, L> creator) throws Exception;
+			int maxUpdateCount, String globalDatabase, String globalSchema) throws Exception;
 
 	/**验证返回结果的数据和结构
 	 * @param method
@@ -92,13 +92,16 @@ M verifyRequest(RequestMethod method, String name, M target, M request,
 	 */
 	M verifyResponse(
 		RequestMethod method, String name, M target, M response,
-		String database, String schema, SQLCreator<T, M, L> creator, OnParseCallback<T, M, L> callback
+		String database, String schema, @NotNull Parser<T, M, L> parser, OnParseCallback<T, M, L> callback
 	) throws Exception;
 
 
 	@NotNull
 	Parser<T, M, L> createParser();
 
+	Parser<T, M, L> getParser();
+	Verifier<T, M, L> setParser(AbstractParser<T, M, L> parser);
+
 	@NotNull
 	Visitor<T> getVisitor();
 	Verifier<T, M, L> setVisitor(@NotNull Visitor<T> visitor);
diff --git a/APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java b/APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java
index a3c51694a..374290989 100644
--- a/APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java
+++ b/APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/Visitor.java b/APIJSONORM/src/main/java/apijson/orm/Visitor.java
index f474bd91e..5d1b6063d 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Visitor.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Visitor.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/CommonException.java b/APIJSONORM/src/main/java/apijson/orm/exception/CommonException.java
index 565cef453..7e2884ef7 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/CommonException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/CommonException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
@@ -247,9 +247,15 @@ else if (config.isPresto()) {
         else if (config.isTrino()) {
           db = SQLConfig.DATABASE_TRINO + " " + dbVersion;
         }
+        else if (config.isDoris()) {
+          db = SQLConfig.DATABASE_DORIS + " " + dbVersion;
+        }
         else if (config.isSnowflake()) {
           db = SQLConfig.DATABASE_SNOWFLAKE + " " + dbVersion;
         }
+        else if (config.isDatabend()) {
+          db = SQLConfig.DATABASE_DATABEND + " " + dbVersion;
+        }
         else if (config.isDatabricks()) {
           db = SQLConfig.DATABASE_DATABRICKS + " " + dbVersion;
         }
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/ConditionErrorException.java b/APIJSONORM/src/main/java/apijson/orm/exception/ConditionErrorException.java
index fe2ccd761..44c43a29f 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/ConditionErrorException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/ConditionErrorException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/ConflictException.java b/APIJSONORM/src/main/java/apijson/orm/exception/ConflictException.java
index ee258eee9..a39d88d3b 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/ConflictException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/ConflictException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/NotExistException.java b/APIJSONORM/src/main/java/apijson/orm/exception/NotExistException.java
index 5c5a42bc8..69e34a809 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/NotExistException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/NotExistException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/NotLoggedInException.java b/APIJSONORM/src/main/java/apijson/orm/exception/NotLoggedInException.java
index 2fbbb89ba..1e16b5796 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/NotLoggedInException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/NotLoggedInException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/OutOfRangeException.java b/APIJSONORM/src/main/java/apijson/orm/exception/OutOfRangeException.java
index bde6fa42c..043ba5a65 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/OutOfRangeException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/OutOfRangeException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/UnsupportedDataTypeException.java b/APIJSONORM/src/main/java/apijson/orm/exception/UnsupportedDataTypeException.java
index e272141c9..1c7d7c27a 100644
--- a/APIJSONORM/src/main/java/apijson/orm/exception/UnsupportedDataTypeException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/UnsupportedDataTypeException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/package-info.java b/APIJSONORM/src/main/java/apijson/orm/exception/package-info.java
index 70d3bb96e..073c6bdac 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/package-info.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/package-info.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Access.java b/APIJSONORM/src/main/java/apijson/orm/model/Access.java
index e114f5654..ab44f8664 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/Access.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Access.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/AllColumn.java b/APIJSONORM/src/main/java/apijson/orm/model/AllColumn.java
index 90da2664e..02906c6ec 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/AllColumn.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/AllColumn.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/AllColumnComment.java b/APIJSONORM/src/main/java/apijson/orm/model/AllColumnComment.java
index fe98fa51d..81e2c9fe9 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/AllColumnComment.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/AllColumnComment.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/AllTable.java b/APIJSONORM/src/main/java/apijson/orm/model/AllTable.java
index 215fde316..2934ad0ba 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/AllTable.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/AllTable.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/AllTableComment.java b/APIJSONORM/src/main/java/apijson/orm/model/AllTableComment.java
index 5dd4b0a4d..49a4dee3a 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/AllTableComment.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/AllTableComment.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Column.java b/APIJSONORM/src/main/java/apijson/orm/model/Column.java
index d38d4fda3..573ab7fc4 100755
--- a/APIJSONORM/src/main/java/apijson/orm/model/Column.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Column.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Document.java b/APIJSONORM/src/main/java/apijson/orm/model/Document.java
index 6f2a8bba2..2e8db19c2 100755
--- a/APIJSONORM/src/main/java/apijson/orm/model/Document.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Document.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/ExtendedProperty.java b/APIJSONORM/src/main/java/apijson/orm/model/ExtendedProperty.java
index 81227eb13..393a7e0d1 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/ExtendedProperty.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/ExtendedProperty.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Function.java b/APIJSONORM/src/main/java/apijson/orm/model/Function.java
index b02175f4a..da6c3f53e 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/Function.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Function.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/PgAttribute.java b/APIJSONORM/src/main/java/apijson/orm/model/PgAttribute.java
index 7c85f9f42..dbd4b4b69 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/PgAttribute.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/PgAttribute.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/PgClass.java b/APIJSONORM/src/main/java/apijson/orm/model/PgClass.java
index 3a47b2791..199a7ef86 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/PgClass.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/PgClass.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Request.java b/APIJSONORM/src/main/java/apijson/orm/model/Request.java
index 8e83a2707..5d0d04092 100755
--- a/APIJSONORM/src/main/java/apijson/orm/model/Request.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Request.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Script.java b/APIJSONORM/src/main/java/apijson/orm/model/Script.java
index ddb608432..53cda4323 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/Script.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Script.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/SysColumn.java b/APIJSONORM/src/main/java/apijson/orm/model/SysColumn.java
index 3e2c5c2b0..a4d7ca881 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/SysColumn.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/SysColumn.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/SysTable.java b/APIJSONORM/src/main/java/apijson/orm/model/SysTable.java
index 221807c48..bb6142310 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/SysTable.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/SysTable.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Table.java b/APIJSONORM/src/main/java/apijson/orm/model/Table.java
index 0135fd947..1ab004cce 100755
--- a/APIJSONORM/src/main/java/apijson/orm/model/Table.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Table.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/TestRecord.java b/APIJSONORM/src/main/java/apijson/orm/model/TestRecord.java
index b1ceaa77c..32ad98f9e 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/TestRecord.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/TestRecord.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/package-info.java b/APIJSONORM/src/main/java/apijson/orm/model/package-info.java
index af556632a..a0b5641c9 100755
--- a/APIJSONORM/src/main/java/apijson/orm/model/package-info.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/package-info.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/package-info.java b/APIJSONORM/src/main/java/apijson/orm/package-info.java
index e0f9a3d51..76569c93d 100755
--- a/APIJSONORM/src/main/java/apijson/orm/package-info.java
+++ b/APIJSONORM/src/main/java/apijson/orm/package-info.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/APIJSONORM/src/main/java/apijson/orm/script/JSR223ScriptExecutor.java b/APIJSONORM/src/main/java/apijson/orm/script/JSR223ScriptExecutor.java
index 59dba0117..6a3a6c4f4 100644
--- a/APIJSONORM/src/main/java/apijson/orm/script/JSR223ScriptExecutor.java
+++ b/APIJSONORM/src/main/java/apijson/orm/script/JSR223ScriptExecutor.java
@@ -55,7 +55,7 @@ public Object execute(AbstractFunctionParser<T, M, L> parser, Map<String, Object
 		CompiledScript compiledScript = compiledScriptMap.get(methodName);
 		Bindings bindings = new SimpleBindings();
 		// 往脚本上下文里放入元数据
-		// 把 RequestMethod method, String tag, int version, @NotNull JSONObject request,
+		// 把 RequestMethod method, String tag, int version, @NotNull JSONMap request,
 		// HttpSession session 等参数作为全局参数传进去供脚本使用
 		
 		// 加载扩展属性
diff --git a/APIJSONORM/src/main/java/apijson/package-info.java b/APIJSONORM/src/main/java/apijson/package-info.java
index 42e240185..a4fcbeb21 100755
--- a/APIJSONORM/src/main/java/apijson/package-info.java
+++ b/APIJSONORM/src/main/java/apijson/package-info.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+/*Copyright (C) 2020 Tencent.  All rights reserved.
 
 This source code is licensed under the Apache License Version 2.0.*/
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 06596081b..f9fab2942 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -25,7 +25,7 @@
 - [403f](https://github.com/403f)
 - [gujiachun](https://github.com/gujiachun)
 - [gdjs2](https://github.com/gdjs2)(University of California, Riverside)
-- [Rkyzzy](https://github.com/Rkyzzy)(SUSTech, University of California, Berkeley)
+- [Rkyzzy](https://github.com/Rkyzzy)(理想汽车工程师, SUSTech, University of California, Berkeley)
 - [kxlv2000](https://github.com/kxlv2000)(SUSTech)
 - [caohao-go](https://github.com/caohao-go)(腾讯工程师，曾在华为、恒生担任C/C++开发工程师，在wps担任项目经理，在360担任技术专家)
 - [Wscats](https://github.com/Wscats)(腾讯工程师、腾讯 AlloyTeam 成员、Tencent Creation Camp 成员、知名技术博主)
@@ -33,10 +33,10 @@
 - [JieJo](https://github.com/JieJo)
 - [yeyuezhishou](https://github.com/yeyuezhishou)(圆通工程师)
 - [kenlig](https://github.com/kenlig)(还开源了 apijsondocs)
-- [andream7](https://github.com/andream7)(微软工程师，还开源了 apijson-db2)
+- [andream7](https://github.com/andream7)(字节跳动、微软 工程师，还开源了 apijson-db2)
 - [qiujunlin](https://github.com/qiujunlin)(字节跳动工程师，还开源了 APIJSONDemo)
 - [HANXU2018](https://github.com/HANXU2018)(网易工程师，还开源了 APIJSON-DOC)
-- [hclown9804](https://github.com/hclown9804)
+- [hclown9804](https://github.com/hclown9804)(Datawhale)
 - [chenyanlann](https://github.com/chenyanlann)(还开源了 APIJSONDemo_ClickHouse)
 - [haolingzhang1](https://github.com/haolingzhang1)(腾讯工程师，还开源了 APIJson--demo)
 - [jerrylususu](https://github.com/jerrylususu)(还开源了 apijson_todo_demo 和 apijson_role_extend)
@@ -57,13 +57,24 @@
 - [aninZz](https://github.com/aninZz)
 - [leomiaomiao](https://github.com/leomiaomiao)
 - [YqxLzx](https://github.com/YqxLzx)
-- [hiteshbedre](https://github.com/hiteshbedre)
+- [hiteshbedre](https://github.com/hiteshbedre)(privado.ai 印裔工程师)
 - [wahowaho](https://github.com/wahowaho)
 - [jarrodquan](https://github.com/jarrodquan)
 - [gemufeng](https://github.com/gemufeng)(上海麦市工程师)
 - [komiblog](https://github.com/komiblog)
 - [ostrichManX](https://github.com/ostrichManX)
 - [jia199807](https://github.com/jia199807)
+- [zxcwindy](https://github.com/zxcwindy)
+- [afumu](https://github.com/afumu)(gorm-plus 作者)
+- [alittle-yu](https://github.com/alittle-yu)
+- [Damon Nicola](https://github.com/Reynold3D)
+- [calmcc](https://github.com/calmcc)
+- [lindaifeng](https://github.com/lindaifeng)
+- [DenineLu](https://github.com/DenineLu)(小红书工程师）
+- [wz11wz](https://github.com/wz11wz)
+- [GeXin97](https://github.com/GeXin97)
+- [yunjiao-source](https://github.com/yunjiao-source)(还开源了 [apijson-spring-boot](https://gitee.com/yunjiao-source/apijson-spring-boot))
+- [moxixi527](https://github.com/moxixi527)(热门技术博主)
 
 #### 其中特别致谢: <br/>
 cloudAndMonkey 提交的 11 个 Commits, 对 APIJSON 做出了 1,496 增加和 845 处删减(截止 2022/12/15 日)； <br/>
diff --git a/Document-English.md b/Document-English.md
index c9a4f2948..62f40b0a0 100644
--- a/Document-English.md
+++ b/Document-English.md
@@ -324,7 +324,7 @@ Response:
  Fuzzy matching | `"key$":"SQL search expressions"`  =>  `"key$":["SQL search expressions"]`<br />Any SQL search expressions.Eg.%key%(include key), key%(start with key),%k%e%y%(include k, e, y). % means any characters. | ["name$":"%m%"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name$":"%2525m%2525"}}}) <br />In SQL, it's <br />`name LIKE '%m%'`, <br />meaning that get User with ‘m’ in name.
  Regular Expression| `"key~":"regular expression"`  =>  `"key~":["regular expression"]`<br />It can be any regular expressions.Eg. ^[0-9]+$ ，*~ not case sensitive, advanced search is applicable.| ["name~":"^[0-9]+$"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name~":"^[0-9]%252B$"}}}) <br />In SQL, it's <br />`name REGEXP '^[0-9]+$'`.
  Get data in a range| `"key%":"start,end"`  =>  `"key%":["start,end"]`<br />The data type of start and end can only be either Boolean, Number or String. Eg. "2017-01-01,2019-01-01" ，["1,90000", "82001,100000"]. It's used for getting data from a specific time range. | ["date%":"2017-10-01,2018-10-01"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"date%2525":"2017-10-01,2018-10-01"}}}) <br />In SQL, it's <br />`date BETWEEN '2017-10-01' AND '2018-10-01'`, <br />meaning to get User data that registered between 2017-10-01 and 2018-10-01.
- Make an alias | `"name:alias"`<br />this changes name to alias in returning results. It’s applicable to column, tableName, SQL Functions, etc. but only in GET, HEAD requests. | ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}}) <br />In SQL, it's <br />`toId AS parentId`. <br />It'll return `parentId` instead of `toId`.
+ Make an alias | `"name:alias"`<br />this changes name to alias in returning results. It’s applicable to column, tableName, SQL Functions, etc. but only in GET, HEAD requests. | ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}}) <br />In SQL, it's <br />`toId AS parentId`. <br />It'll return `parentId` instead of `toId`.<br /><br />For @key format like "lc_wai6b3vk2:(lc_wai6b3vk)", it means renaming field lc_wai6b3vk2 to lc_wai6b3vk, commonly used for field renaming scenarios. Example:<br />{<br />&nbsp;&nbsp;"lc_sinan_ba074fbb": {<br />&nbsp;&nbsp;&nbsp;&nbsp;"lc_wai6b3vk": "11",<br />&nbsp;&nbsp;&nbsp;&nbsp;"lc_wai6b3vk2": "22",<br />&nbsp;&nbsp;&nbsp;&nbsp;"@combine": "lc_wai6b3vk \\| lc_wai6b3vk2",<br />&nbsp;&nbsp;&nbsp;&nbsp;"@key": "lc_wai6b3vk2:(lc_wai6b3vk)"<br />&nbsp;&nbsp;}<br />}<br />corresponds to SQL `(lc_wai6b3vk = '11' OR lc_wai6b3vk2 = '22')`, but the lc_wai6b3vk2 field will be renamed and displayed as lc_wai6b3vk in the returned result
  Add / expand an item | `"key+":Object` <br /> The type of Object is decided by *key*. Types can be Number, String, JSONArray. Froms are 82001,"apijson",["url0","url1"] respectively. It’s only applicable to PUT request.| "praiseUserIdList+":[82001]. In SQL, it's <br />`json_insert(praiseUserIdList,82001)`. <br />Add an *id* that praised the Moment.
  Delete / decrease an item | `"Key-":Object`<br /> It’s the contrary of "key+" | "balance-":100.00. In SQL, it's <br />`balance = balance - 100.00`, <br />meaning there's 100 less in balance.
  Operations | &, \|, ! <br /> They're used in logic operations. It’s the same as AND, OR, NOT in SQL respectively. <br />By default, for the same key, it’s ‘\|’ (OR)operation among conditions; for different keys, the default operation among conditions is ‘&’(AND). <br /> |  ① ["id&{}":">80000,<=90000"](http://apijson.cn:8080/head/{"User":{"id&{}":">80000,<=90000"}}) <br />In SQL, it's <br />`id>80000 AND id<=90000`, <br />meaning *id* needs to be id>80000 & id<=90000<br /><br /> ② ["id\|{}":">90000,<=80000"](http://apijson.cn:8080/head/{"User":{"id\|{}":">90000,<=80000"}}) <br />It's the same as "id{}":">90000,<=80000". <br />In SQL, it's <br />`id>80000 OR id<=90000`, <br />meaning that *id* needs to be id>90000 \| id<=80000<br /><br /> ③ ["id!{}":[82001,38710]](http://apijson.cn:8080/head/{"User":{"id!{}":[82001,38710]}}) <br />In SQL, it's <br />`id NOT IN(82001,38710)`, <br />meaning id needs to be ! (id=82001 \| id=38710).
diff --git a/Document.md b/Document.md
index a97f7b823..11db6fe86 100644
--- a/Document.md
+++ b/Document.md
@@ -408,19 +408,19 @@ DELETE: <br > 删除数据 | base_url/delete/ | {<br > &nbsp;&nbsp; TableName:{<
  匹配条件范围 | "key{}":"条件0,条件1..."，条件为 SQL 表达式字符串，可进行数字比较运算等 | ["id{}":"<=80000,\>90000"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"id{}":"<=80000,\>90000"}}})，对应 SQL 是`id<=80000 OR id>90000`，查询 id 符合 id\<=80000 \| id>90000 的一个 User 数组
  包含选项范围 | "key<\>":value  =>  "key<\>":[value]，key 对应值的类型必须为 JSONArray，value 值类型只能为 Boolean, Number, String 中的一种 |  ["contactIdList<\>":38710](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"contactIdList<\>":38710}}})，对应SQL是`json_contains(contactIdList,38710)`，查询 contactIdList 包含 38710 的一个 User 数组
  判断是否存在 | "key}{@":{<br /> &nbsp;&nbsp; "from":"Table",<br /> &nbsp;&nbsp; "Table":{ ... }<br />}<br />其中：<br />}{ 表示 EXISTS；<br /> key 用来标识是哪个判断；<br /> @ 后面是 子查询 对象，具体见下方 子查询 的说明。 | ["id}{@":{<br /> &nbsp;&nbsp; "from":"Comment",<br /> &nbsp;&nbsp; "Comment":{<br /> &nbsp;&nbsp;  &nbsp;&nbsp; "momentId":15 <br /> &nbsp;&nbsp; }<br />}](http://apijson.cn:8080/get/{"User":{"id}{@":{"from":"Comment","Comment":{"momentId":15}}}})<br /> WHERE EXISTS(SELECT * FROM Comment WHERE momentId=15)
- 远程调用函数 | "key()":"函数表达式"，函数表达式为 function(key0,key1...)，会调用后端对应的函数 function(JSONObject request, String key0, String key1...)，实现 参数校验、数值计算、数据同步、消息推送、字段拼接、结构变换 等特定的业务逻辑处理，<br>可使用 - 和 + 表示优先级，解析 key-() > 解析当前对象 > 解析 key() > 解析子对象 > 解析 key+()  | ["isPraised()":"isContain(praiseUserIdList,userId)"](http://apijson.cn:8080/get/{"Moment":{"id":301,"isPraised()":"isContain(praiseUserIdList,userId)"}})，会调用远程函数 [boolean isContain(JSONObject request, String array, String value)](https://github.com/APIJSON/apijson-framework/blob/master/src/main/java/apijson/framework/APIJSONFunctionParser.java#L361-L374) ，然后变为 "isPraised":true 这种（假设点赞用户 id 列表包含了 userId，即这个 User 点了赞）
- 存储过程 | "@key()":"SQL函数表达式"，函数表达式为 <br />  function(key0,key1...) <br /> 会调用后端数据库对应的存储过程 SQL 函数 <br /> function(String key0, String key1...) <br /> 除了参数会提前赋值，其它和 远程函数 一致 | ["@limit":10, <br /> "@offset":0, <br /> "@procedure()":"getCommentByUserId(id,@limit,@offset)"](http://apijson.cn:8080/get/{"User":{"@limit":10,"@offset":0,"@procedure()":"getCommentByUserId(id,@limit,@offset)"}}) <br /> 会转为 <br /> `getCommentByUserId(38710,10,0)` <br /> 来调用存储过程 SQL 函数 <br /> `getCommentByUserId(IN id bigint, IN limit int, IN offset int)` <br /> 然后变为 <br />"procedure":{<br /> &nbsp;&nbsp; "count":-1, <br /> &nbsp;&nbsp; "update":false, <br /> &nbsp;&nbsp; "list":[] <br /> } <br /> 其中 count 是指写操作影响记录行数，-1 表示不是写操作；update 是指是否为写操作（增删改）；list 为返回结果集
- 引用赋值 | "key@":"key0/key1/.../refKey"，引用路径为用 / 分隔的字符串。以 / 开头的是缺省引用路径，从声明 key 所处容器的父容器路径开始；其它是完整引用路径，从最外层开始。<br /> 被引用的 refKey 必须在声明 key 的上面。如果对 refKey 的容器指定了返回字段，则被引用的 refKey 必须写在 @column 对应的值内，例如 "@column":"refKey,key1,..." | ["Moment":{<br /> &nbsp;&nbsp; "userId":38710<br />},<br />"User":{<br /> &nbsp;&nbsp; "id@":"/Moment/userId"<br />}](http://apijson.cn:8080/get/{"Moment":{"userId":38710},"User":{"id@":"%252FMoment%252FuserId"}})<br /> User 内的 id 引用了与 User 同级的 Moment 内的 userId，<br />即 User.id = Moment.userId，请求完成后<br > "id@":"/Moment/userId" 会变成 "id":38710
- 子查询 | "key@":{<br /> &nbsp;&nbsp; "range":"ALL", <br /> &nbsp;&nbsp; "from":"Table", // 可省略，默认为首个表对象 key 名<br /> &nbsp;&nbsp; "Table":{ ... }<br />}<br />其中：<br />range 可为 ALL,ANY；<br />from 为目标表 Table 的名称；<br />@ 后面的对象类似数组对象，可使用 count 和 join 等功能。 | ["id@":{<br /> &nbsp;&nbsp; "from":"Comment", // 可省略<br /> &nbsp;&nbsp; "Comment":{<br /> &nbsp;&nbsp;  &nbsp;&nbsp; "@column":"min(userId)" <br /> &nbsp;&nbsp; }<br />}](http://apijson.cn:8080/get/{"User":{"id@":{"from":"Comment","Comment":{"@column":"min(userId)"}}}})<br /> WHERE id=(SELECT min(userId) FROM Comment)
- 模糊搜索 | `"key$":"SQL搜索表达式"` => `"key$":["SQL搜索表达式"]`，任意 SQL 搜索表达式字符串，如 %key%(包含 key), key%(以 key 开始), %k%e%y%(包含字母 k,e,y) 等，% 表示任意字符 | ["name$":"%m%"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name$":"%2525m%2525"}}})，对应 SQL 是`name LIKE '%m%'`，查询 name 包含 "m" 的一个 User 数组
- 正则匹配 | "key~":"正则表达式" => "key~":["正则表达式"]，任意正则表达式字符串，如 ^[0-9]+$ ，*~ 忽略大小写，可用于高级搜索 | ["name~":"^[0-9]+$"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name~":"^[0-9]%252B$"}}})，对应 SQL 是`name REGEXP '^[0-9]+$'`，查询 name 中字符全为数字的一个 User 数组
- 连续范围 | "key%":"start,end" => "key%":["start,end"]，其中 start 和 end 都只能为 Number, String 中的一种，如 "2017-01-01,2019-01-01" ，["1,90000", "82001,100000"] ，可用于连续范围内的筛选 | ["date%":"2017-10-01,2018-10-01"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"date%2525":"2017-10-01,2018-10-01"}}})，对应SQL是`date BETWEEN '2017-10-01' AND '2018-10-01'`，查询在2017-10-01和2018-10-01期间注册的用户的一个User数组
- 新建别名 | "name:alias"，name 映射为 alias，用 alias 替代 name。可用于 column,Table,SQL 函数 等。只用于 GET 类型、HEAD 类型的请求 | ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}})，对应 SQL 是`toId AS parentId`，将查询的字段 toId 变为 parentId 返回
- 增加 或 扩展 | "key+":Object，Object的类型由key指定，且类型为 Number,String,JSONArray 中的一种。如 82001,"apijson",["url0","url1"] 等。只用于 PUT 请求 | "praiseUserIdList+":[82001]，对应 SQL 是`json_insert(praiseUserIdList,82001)`，添加一个点赞用户 id，即这个用户点了赞
+ 远程调用函数 | "key()":"函数表达式"，函数表达式为 function(key0,key1...)，会调用后端对应的函数 function(JSONObject request, String key0, String key1...)，实现 参数校验、数值计算、数据同步、消息推送、字段拼接、结构变换 等特定的业务逻辑处理，<br>可使用 - 和 + 表示优先级，解析 key-() > 解析当前对象 > 解析 key() > 解析子对象 > 解析 key+()  | ["isPraised()":"isContain(praiseUserIdList,userId)"](http://apijson.cn:8080/get/{"Moment":{"id":301,"isPraised()":"isContain(praiseUserIdList,userId)"}})，会调用远程函数 [boolean isContain(JSONObject request, String array, String value)](https://github.com/APIJSON/apijson-framework/blob/master/src/main/java/apijson/framework/APIJSONFunctionParser.java#L361-L374) ，然后变为 "isPraised":true 这种（假设点赞用户id列表包含了userId，即这个User点了赞）
+ 存储过程 | "@key()":"SQL函数表达式"，函数表达式为 <br />  function(key0,key1...) <br /> 会调用后端数据库对应的存储过程 SQL函数 <br /> function(String key0, String key1...) <br /> 除了参数会提前赋值，其它和 远程函数 一致 | ["@limit":10, <br /> "@offset":0, <br /> "@procedure()":"getCommentByUserId(id,@limit,@offset)"](http://apijson.cn:8080/get/{"User":{"@limit":10,"@offset":0,"@procedure()":"getCommentByUserId(id,@limit,@offset)"}}) <br /> 会转为 <br /> `getCommentByUserId(38710,10,0)` <br /> 来调用存储过程 SQL 函数 <br /> `getCommentByUserId(IN id bigint, IN limit int, IN offset int)` <br /> 然后变为 <br />"procedure":{<br /> &nbsp;&nbsp; "count":-1, <br /> &nbsp;&nbsp; "update":false, <br /> &nbsp;&nbsp; "list":[] <br /> } <br /> 其中 count 是指写操作影响记录行数，-1 表示不是写操作；update 是指是否为写操作（增删改）；list 为返回结果集
+ 引用赋值 | "key@":"key0/key1/.../refKey"，引用路径为用/分隔的字符串。以/开头的是缺省引用路径，从声明key所处容器的父容器路径开始；其它是完整引用路径，从最外层开始。<br /> 被引用的refKey必须在声明key的上面。如果对refKey的容器指定了返回字段，则被引用的refKey必须写在@column对应的值内，例如 "@column":"refKey,key1,..." | ["Moment":{<br /> &nbsp;&nbsp; "userId":38710<br />},<br />"User":{<br /> &nbsp;&nbsp; "id@":"/Moment/userId"<br />}](http://apijson.cn:8080/get/{"Moment":{"userId":38710},"User":{"id@":"%252FMoment%252FuserId"}})<br /> User内的id引用了与User同级的Moment内的userId，<br />即User.id = Moment.userId，请求完成后<br > "id@":"/Moment/userId" 会变成 "id":38710
+ 子查询 | "key@":{<br /> &nbsp;&nbsp; "range":"ALL", <br /> &nbsp;&nbsp; "from":"Table",<br /> &nbsp;&nbsp; "Table":{ ... }<br />}<br />其中：<br />range 可为 ALL,ANY；<br />from 为目标表 Table 的名称；<br />@ 后面的对象类似数组对象，可使用 count 和 join 等功能。 | ["id@":{<br /> &nbsp;&nbsp; "from":"Comment",<br /> &nbsp;&nbsp; "Comment":{<br /> &nbsp;&nbsp;  &nbsp;&nbsp; "@column":"min(userId)" <br /> &nbsp;&nbsp; }<br />}](http://apijson.cn:8080/get/{"User":{"id@":{"from":"Comment","Comment":{"@column":"min(userId)"}}}})<br /> WHERE id=(SELECT min(userId) FROM Comment)
+ 模糊搜索 | `"key$":"SQL搜索表达式"`  =>  `"key$":["SQL搜索表达式"]`，任意SQL搜索表达式字符串，如 %key%(包含key), key%(以key开始), %k%e%y%(包含字母k,e,y) 等，%表示任意字符 | ["name$":"%m%"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name$":"%2525m%2525"}}})，对应SQL是`name LIKE '%m%'`，查询name包含"m"的一个User数组
+ 正则匹配 | "key~":"正则表达式"  =>  "key~":["正则表达式"]，任意正则表达式字符串，如 ^[0-9]+$ ，*~ 忽略大小写，可用于高级搜索 | ["name~":"^[0-9]+$"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name~":"^[0-9]%252B$"}}})，对应SQL是`name REGEXP '^[0-9]+$'`，查询name中字符全为数字的一个User数组
+ 连续范围 | "key%":"start,end"  =>  "key%":["start,end"]，其中 start 和 end 都只能为 Boolean, Number, String 中的一种，如 "2017-01-01,2019-01-01" ，["1,90000", "82001,100000"] ，可用于连续范围内的筛选 | ["date%":"2017-10-01,2018-10-01"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"date%2525":"2017-10-01,2018-10-01"}}})，对应SQL是`date BETWEEN '2017-10-01' AND '2018-10-01'`，查询在2017-10-01和2018-10-01期间注册的用户的一个User数组
+ 新建别名 | ① "name:alias"，name 映射为 alias，用 alias 替代 name，可用于 column,Table,SQL 函数 等，只用于 GET 类型、HEAD 类型的请求 <br /><br />② 函数调用映射<br />"@key": "fun:avg(id);keyA:(keyB)",<br />"fun>": 1,<br />"keyA": 1<br />其中 fun:fun(arg) 把 SQL 函数调用 fun(arg) 作为左侧表达式替代 fun，即 fun(arg) > 1；<br />keyA:(keyB) 表示将字段 keyA 重命名为 keyB，即实际 SQL 中为 keyB = 1，常用于重命名冲突的多条件同名字段。 | ① ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}})，对应 SQL 是 `toId AS parentId`，将查询的字段 toId 变为 parentId 返回<br /><br />② ["@key": "len:length(content);mid:(momentId)",<br />"len<=": 10,<br />"mid": 12,<br />"momentId": 15,<br />"@combine": "(len<= \\| mid) & momentId"](http://apijson.cn/api?type=JSON&json={%22Comment%22:{%22@key%22:%22len%3Alength(content)%3Bmid%3A(momentId)%22,%22len%3C=%22:10,%22mid%22:12,%22momentId%22:15,%22@combine%22:%22(len%3C%3D%20%7C%20mid)%20%26%20momentId%22}})<br />对应 SQL 是 `(length(content) <= 10 OR momentId = 12) AND momentId = 15`
+ 增加 或 扩展 | "key+":Object，Object的类型由key指定，且类型为Number,String,JSONArray中的一种。如 82001,"apijson",["url0","url1"] 等。只用于PUT请求 | "praiseUserIdList+":[82001]，对应SQL是`json_insert(praiseUserIdList,82001)`，添加一个点赞用户id，即这个用户点了赞
  减少 或 去除 | "key-":Object，与"key+"相反 | "balance-":100.00，对应SQL是`balance = balance - 100.00`，余额减少100.00，即花费了100元
  比较运算 | >, <, >=, <= 比较运算符，用于 <br />① 提供 "id{}":"<=90000" 这种条件范围的简化写法 <br /><br />② 实现子查询相关比较运算<br /><br />不支持 "key=":Object 和 "key!=":Object 这两种写法，直接用更简单的 "key":Object 和 "key!":Object 替代。 |  ① ["id<=":90000](http://apijson.cn:8080/get/{"[]":{"User":{"id<=":90000}}})，对应 SQL 是`id<=90000`，查询符合id<=90000的一个User数组<br /><br /> ② ["id>@":{<br /> &nbsp;&nbsp; "from":"Comment",<br /> &nbsp;&nbsp; "Comment":{<br /> &nbsp;&nbsp;  &nbsp;&nbsp; "@column":"min(userId)" <br /> &nbsp;&nbsp; }<br />}](http://apijson.cn:8080/get/{"User":{"id>@":{"from":"Comment","Comment":{"@column":"min(userId)"}}}})<br /> WHERE id>(SELECT min(userId) FROM Comment)
  逻辑运算 | &, \|, ! 逻辑运算符，对应数据库 SQL 中的 AND, OR, NOT。 <br />横或纵与：同一键值对的值内条件默认 \| 或连接，可以在 key 后加逻辑运算符来具体指定；不同键值对的条件默认 & 与连接，可以用下面说明的对象关键词 @combine 来具体指定。 <br /><br />① & 可用于 "key&{}":"条件"等<br /><br />② \| 可用于 "key\|{}":"条件", "key\|{}":[]等，一般可省略<br /><br />③ ! 可单独使用，如 "key!":Object，也可像 &,\| 一样配合其他功能符使用 <br /> "key!":null 无效，null 值会导致整个键值对被忽略解析，可以用 "key{}":"!=null" 替代，<br />"key":null 同理，用 "key{}":"=null" 替代。 |  ① ["id&{}":">80000,<=90000"](http://apijson.cn:8080/head/{"User":{"id&{}":">80000,<=90000"}})，对应SQL是`id>80000 AND id<=90000`，即id满足id>80000 & id<=90000<br /><br /> ② ["id\|{}":">90000,<=80000"](http://apijson.cn:8080/head/{"User":{"id\|{}":">90000,<=80000"}})，同 "id{}":">90000,<=80000"，对应 SQL 是`id>90000 OR id<=80000`，即 id 满足 id>90000 \| id<=80000<br /><br /> ③ ["id!{}":[82001,38710]](http://apijson.cn:8080/head/{"User":{"id!{}":[82001,38710]}})，对应 SQL 是`id NOT IN(82001,38710)`，即 id 满足 ! (id=82001 \| id=38710)，可过滤黑名单的消息
- 数组关键词，可自定义 | "key":Object，key为 "[]":{} 中 {} 内的关键词，Object 的类型由 key 指定<br /><br />① "count":5，查询数量，0 表示最大值，默认值为 10，默认最大值为 100 <br /><br />② "page":1，查询页码，从 0 开始，默认值为 0，默认最大值为 100，一般和 count 一起用<br /><br />③ "query":2，查询内容<br />0-对象，1-总数和分页详情，2-数据、总数和分页详情<br />总数关键词为 total，分页详情关键词为 info，<br /> 它们都和 query 同级，通过引用赋值得到自定义 key:value 键值对，不传则返回默认键值对，例如  <br />"total@":"/[]/total", "info@":"/[]/info" <br />这里query及total仅为GET类型的请求提供方便，<br /> 一般可直接用HEAD类型的请求获取总数<br /><br />④ "join":"&/Table0,\</Table1/key1@" 或 <br />"join":{<br /> &nbsp;&nbsp; "&/Table0":{},  // 支持 ON 多个字段关联,<br /> &nbsp;&nbsp; "\</Table1/key1@":{  // ON 只允许指定的 key1 关联<br /> &nbsp;&nbsp;&nbsp;&nbsp; "key0":value0, // 其它ON条件 <br /> &nbsp;&nbsp;&nbsp;&nbsp; "key2":value2,<br /> &nbsp;&nbsp;&nbsp;&nbsp; ... <br /> &nbsp;&nbsp;&nbsp;&nbsp; "@combine":"...", // 其它ON条件的组合方式 <br /> &nbsp;&nbsp;&nbsp;&nbsp; "@column":"...", // 外层 SELECT <br /> &nbsp;&nbsp;&nbsp;&nbsp; "@group":"...", // 外层 GROUP BY <br /> &nbsp;&nbsp;&nbsp;&nbsp; "@having":"..." // 外层 HAVING <br /> &nbsp;&nbsp; }<br />}<br />多表连接方式：<br />  "@" - APP JOIN <br /> "\<" - LEFT JOIN <br /> ">" - RIGHT JOIN <br /> "&" - INNER JOIN <br /> "\|" - FULL JOIN <br />  "!" - OUTER JOIN <br />  "*" - CROSS JOIN <br />  "^" - SIDE JOIN <br />  "(" - ANTI JOIN <br />  ")" - FOREIGN JOIN <br />其中 @ APP JOIN 为应用层连表，会从已查出的主表里取得所有副表 key@ 关联的主表内的 refKey 作为一个数组 refKeys: [value0, value1...]，然后把原来副表 count 次查询 key=$refKey 的 SQL 用 key IN($refKeys) 的方式合并为一条 SQL 来优化性能；<br /> 其它 JOIN 都是 SQL JOIN，具体功能和 MySQL,PostgreSQL 等数据库的 JOIN 一一对应 <br />`"join":"</ViceTable/key@",`<br />`"MainTable":{},`<br />`"ViceTable":{"key@":"/MainTable/refKey"}`<br />会对应生成 <br />`MainTable LEFT JOIN ViceTable` <br />`ON ViceTable.key=MainTable.refKey` AND 其它ON条件 <br /> 除了 = 等价关联，也支持 ! 不等关联、\> \< \>= \<= 等比较关联和 $ ~ {} <> 等其它复杂关联方式 <br /><br />⑤ "otherKey":Object，自定义关键词，名称和以上系统关键词不一样，且原样返回上传的值  | ① 查询User数组，最多5个：<br />["count":5](http://apijson.cn:8080/get/{"[]":{"count":5,"User":{}}})<br />对应 SQL 是`LIMIT 5` <br /><br /> ② 查询第3页的User数组，每页5个：<br />["count":5,<br />"page":3](http://apijson.cn:8080/get/{"[]":{"count":5,"page":3,"User":{}}})<br />对应 SQL 是`LIMIT 5 OFFSET 15` <br /><br /> ③ 查询User数组和对应的User总数：<br />["[]":{<br /> &nbsp;&nbsp; "query":2,<br /> &nbsp;&nbsp; "User":{}<br />},<br />"total@":"/[]/total", // 可省略<br />"info@":"/[]/info" // 可省略](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}},"total@":"%252F[]%252Ftotal","info@":"%252F[]%252Finfo"})<br /> 返回的数据中，总数及分页详情结构为： <br />  "total":139, // 总数 <br /> "info":{ // 分页详情 <br /> &nbsp;&nbsp; "total":139, // 总数 <br /> &nbsp;&nbsp; "count":5, // 每页数量 <br /> &nbsp;&nbsp; "page":0, // 当前页码 <br /> &nbsp;&nbsp; "max":27, // 最大页码 <br /> &nbsp;&nbsp; "more":true, // 是否还有更多 <br /> &nbsp;&nbsp; "first":true, // 是否为首页 <br /> &nbsp;&nbsp; "last":false // 是否为尾页 <br />} <br /><br /> ④ Moment INNER JOIN User LEFT JOIN Comment：<br />["[]":{<br /> &nbsp;&nbsp; "join":"&/User/id@,\</Comment",<br /> &nbsp;&nbsp; "Moment":{<br />&nbsp;&nbsp;&nbsp;&nbsp; "@group":"id" // 主副表不是一对一，要去除重复数据<br />&nbsp;&nbsp; },<br /> &nbsp;&nbsp; "User":{<br /> &nbsp;&nbsp;&nbsp;&nbsp; "name~":"t",<br /> &nbsp;&nbsp;&nbsp;&nbsp; "id@":"/Moment/userId"<br /> &nbsp;&nbsp; },<br /> &nbsp;&nbsp; "Comment":{<br /> &nbsp;&nbsp;&nbsp;&nbsp; "momentId@":"/Moment/id"<br /> &nbsp;&nbsp; }<br />}](http://apijson.cn/api/?type=JSON&url=http://apijson.cn:8080/get&json=%7B%22%5B%5D%22:%7B%22count%22:5,%22join%22:%22%26%2FUser%2Fid@,%3C%2FComment%22,%22Moment%22:%7B%22@column%22:%22id,userId,content%22,%22@group%22:%22id%22%7D,%22User%22:%7B%22name~%22:%22t%22,%22id@%22:%22%2FMoment%2FuserId%22,%22@column%22:%22id,name,head%22%7D,%22Comment%22:%7B%22momentId@%22:%22%2FMoment%2Fid%22,%22@column%22:%22id,momentId,content%22%7D%7D%7D)<br /><br /> ⑤ 每一层都加当前用户名：<br />["User":{},<br />"[]":{<br /> &nbsp;&nbsp; "name@":"User/name", // 自定义关键词<br /> &nbsp;&nbsp; "Moment":{}<br />}](http://apijson.cn:8080/get/{"User":{},"[]":{"name@":"User%252Fname","Moment":{}}})
+ 数组关键词，可自定义 | "key":Object，key为 "[]":{} 中 {} 内的关键词，Object 的类型由 key 指定<br /><br />① "count":5，查询数量，0 表示最大值，默认值为 10，默认最大值为 100 <br /><br />② "page":1，查询页码，从 0 开始，默认值为 0，默认最大值为 100，一般和 count 一起用<br /><br />③ "query":2，查询内容<br />0-对象，1-总数和分页详情，2-数据、总数和分页详情<br />总数关键词为 total，分页详情关键词为 info，<br /> 它们都和 query 同级，通过引用赋值得到自定义 key:value 键值对，不传则返回默认键值对，例如  <br />"total@":"/[]/total", "info@":"/[]/info" <br />这里query及total仅为GET类型的请求提供方便，<br /> 一般可直接用HEAD类型的请求获取总数<br /><br />④ "compat": true <br />处理最外层查询字段有特殊处理的情况下 "query":2 返回查询总数不准确的问题：如DISTINCT去重、Aggregate 函数等<br /><br />⑤ "join":"&/Table0,\</Table1/key1@" 或 <br />"join":{<br /> &nbsp;&nbsp; "&/Table0":{},  // 支持 ON 多个字段关联,<br /> &nbsp;&nbsp; "\</Table1/key1@":{  // ON 只允许指定的 key1 关联<br /> &nbsp;&nbsp;&nbsp;&nbsp; "key0":value0, // 其它ON条件 <br /> &nbsp;&nbsp;&nbsp;&nbsp; "key2":value2,<br /> &nbsp;&nbsp;&nbsp;&nbsp; ... <br /> &nbsp;&nbsp;&nbsp;&nbsp; "@combine":"...", // 其它ON条件的组合方式 <br /> &nbsp;&nbsp;&nbsp;&nbsp; "@column":"...", // 外层 SELECT <br /> &nbsp;&nbsp;&nbsp;&nbsp; "@group":"...", // 外层 GROUP BY <br /> &nbsp;&nbsp;&nbsp;&nbsp; "@having":"..." // 外层 HAVING <br /> &nbsp;&nbsp; }<br />}<br />多表连接方式：<br />  "@" - APP JOIN <br /> "\<" - LEFT JOIN <br /> ">" - RIGHT JOIN <br /> "&" - INNER JOIN <br /> "\|" - FULL JOIN <br />  "!" - OUTER JOIN <br />  "*" - CROSS JOIN <br />  "^" - SIDE JOIN <br />  "(" - ANTI JOIN <br />  ")" - FOREIGN JOIN <br />其中 @ APP JOIN 为应用层连表，会从已查出的主表里取得所有副表 key@ 关联的主表内的 refKey 作为一个数组 refKeys: [value0, value1...]，然后把原来副表 count 次查询 key=$refKey 的 SQL 用 key IN($refKeys) 的方式合并为一条 SQL 来优化性能；<br /> 其它 JOIN 都是 SQL JOIN，具体功能和 MySQL,PostgreSQL 等数据库的 JOIN 一一对应 <br />`"join":"</ViceTable/key@",`<br />`"MainTable":{},`<br />`"ViceTable":{"key@":"/MainTable/refKey"}`<br />会对应生成 <br />`MainTable LEFT JOIN ViceTable` <br />`ON ViceTable.key=MainTable.refKey` AND 其它ON条件 <br /> 除了 = 等价关联，也支持 ! 不等关联、\> \< \>= \<= 等比较关联和 $ ~ {} <> 等其它复杂关联方式 <br /><br />⑥ "otherKey":Object，自定义关键词，名称和以上系统关键词不一样，且原样返回上传的值  | ① 查询User数组，最多5个：<br />["count":5](http://apijson.cn:8080/get/{"[]":{"count":5,"User":{}}})<br />对应 SQL 是`LIMIT 5` <br /><br /> ② 查询第3页的User数组，每页5个：<br />["count":5,<br />"page":3](http://apijson.cn:8080/get/{"[]":{"count":5,"page":3,"User":{}}})<br />对应 SQL 是`LIMIT 5 OFFSET 15` <br /><br /> ③ 查询User数组和对应的User总数：<br />["[]":{<br /> &nbsp;&nbsp; "query":2,<br /> &nbsp;&nbsp; "User":{}<br />},<br />"total@":"/[]/total", // 可省略<br />"info@":"/[]/info" // 可省略](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}},"total@":"%252F[]%252Ftotal","info@":"%252F[]%252Finfo"})<br /> 返回的数据中，总数及分页详情结构为： <br />  "total":139, // 总数 <br /> "info":{ // 分页详情 <br /> &nbsp;&nbsp; "total":139, // 总数 <br /> &nbsp;&nbsp; "count":5, // 每页数量 <br /> &nbsp;&nbsp; "page":0, // 当前页码 <br /> &nbsp;&nbsp; "max":27, // 最大页码 <br /> &nbsp;&nbsp; "more":true, // 是否还有更多 <br /> &nbsp;&nbsp; "first":true, // 是否为首页 <br /> &nbsp;&nbsp; "last":false // 是否为尾页 <br />} <br /><br /> ④查询User数组ID唯一情况下的User总数：<br />["[]":{<br /> &nbsp;&nbsp; "query":2,<br /> &nbsp;&nbsp; "compat":"true",<br /> &nbsp;&nbsp; "User":{<br /> &nbsp;&nbsp;&nbsp;&nbsp; "@column":"DISTINCT id" <br /> &nbsp;&nbsp; }<br />}](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}}})<br /> 返回的数据和结构同上 <br /><br /> ⑤ Moment INNER JOIN User LEFT JOIN Comment：<br />["[]":{<br /> &nbsp;&nbsp; "join":"&/User/id@,\</Comment",<br /> &nbsp;&nbsp; "Moment":{<br />&nbsp;&nbsp;&nbsp;&nbsp; "@group":"id" // 主副表不是一对一，要去除重复数据<br />&nbsp;&nbsp; },<br /> &nbsp;&nbsp; "User":{<br /> &nbsp;&nbsp;&nbsp;&nbsp; "name~":"t",<br /> &nbsp;&nbsp;&nbsp;&nbsp; "id@":"/Moment/userId"<br /> &nbsp;&nbsp; },<br /> &nbsp;&nbsp; "Comment":{<br /> &nbsp;&nbsp;&nbsp;&nbsp; "momentId@":"/Moment/id"<br /> &nbsp;&nbsp; }<br />}](http://apijson.cn/api/?type=JSON&url=http://apijson.cn:8080/get&json=%7B%22%5B%5D%22:%7B%22count%22:5,%22join%22:%22%26%2FUser%2Fid@,%3C%2FComment%22,%22Moment%22:%7B%22@column%22:%22id,userId,content%22,%22@group%22:%22id%22%7D,%22User%22:%7B%22name~%22:%22t%22,%22id@%22:%22%2FMoment%2FuserId%22,%22@column%22:%22id,name,head%22%7D,%22Comment%22:%7B%22momentId@%22:%22%2FMoment%2Fid%22,%22@column%22:%22id,momentId,content%22%7D%7D%7D)<br /><br /> ⑥ 每一层都加当前用户名：<br />["User":{},<br />"[]":{<br /> &nbsp;&nbsp; "name@":"User/name", // 自定义关键词<br /> &nbsp;&nbsp; "Moment":{}<br />}](http://apijson.cn:8080/get/{"User":{},"[]":{"name@":"User%252Fname","Moment":{}}})
  对象关键词，可自定义 | "@key":Object，@key 为 Table:{} 中 {} 内的关键词，Object 的类型由 @key 指定<br /><br />① "@combine":"key0 \| (key1 & (key2 \| !key3))..."，条件组合方式，最终按 <br /> (其它key条件 AND 连接) AND (key0条件 OR (key1条件 AND (key2条件 OR (NOT key3条件)))) <br />这种方式连接，其中 "其它key" 是指与 @combine 在同一对象，且未被它声明的条件 key，默认都是 & 连接。注意不要缺少或多余任何一个空格。 <br /><br />② "@column":"column;function(arg)..."，返回字段<br /><br />③ "@order":"column0+,column1-..."，排序方式<br /><br />④ "@group":"column0,column1..."，分组方式。如果 @column 里声明了 Table 的 id，则 id 也必须在 @group 中声明；其它情况下必须满足至少一个条件:<br />1.分组的 key 在 @column 里声明<br />2.Table 主键在 @group 中声明 <br /><br />⑤ "@having":"function0(...)?value0;function1(...)?value1;function2(...)?value2..." // OR 连接，或 <br />"@having&":"function0(...)?value0;function1(...)?value1;function2(...)?value2..." // AND 连接，或 <br />"@having":{<br />&nbsp;&nbsp; "h0":"function0(...)?value0",<br />&nbsp;&nbsp; "h1":function1(...)?value1",<br />&nbsp;&nbsp; "h2":function2(...)?value2...",<br />&nbsp;&nbsp; "@combine":"h0 & (h1 \| !h2)"  // 任意组合，非必传<br />}<br />SQL 函数条件，一般和 @group 一起用，函数一般在 @column 里声明<br /><br />⑥ "@schema":"sys"，集合空间(数据库名/模式)，非默认的值可通过它来指定，可以在最外层作为全局默认配置<br /><br />⑦ "@database":"POSTGRESQL"，数据库类型，非默认的值可通过它来指定，可以在最外层作为全局默认配置<br /><br />⑧ "@datasource":"DRUID"，跨数据源，非默认的值可通过它来指定，可以在最外层作为全局默认配置<br /><br />⑨ "@json":"key0,key1..."，转为 JSON 格式返回，符合 JSONObject 则转为 {...}，符合 JSONArray 则转为 \[...] <br /><br />⑩ "@role":"OWNER"，来访角色，包括<br />UNKNOWN,LOGIN,CONTACT,CIRCLE,OWNER,ADMIN，<br />可以在最外层作为全局默认配置，<br />可自定义其它角色并重写 Verifier.verify 等相关方法来自定义校验 <br /><br />⑪ "@explain":true，性能分析，可以在最外层作为全局默认配置 <br /><br />⑫ "@raw":"key0,key1..."，其中 key0, key1 都对应有键值对<br /> "key0":"SQL片段或SQL片段的别名", <br /> "key1":"SQL片段或SQL片段的别名" <br /> 自定义原始SQL片段，可扩展嵌套SQL函数等复杂语句，必须是后端已配置的，只有其它功能符都做不到才考虑，谨慎使用，注意防 SQL 注入<br /><br />⑬ "@null":"key1,key2..."，空值键值对，自动插入 key1:null, key2:null ... 并作为有效键值对执行，作为条件时对应 SQL 是 `WHERE tag IS NULL`，作为值时对应 SQL 是 `SET tag = NULL`<br /><br />⑭ "@otherKey":Object，自定义关键词，名称和以上系统关键词不一样，且原样返回上传的值 | ① 搜索 name 或 tag 任何一个字段包含字符 a 的 User 列表：<br /> ["name~":"a",<br />"tag~":"a",<br />"@combine":"name~ \| tag~"](http://apijson.cn:8080/get/{"User[]":{"count":10,"User":{"@column":"id,name,tag","name~":"a","tag~":"a","@combine":"name~%20%7C%20tag~"}}}) <br />对应SQL是`name REGEXP 'a' OR tag REGEXP 'a'` <br /><br /> ② 只查询 id,sex,name 这几列并且请求结果也按照这个顺序：<br />["@column":"id,sex,name"](http://apijson.cn:8080/get/{"User":{"@column":"id,sex,name","id":38710}})<br />对应 SQL 是`SELECT id,sex,name` <br /><br /> ③ 查询按 name 降序、id 默认顺序 排序的 User 数组：<br />["@order":"name-,id"](http://apijson.cn:8080/get/{"[]":{"count":10,"User":{"@column":"name,id","@order":"name-,id"}}})<br />对应 SQL 是`ORDER BY name DESC,id` <br /><br /> ④ 查询按 userId 分组的 Moment 数组：<br />["@group":"userId,id"](http://apijson.cn:8080/get/{"[]":{"count":10,"Moment":%7B"@column":"userId,id","@group":"userId,id"}}})<br />对应 SQL 是`GROUP BY userId,id` <br /><br /> ⑤ 查询 按 userId 分组、id 最大值>=100 的 Moment 数组：<br />["@column":"userId;max(id)",<br />"@group":"userId",<br />"@having":"max(id)>=100"](http://apijson.cn:8080/get/{"[]":{"count":10,"Moment":{"@column":"userId%253Bmax(id)","@group":"userId","@having":"max(id)>=100"}}})<br />对应 SQL 是`SELECT userId,max(id) ... GROUP BY userId HAVING max(id)>=100` <br />还可以指定函数返回名：<br />["@column":"userId;max(id):maxId",<br />"@group":"userId",<br />"@having":"(maxId)>=100"](http://apijson.cn:8080/get/{"[]":{"count":10,"Moment":{"@column":"userId%253Bmax(id):maxId","@group":"userId","@having":"(maxId)>=100"}}})<br />对应 SQL 是`SELECT userId,max(id) AS maxId ... GROUP BY userId HAVING (maxId)>=100` <br /><br /> ⑥ 查询 sys 内的 User 表：<br />["@schema":"sys"](http://apijson.cn:8080/get/{"User":{"@schema":"sys"}})<br />对应 SQL 是`FROM sys.User` <br /><br /> ⑦ 查询 PostgreSQL 数据库的 User 表：<br />["@database":"POSTGRESQL"](http://apijson.cn:8080/get/{"User":{"@database":"POSTGRESQL","@explain":true}})<br /><br /> ⑧ 使用 Druid 连接池查询 User 表：<br />["@datasource":"DRUID"](http://apijson.cn:8080/get/{"User":{"@datasource":"DRUID"}})<br /><br /> ⑨ 将 VARCHAR 字符串字段 get 转为 JSONArray 返回：<br />["@json":"get"](http://apijson.cn:8080/get/{"Access":{"@json":"get"}})<br /><br /> ⑩ 查询当前用户的动态：<br />["@role":"OWNER"](http://apijson.cn:8080/get/{"[]":{"Moment":{"@role":"OWNER"}}})<br /><br /> ⑪ 开启性能分析：<br />["@explain":true](http://apijson.cn:8080/get/{"[]":{"Moment":{"@explain":true}}})<br />对应 SQL 是`EXPLAIN` <br /><br /> ⑫ 统计最近一周偶数 userId 的数量<br />["@column":"date;left(date,10):day;sum(if(userId%2=0,1,0))",<br />"@group":"day",<br />"@having":"to_days(now())-to_days(\`date\`)<=7",<br />"@raw":"@column,@having"](http://apijson.cn:8080/get/{"[]":{"Moment":{"@column":"date%3bleft(date,10):day%3bsum(if(userId%252=0,1,0))","@group":"day","@having":"to_days(now())-to_days(\`date\`)<=7","@raw":"@column,@having"}}})<br />对应 SQL 是``SELECT date, left(date,10) AS day, sum(if(userId%2=0,1,0)) ... GROUP BY day HAVING to_days(now())-to_days(`date`)<=7`` <br /><br /> ⑬ 把用户的标签设置为空 <br />["@null":"tag"](http://apijson.cn/api/?type=JSON&url=http://apijson.cn:8080/put/User&json={%22id%22:82001,%22@null%22:%22tag%22,%22@explain%22:true}) <br /><br /> ⑭  从pictureList 获取第 0 张图片：<br />["@position":0, // 自定义关键词<br />"firstPicture()":"getFromArray(pictureList,@position)"](http://apijson.cn:8080/get/{"User":{"id":38710,"@position":0,"firstPicture()":"getFromArray(pictureList,@position)"}})
  全局关键词 | 为最外层对象 {} 内的关键词。其中 @database，@schema, @datasource, @role, @explain 基本同对象关键词，见上方说明，区别是全局关键词会每个表对象中没有时自动放入，作为默认值。 <br /><br />① "tag":"Table"，后面的 tag 是非 GET、HEAD 请求中匹配请求的 JSON 结构的标识，一般是要查询的 Table 的名称或该名称对应的数组 Table[] 或 Table:[]，由后端 Request 表中指定。 <br /><br />② "version":1，接口版本，version 不传、为 null 或 <=0 都会使用最高版本，传了其它有效值则会使用最接近它的最低版本，由后端 Request 表中指定。<br /><br />③ "format":true，格式化返回 Response JSON 的 key，一般是将 TableName 转为 tableName, TableName[] 转为 tableNameList, Table:alias 转为 alias, TableName-key[] 转为 tableNameKeyList 等小驼峰格式。  | ①  查隐私信息：<br />[{"tag":"Privacy","Privacy":{"id":82001}}](http://apijson.cn/api?url=http%3A%2F%2Fapijson.cn%3A8080%2Fgets&type=JSON&json={%22tag%22:%22Privacy%22,%22Privacy%22:{%22id%22:82001}})<br /><br /> ② 使用第 1 版接口查隐私信息：<br />[{"version":1,"tag":"Privacy","Privacy":{"id":82001}}](http://apijson.cn/api?url=http%3A%2F%2Fapijson.cn%3A8080%2Fgets&type=JSON&json={%22version%22:1,%22tag%22:%22Privacy%22,%22Privacy%22:{%22id%22:82001}}) <br /><br /> ③ 格式化朋友圈接口返回 JSON 中的 key：<br />[{<br > &nbsp;&nbsp; "format":true, <br > &nbsp;&nbsp; "[]":{<br > &nbsp;&nbsp;&nbsp;&nbsp; "page":0, <br > &nbsp;&nbsp;&nbsp;&nbsp; "count":3, <br > &nbsp;&nbsp;&nbsp;&nbsp; "Moment":{}, <br > &nbsp;&nbsp;&nbsp;&nbsp; "User":{<br > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "id@":"/Moment/userId"<br > &nbsp;&nbsp;&nbsp;&nbsp; },<br > &nbsp;&nbsp;&nbsp;&nbsp; "Comment[]":{<br > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "count":3,<br > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Comment":{<br > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "momentId@":"[]/Moment/id"<br > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br > &nbsp;&nbsp;&nbsp;&nbsp; }<br > &nbsp;&nbsp; }<br >}](http://apijson.cn:8080/get/{"format":true,"[]":{"page":0,"count":3,"Moment":{},"User":{"id@":"%252FMoment%252FuserId"},"Comment[]":{"count":3,"Comment":{"momentId@":"[]%252FMoment%252Fid"}}}})
 <br />
diff --git a/LICENSE b/LICENSE
index 1a71560c8..9743dd5aa 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,18 +1,18 @@
 Tencent is pleased to support the open source community by making APIJSON available.  
 
-Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved.
+Copyright (C) 2020 Tencent.  All rights reserved.
 
 APIJSON is licensed under the Apache License Version 2.0.
 A copy of the Apache License Version 2.0 is included in this file.
 
+The copyright notice pertaining to the Tencent code in this repo was previously in the name of “THL A29 Limited.”
+That entity has now been de-registered.
+You should treat all previously distributed copies of the code as if the copyright notice was in the name of “Tencent.”
 
 Other dependencies and licenses:
 
 Open Source Software Licensed under the Apache License Version 2.0:
 --------------------------------------------------------------------
-1.  fastjson
-Copyright 1999-2019 Alibaba Group Holding Ltd.
-
 
 
 Terms of  Apache License Version 2.0
diff --git a/README-English.md b/README-English.md
index beea69d6c..ccafb9850 100644
--- a/README-English.md
+++ b/README-English.md
@@ -1,5 +1,5 @@
 Tencent is pleased to support the open source community by making APIJSON available.   <br/>
-Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved. <br/>
+Copyright (C) 2020 Tencent.  All rights reserved. <br/>
 This source code is licensed under the Apache License Version 2.0 <br/>
 
 <h1 align="center" style="text-align:center;">
@@ -14,6 +14,7 @@ This source code is licensed under the Apache License Version 2.0 <br/>
   <a href="https://github.com/Tencent/APIJSON/blob/master/Document-English.md">&nbsp;Document&nbsp;</a>
   <a href="https://search.bilibili.com/all?keyword=APIJSON">&nbsp;Video&nbsp;</a>
   <a href="http://apijson.cn/api">&nbsp;Test&nbsp;</a>
+  <a href="https://deepwiki.com/Tencent/APIJSON">Ask AI</a>
 </p>
 <p align="center" >
   <a href="https://github.com/APIJSON/APIJSON-Demo/tree/master/MySQL"><img src="https://img.shields.io/badge/MySQL-5.7%2B-brightgreen.svg?style=flat"></a>
diff --git a/README-extend.md b/README-extend.md
index 09301ddca..98b60ac2c 100644
--- a/README-extend.md
+++ b/README-extend.md
@@ -6,13 +6,23 @@ https://github.com/Tencent/APIJSON/issues/468
 
 #### 使用说明
 
-json支持多种方式定义method
+json 支持多种方式定义 method
 
-第一种:
+#### 第一种:
 
- "@post","@put","@delete","@head","@get","@gets","@head","@heads"
+"@post","@put","@delete","@head","@get","@gets","@head","@heads"
 
-"@post": ["Moment","Comment[]"] , 值为数组格式,  每个value = key
+"@post": "Moment,Comment[]" , 值为 String 或 JSONObject 格式,  为 String 时每个 value = key，为 JSONObject 时：
+```json
+"@post": { 
+   "Moment": "Moment", // 只指定 tag，为 "" 则和 key 一致
+   "Comment[]": { // 同时指定多个全局关键词
+      "tag": "Comment[]",
+      "version": 2
+      // 其它全局关键词
+   }
+}
+```
 
 需要保证每个key唯一, 唯一判断标准:
 
@@ -24,7 +34,7 @@ key= Moment[]
 
 ```
 {
-   "@post": ["Moment","Comment:cArray[]","User:u"], // 分发到 POST 请求对应的解析处理
+   "@post": "Moment,Comment:cArray[],User:u", // 分发到 POST 请求对应的解析处理
    "Moment": {
      // TODO 其它字段
    },
@@ -33,7 +43,7 @@ key= Moment[]
         // TODO 其它字段
       }
    ],
-   "@get": ["User"], // 分发到 GET 请求对应的解析处理
+   "@get": "User", // 分发到 GET 请求对应的解析处理
    "User:u": {
      // TODO 其它字段
    },
@@ -46,19 +56,19 @@ key= Moment[]
 
 ```
 
-第二种:
+#### 第二种: @Deprecated 即将弃用，请使用第一种
 
 对象内定义"@method": "GET", value大写
 
 ```
 {
-	"sql@": {
+    "sql@": {
     	"@method": "GET",
         "with": true,
         "from": "Sys_role",
         "Sys_role": {
-          "@column": "id",
-          "role_name": "角色1"
+            "@column": "id",
+            "role_name": "角色1"
         }
     },
     "Sys_user_role:sur[]": {
@@ -152,14 +162,14 @@ Comment:cArray[]
 
 并将method 添加到 json对象属性中.
 
-```
+```json
 "Sys_role": {
-    	"@method": "PUT",
-		"id": "6aedce0d-2a29-4fbe-aeed-0ba935ca6b41",
-        "id{}@": "sql",
-        "role_code": "code-subrange-4",
-        "role_name": "角色-subrange-4"
-    }
+    "@method": "PUT",
+    "id": "6aedce0d-2a29-4fbe-aeed-0ba935ca6b41",
+    "id{}@": "sql",
+    "role_code": "code-subrange-4",
+    "role_name": "角色-subrange-4"
+}
 ```
 
 2、对象解析
@@ -741,6 +751,7 @@ AbstractVerifier.IS_UPDATE_MUST_HAVE_ID_CONDITION = true; // true: 必须有
 
 ```
 // 条件删除
+```json
 {
     "User:del": {
         "username": "test3"
@@ -748,8 +759,10 @@ AbstractVerifier.IS_UPDATE_MUST_HAVE_ID_CONDITION = true; // true: 必须有
     "tag": "User",
     "explain": true
 }
+```
 
 // 引用id{}@删除
+```json
 {
 	"sql@": {
 		"@method": "GET",
@@ -766,8 +779,11 @@ AbstractVerifier.IS_UPDATE_MUST_HAVE_ID_CONDITION = true; // true: 必须有
     },
     "explan": true
 }
+```
+
 // 子查询条件删除
 http://localhost:8675/lowCodePlatform/forms/api/delete
+```json
 {
 	"sql@": {
 		"@method": "GET",
@@ -783,8 +799,10 @@ http://localhost:8675/lowCodePlatform/forms/api/delete
     },
     "explan": true
 }
+```
 
 第二种写法:
+```json
 {
 	"@get": ["sql@"],
 	"sql@": {
@@ -800,23 +818,21 @@ http://localhost:8675/lowCodePlatform/forms/api/delete
     },
     "explan": true
 }
-
-
 ```
 
 
 
 开启id删除, 删除失败:
 
-```
+```json
 {
-	"@get": ["sql@"],
-	"sql@": {
+    "@get": ["sql@"],
+    "sql@": {
         "with": true,
         "from": "User",
         "User": {
-          "@column": "username",
-		  "username": "test4"
+            "@column": "username",
+            "username": "test4"
         }
     },
     "User": {
@@ -830,7 +846,7 @@ http://localhost:8675/lowCodePlatform/forms/api/delete
 
 开启id删除、id引用 删除成功
 
-```
+```json
 {
 	"sql@": {
 		"@method": "GET",
@@ -848,19 +864,20 @@ http://localhost:8675/lowCodePlatform/forms/api/delete
     "explan": true
 }
 ```
+
 ![image](https://user-images.githubusercontent.com/12228225/204080050-e6f04fe6-319e-45b7-b1b2-bf4cda4ab2db.png)
 
 PUT 子查询 修改
 
-```
+```json
 {
    "sql@": {
-		"@method": "GET",
+	"@method": "GET",
         "with": true,
         "from": "Sys_role_permission",
         "Sys_role_permission": {
-          "@column": "role_id",
-		  "id{}": ["ba2634f8-0bdc-4b50-9c5e-47786b1536ef"]
+             "@column": "role_id",
+	     "id{}": ["ba2634f8-0bdc-4b50-9c5e-47786b1536ef"]
         }
     },
     "Sys_role": {
@@ -892,15 +909,15 @@ WHERE ( (`username` IN (SELECT * FROM (SELECT `username` FROM `housekeeping`.`Us
 
 ### must、refuses判断、delete、PUT支持 ref
 
-```
+```json
 {
-	"sql@": {
-		"@method": "GET",
+    "sql@": {
+	"@method": "GET",
         "with": true,
         "from": "Sys_role_permission",
         "Sys_role_permission": {
-          "@column": "id",
-		  "role_id{}": ["94f79f0b-331b-4cc5-bfc0-ebfc47d00f13"]
+            "@column": "id",
+	    "role_id{}": ["94f79f0b-331b-4cc5-bfc0-ebfc47d00f13"]
         }
     },
     "Sys_role_permission": {
diff --git a/README.md b/README.md
index 67610d168..99d0f7272 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 Tencent is pleased to support the open source community by making APIJSON available.   <br/>
-Copyright (C) 2020 THL A29 Limited, a Tencent company.  All rights reserved. <br/>
+Copyright (C) 2020 Tencent.  All rights reserved. <br/>
 This source code is licensed under the Apache License Version 2.0 <br/>
 
 <h1 align="center" style="text-align:center;">
@@ -13,6 +13,7 @@ This source code is licensed under the Apache License Version 2.0 <br/>
   <a href="https://github.com/Tencent/APIJSON/blob/master/Document.md">通用文档</a>
   <a href="https://search.bilibili.com/all?keyword=APIJSON">视频教程</a>
   <a href="http://apijson.cn/api">测试用例</a>
+  <a href="https://deepwiki.com/Tencent/APIJSON">AI 问答</a>
 </p>
 <p align="center" >
   <a href="https://github.com/APIJSON/APIJSON-Demo/tree/master/MySQL"><img src="https://img.shields.io/badge/MySQL-5.7%2B-brightgreen.svg?style=flat"></a>
@@ -191,7 +192,7 @@ https://github.com/Tencent/APIJSON/wiki
 * **开发提速很大** (CRUD 零代码热更新全自动，APIJSONBoot 对比 SSM、SSH 等保守估计可提速 20 倍以上)
 * **腾讯官方开源** (使用 GitHub、Gitee、工蜂 等平台的官方账号开源，微信公众号、腾讯云+社区 等官方公告)
 * **社区影响力大** (GitHub 17K+ Star 在 400W Java 项目排名前 100，远超 FLAG, BAT 等国内外绝大部分开源项目)
-* **各项荣誉成就** (腾讯内外 5 个奖项、腾讯开源前六、腾讯后端 Star 第一、Trending 日周月榜大满贯 等)
+* **各项荣誉成就** (腾讯内外 5 个奖项、腾讯开源前五、腾讯后端 Star 第一、Trending 日周月榜大满贯 等)
 * **多样用户案例** (腾讯内有互娱、音乐、微信、云与智慧，外部有华为、华能、百度、快手、中兴、圆通、传音等)
 * **适用场景广泛** (社交聊天、阅读资讯、影音娱乐、办公学习 等各种 App、网站、小程序、公众号 等非金融类项目)
 * **周边生态丰富** (Android, iOS, Web 等各种 Demo、继承 JSON 的海量生态、零代码 接口测试 和 单元测试 工具等)
@@ -558,7 +559,7 @@ Issue/问卷 一般解答顺序：贡献者 > 帮助他人的用户 > 提供任
 
 [3步创建APIJSON后端新表及配置](https://my.oschina.net/tommylemon/blog/889074)
 
-[APIJSON对接分布式HTAP数据库TiDB](https://asktug.com/t/htap-tidb/395)
+[APIJSON对接分布式HTAP数据库TiDB](https://my.oschina.net/tommylemon/blog/3081913)
 
 [APIJSON教程（一）：上手apijson项目，学习apijson语法，并实现持久层配置](https://zhuanlan.zhihu.com/p/375681893)
 
@@ -571,13 +572,7 @@ Issue/问卷 一般解答顺序：贡献者 > 帮助他人的用户 > 提供任
 [学习自动化接口APIJSON](https://www.jianshu.com/p/981a2a630c7b)
 
 [APIJSON 接口调试实践](https://github.com/Tencent/APIJSON/issues/189)
-  
-[关于APIJSON远程函数](https://mp.weixin.qq.com/s?__biz=Mzg3NTc1NDUyNA==&mid=2247483950&idx=1&sn=b11e70bdf083c55d72238e107449ae2e&chksm=cf3de75df84a6e4b3a4acd0846531b0bd12bc90379523fbaf6b4f900fc3cdc1b1ce3eff97fd9&scene=178&cur_album_id=2548737392338354178#rd)
-  
-[APIJSON新增方法实例](https://cloud.tencent.com/developer/article/2098890)
-  
-[APIJSON-APIJSON的那些事儿](https://cloud.tencent.com/developer/article/2098888)
-
+    
 [APIJSON-零代码接口和文档 JSON 协议 与 ORM 库](https://cloud.tencent.com/developer/article/2077042)
 
 [APIJSON使用例子总结](https://blog.csdn.net/weixin_41077841/article/details/110518007)
@@ -588,8 +583,6 @@ Issue/问卷 一般解答顺序：贡献者 > 帮助他人的用户 > 提供任
 
 [APIJSON复杂业务深入实践（类似12306订票系统）](https://blog.csdn.net/aa330233789/article/details/105309571)
 
-[全国行政区划数据抓取与处理](https://www.xlongwei.com/detail/21032616)
-
 [新手搭建 APIJSON 项目指北](https://github.com/jerrylususu/apijson_todo_demo/blob/master/FULLTEXT.md)  
 
 [使用APIJSON写低代码Crud接口](https://blog.csdn.net/weixin_42375862/article/details/121654264)
@@ -622,6 +615,20 @@ Issue/问卷 一般解答顺序：贡献者 > 帮助他人的用户 > 提供任
 
 [wend看源码-ORM-APIJSON](https://itwend.blog.csdn.net/article/details/143980281)
 
+[APIJSON – The No-Code API Revolution That Puts Developers in the Fast Lane](https://medevel.com/apijson)
+
+[APIJSON：17.4k Star！腾讯开源的零代码接口与文档协议及ORM库](https://mp.weixin.qq.com/s/gr84DmWKs4O6lcoT-iaV5w)
+
+[APIJSON腾讯开源的后端开发神器！！！](https://cloud.tencent.com/developer/article/2372220)
+
+[apijson 快速上手](https://blog.csdn.net/qq_16381291/article/details/147110737)
+
+[APIJSON快速入门-零后端代码，接口所见即所得](https://www.toutiao.com/article/7503844050689376783)
+
+[腾讯开源！零代码，全自动万能API接口](https://mp.weixin.qq.com/s/WWndAa68BqBfflWgL5592A)
+
+[APIJSON项目实战教程：零代码实现高效JSON接口开发](https://blog.csdn.net/gitblog_00682/article/details/148375065)
+
 ### 生态项目
 [APIJSON-Demo](https://github.com/APIJSON/APIJSON-Demo) APIJSON 各种语言、各种框架 的 使用示例项目、上手文档、测试数据 SQL 文件 等
 
@@ -633,6 +640,10 @@ Issue/问卷 一般解答顺序：贡献者 > 帮助他人的用户 > 提供任
   
 [apijson-column](https://github.com/APIJSON/apijson-column) APIJSON 的字段插件，支持 字段名映射 和 !key 反选字段
 
+[apijson-gson](https://github.com/APIJSON/apijson-gson) APIJSON 的 gson 插件，简化使用
+
+[apijson-fastjson2](https://github.com/APIJSON/apijson-fastjson2) APIJSON 的 fastjson2 插件，简化使用
+
 [apijson-milvus](https://github.com/APIJSON/apijson-milvus) APIJSON 的 Milvus AI 向量数据库插件
 
 [apijson-influxdb](https://github.com/APIJSON/apijson-influxdb) APIJSON 的 InfluxDB 物联网时序数据库插件
@@ -641,13 +652,15 @@ Issue/问卷 一般解答顺序：贡献者 > 帮助他人的用户 > 提供任
 
 [apijson-cassandra](https://github.com/APIJSON/apijson-cassandra) APIJSON 的 Cassandra NoSQL 数据库插件
 
-[APIAuto](https://github.com/TommyLemon/APIAuto) 敏捷开发最强大易用的接口工具，机器学习零代码测试、生成代码与静态检查、生成文档与光标悬浮注释
+[APIAuto](https://github.com/TommyLemon/APIAuto) ☔ 敏捷开发最强大易用的接口工具，零代码测试与 AI 问答、生成代码与静态检查、生成文档与光标悬浮注释，腾讯、SHEIN、传音 等使用
+
+[CVAuto](https://github.com/TommyLemon/CVAuto) 👁 零代码零标注 CV AI 自动化测试平台 🚀 免除大量人工画框和打标签等，直接快速测试 CV 计算机视觉 AI 图像识别算法
 
 [UnitAuto](https://github.com/TommyLemon/UnitAuto) 最先进、最省事、ROI 最高的单元测试，机器学习 零代码、全方位、自动化 测试 方法/函数，用户包含腾讯、快手、某 500 强巨头等
 
-[SQLAuto](https://github.com/TommyLemon/SQLAuto) 智能零代码自动化测试 SQL 语句执行结果的数据库工具，一键批量生成参数组合、快速构造大量测试数据
+[SQLAuto](https://github.com/TommyLemon/SQLAuto) 智能零代码自动化测试 SQL 数据库工具，任意增删改查、任意 SQL 模板变量、一键批量生成参数组合、快速构造大量测试数据
 
-[UIGO](https://github.com/TommyLemon/UIGO) 📱 零代码快准稳 UI 智能录制回放平台 🚀 自动兼容任意宽高比分辨率屏幕、自动精准等待网络请求，录制回放快、准、稳！
+[UIGO](https://github.com/TommyLemon/UIGO) 📱 零代码快准稳 UI 智能录制回放平台 🚀 3 像素内自动精准定位，2 毫秒内自动精准等待，用户包含腾讯，微信团队邀请分享
 
 [apijson-doc](https://github.com/vincentCheng/apijson-doc) APIJSON 官方文档，提供排版清晰、搜索方便的文档内容展示，包括设计规范、图文教程等
 
@@ -693,7 +706,7 @@ Issue/问卷 一般解答顺序：贡献者 > 帮助他人的用户 > 提供任
 
 [apijson-examples](https://gitee.com/drone/apijson-examples) APIJSON 的前端、业务后端、管理后端 Demo
 
-[apijson-ruoyi](https://gitee.com/yxiedd/apijson-ruoyi) APIJSON 和 RuoYi 框架整合，实现零代码生成页面模板接口，在线维护 APIJSON 数据库配置等
+[apijson-ruoyi](https://github.com/daodol/apijson-ruoyi) APIJSON 和 RuoYi 框架整合，实现零代码生成页面模板接口，在线维护 APIJSON 数据库配置等
 
 [light4j](https://github.com/xlongwei/light4j) 整合 APIJSON 和微服务框架 light-4j 的 Demo，同时接入了 Redis
 
@@ -732,7 +745,9 @@ Issue/问卷 一般解答顺序：贡献者 > 帮助他人的用户 > 提供任
 [review_plan](https://gitee.com/PPXcodeTry/review_plan) 复习提醒Web版（Java技术练习项目）
 
 [apijson-nutz](https://github.com/vincent109/apijson-nutz) APIJSON + Nutz 框架 + NutzBoot 的 Demo
-  
+
+[apijson-spring-boot](https://gitee.com/yunjiao-source/apijson-spring-boot) Springboot3 for APIJSON，用 YAML 简化代码配置
+
 感谢热心的作者们的贡献，点 ⭐Star 支持下他们吧~
 
   
