diff --git a/APIJSONORM/pom.xml b/APIJSONORM/pom.xml index 2cf436bd5..391319beb 100644 --- a/APIJSONORM/pom.xml +++ b/APIJSONORM/pom.xml @@ -5,7 +5,7 @@ com.github.Tencent APIJSON - 7.9.0 + 8.0.0 jar APIJSONORM @@ -21,11 +21,6 @@ - - com.alibaba - fastjson - 1.2.83 - diff --git a/APIJSONORM/src/main/java/apijson/JSON.java b/APIJSONORM/src/main/java/apijson/JSON.java index 0a1f901b7..c2039c958 100755 --- a/APIJSONORM/src/main/java/apijson/JSON.java +++ b/APIJSONORM/src/main/java/apijson/JSON.java @@ -4,269 +4,690 @@ package apijson; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.parser.Feature; -import com.alibaba.fastjson.serializer.SerializerFeature; - import java.util.List; +import java.util.Map; -/**阿里FastJSON封装类 防止解析时异常 +/**JSON工具类 防止解析时异常 * @author Lemon */ public class JSON { - private static final String TAG = "JSON"; + public static Class JSON_OBJECT_CLASS = JSONObject.class; + public static Class JSON_ARRAY_CLASS = JSONArray.class; - /**判断json格式是否正确 - * @param s - * @return - */ - public static boolean isJsonCorrect(String s) { - //太长 Log.i(TAG, "isJsonCorrect <<<< " + s + " >>>>>>>"); - if (s == null - // || s.equals("[]") - // || s.equals("{}") - || s.equals("") - || s.equals("[null]") - || s.equals("{null}") - || s.equals("null")) { - return false; + static final String TAG = "JSON"; + + public static JSONParser, ? extends List> DEFAULT_JSON_PARSER; + + static { + DEFAULT_JSON_PARSER = new JSONParser() { + + @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 parseObject(Object json, Class clazz) { + throw new UnsupportedOperationException(); + } + + @Override + public JSONArray parseArray(Object json) { + throw new UnsupportedOperationException(); + } + + @Override + public List parseArray(Object json, Class clazz) { + throw new UnsupportedOperationException(); + } + + }; + } + +// public static JSONCreator, ? extends List> DEFAULT_JSON_CREATOR = DEFAULT_JSON_PARSER; + + public static > M createJSONObject() { + return (M) DEFAULT_JSON_PARSER.createJSONObject(); + } + public static > M createJSONObject(String key, Object value) { + return (M) DEFAULT_JSON_PARSER.createJSONObject(key, value); + } + public static > M createJSONObject(Map map) { + return (M) DEFAULT_JSON_PARSER.createJSONObject(map); + } + + public static > L createJSONArray() { + return (L) DEFAULT_JSON_PARSER.createJSONArray(); + } + public static > L createJSONArray(Object obj) { + return (L) DEFAULT_JSON_PARSER.createJSONArray(obj); + } + public static > L createJSONArray(List 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; } - return true; + + 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); } - /**获取有效的json - * @param s + /** + * @param json * @return */ - public static String getCorrectJson(String s) { - return getCorrectJson(s, false); + public static > M parseObject(Object json) { + return (M) parseObject(json, DEFAULT_JSON_PARSER); } - /**获取有效的json - * @param s - * @param isArray - * @return - */ - public static String getCorrectJson(String s, boolean isArray) { - s = StringUtil.trim(s); - // if (isArray) { - // while (s.startsWith("\"")) { - // s = s.substring(1); - // } - // while (s.endsWith("\"")) { - // s = s.substring(0, s.length() - 1); - // } - // } - return s;//isJsonCorrect(s) ? s : null; + + public static , L extends List> M parseObject(Object json, JSONParser parser) { + String s = toJSONString(json); + if (StringUtil.isEmpty(s, true)) { + return null; + } + + return parser.parseObject(s); + } + + public static T parseObject(Object json, Class clazz) { + return parseObject(json, clazz, DEFAULT_JSON_PARSER); + } + + public static , L extends List> T parseObject(Object json, Class clazz, JSONParser parser) { + String s = toJSONString(json); + if (StringUtil.isEmpty(s, true)) { + return null; + } + + if (parser == null) { + parser = (JSONParser) DEFAULT_JSON_PARSER; + } + + return parser.parseObject(s, clazz); } /** * @param json * @return */ - private static final Feature[] DEFAULT_FASTJSON_FEATURES = {Feature.OrderedField, Feature.UseBigDecimal}; - public static Object parse(Object obj) { + public static > L parseArray(Object json) { + return (L) parseArray(json, DEFAULT_JSON_PARSER); + } + + public static , L extends List> L parseArray(Object json, JSONParser parser) { + String s = toJSONString(json); + if (StringUtil.isEmpty(s, true)) { + return null; + } + try { - return com.alibaba.fastjson.JSON.parse(obj instanceof String ? (String) obj : toJSONString(obj), DEFAULT_FASTJSON_FEATURES); + L arr = parser.parseArray(s); + return arr; } catch (Exception e) { - Log.i(TAG, "parse catch \n" + e.getMessage()); + Log.i(TAG, "parseArray catch \n" + e.getMessage()); } return null; } - /**obj转JSONObject - * @param obj - * @return - */ - public static JSONObject parseObject(Object obj) { - if (obj instanceof JSONObject) { - return (JSONObject) obj; + public static List parseArray(Object json, Class clazz) { + return parseArray(json, clazz, DEFAULT_JSON_PARSER); + } + + public static , L extends List> List parseArray(Object json, Class clazz, JSONParser parser) { + String s = toJSONString(json); + if (StringUtil.isEmpty(s, true)) { + return null; + } + + try { + return parser.parseArray(s, clazz); + } catch (Exception e) { + Log.i(TAG, "parseArray catch \n" + e.getMessage()); } - return parseObject(toJSONString(obj)); + return null; } - /**json转JSONObject - * @param json + + /** + * @param obj * @return */ - public static JSONObject parseObject(String json) { - return parseObject(json, JSONObject.class); + public static String format(Object obj) { + return toJSONString(obj, true); } - /**json转实体类 - * @param json - * @param clazz + /** + * @param obj * @return */ - public static T parseObject(String json, Class clazz) { - if (clazz == null || StringUtil.isEmpty(json, true)) { - Log.e(TAG, "parseObject clazz == null || StringUtil.isEmpty(json, true) >> return null;"); - } else { - try { - return com.alibaba.fastjson.JSON.parseObject(getCorrectJson(json), clazz, DEFAULT_FASTJSON_FEATURES); - } catch (Exception e) { - Log.i(TAG, "parseObject catch \n" + e.getMessage()); - } + public static String toJSONString(Object obj) { + return toJSONString(obj, false); + } + public static String toJSONString(Object obj, boolean format) { + if (obj == null) { + return null; } - return null; + + if (obj instanceof String) { + return (String) obj; + } + + //if (obj instanceof Map) { + // // Simple JSON object format + // StringBuilder sb = new StringBuilder("{"); + // @SuppressWarnings("unchecked") + // Map map = (Map) obj; + // boolean first = true; + // for (Map.Entry entry : map.entrySet()) { + // if (! first) { + // sb.append(","); + // } + // + // first = false; + // sb.append("\"").append(entry.getKey()).append("\":"); + // Object value = entry.getValue(); + // if (value instanceof String) { + // sb.append("\"").append(value).append("\""); + // } else { + // sb.append(toJSONString(value)); + // } + // } + // sb.append("}"); + // return sb.toString(); + //} + // + //if (obj instanceof List) { + // StringBuilder sb = new StringBuilder("["); + // @SuppressWarnings("unchecked") + // List list = (List) obj; + // boolean first = true; + // for (Object item : list) { + // if (! first) { + // sb.append(","); + // } + // first = false; + // if (item instanceof String) { + // sb.append("\"").append(item).append("\""); + // } else { + // sb.append(toJSONString(item)); + // } + // } + // sb.append("]"); + // return sb.toString(); + //} + + return DEFAULT_JSON_PARSER.toJSONString(obj, format); } - /**list转JSONArray - * @param list + + /**判断是否为JSONObject或JSONArray的isXxx方法名 + * @param key * @return */ - public static JSONArray parseArray(List list) { - return new JSONArray(list); + public static boolean isJSONType(String key) { + return key != null && key.startsWith("is") && key.length() > 2 && key.contains("JSON"); } - /**obj转JSONArray - * @param obj - * @return + + public static boolean isBoolOrNumOrStr(Object obj) { + return obj instanceof Boolean || obj instanceof Number || obj instanceof String; + } + + /** + * Get a value from a Map and convert to the specified type + * @param map Source map + * @param key The key + * @param Target type + * @return The converted value */ - public static JSONArray parseArray(Object obj) { - if (obj instanceof JSONArray) { - return (JSONArray) obj; + @SuppressWarnings("unchecked") + public static T get(Map map, String key) { + return map == null || key == null ? null : (T) map.get(key); + } + + /** + * Get a value from a Map and convert to the specified type + * @param map Source map + * @param key The key + * @param Target type + * @return The converted value + */ + @SuppressWarnings("unchecked") + public static > M getJSONObject(Map map, String key) { + Object obj = get(map, key); + return (M) obj; + } + + /** + * Get a value from a Map and convert to the specified type + * @param map Source map + * @param key The key + * @param Target type + * @return The converted value + */ + @SuppressWarnings("unchecked") + public static > L getJSONArray(Map map, String key) { + Object obj = get(map, key); + return (L) obj; + } + + /** + * Get a value from a Map and convert to the specified type + * @param list Source map + * @param index The key + * @param Target type + * @return The converted value + */ + @SuppressWarnings("unchecked") + public static T get(List list, int index) { + return list == null || index < 0 || index >= list.size() ? null : (T) list.get(index); + } + + @SuppressWarnings("unchecked") + public static > M getJSONObject(List list, int index) { + Object obj = get(list, index); + return (M) obj; + } + + @SuppressWarnings("unchecked") + public static > L getJSONArray(List list, int index) { + Object obj = get(list, index); + return (L) obj; + } + +// /** +// * Get a value from a Map and convert to the specified type +// * @param map Source map +// * @param key The key +// * @param Target type +// * @return The converted value +// */ +// @SuppressWarnings("unchecked") +// public static T get(List list, int index) { +// return list == null || index < 0 || index >= list.size() ? null : list.get(index); +// } + + /** + * Get a Map value from a Map + * @param map Source map + * @param key The key + * @return The Map value + * @throws IllegalArgumentException If value is not a Map and cannot be converted + */ + @SuppressWarnings("unchecked") + public static Map getMap(Map 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) value; } - return parseArray(toJSONString(obj)); + + throw new IllegalArgumentException("Value for key '" + key + "' is not a Map: " + value.getClass().getName()); } - /**json转JSONArray - * @param json - * @return + + /** + * Get a List value from a Map + * @param map Source map + * @param key The key + * @return The List value + * @throws IllegalArgumentException If value is not a List and cannot be converted */ - public static JSONArray parseArray(String json) { - if (StringUtil.isEmpty(json, true)) { - Log.e(TAG, "parseArray StringUtil.isEmpty(json, true) >> return null;"); - } else { + @SuppressWarnings("unchecked") + public static List getList(Map 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) value; + } + + throw new IllegalArgumentException("Value for key '" + key + "' is not a List: " + value.getClass().getName()); + } + + /** + * Get an int value from a Map + * @param map Source map + * @param key The key + * @return The int value + * @throws IllegalArgumentException If value cannot be converted to int + */ + public static Integer getInteger(Map map, String key) throws IllegalArgumentException { + Object value = map == null || key == null ? null : map.get(key); + if (value == null) { + return null; + } + + if (value instanceof Number) { + return ((Number) value).intValue(); + } + + if (value instanceof String) { try { - return com.alibaba.fastjson.JSON.parseArray(getCorrectJson(json, true)); - } catch (Exception e) { - Log.i(TAG, "parseArray catch \n" + e.getMessage()); + return Integer.parseInt((String) value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Cannot convert String value '" + value + "' to int: " + e.getMessage()); } } - return null; + + throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to int"); } - /**JSONArray转实体类列表 - * @param array - * @param clazz - * @return + + /** + * Get an int value from a Map + * @param map Source map + * @param key The key + * @return The int value + * @throws IllegalArgumentException If value cannot be converted to int */ - public static List parseArray(JSONArray array, Class clazz) { - return parseArray(toJSONString(array), clazz); + public static int getIntValue(Map map, String key) throws IllegalArgumentException { + Object value = map == null || key == null ? null : map.get(key); + if (value == null) { + return 0; + } + + if (value instanceof Number) { + return ((Number) value).intValue(); + } + + if (value instanceof String) { + try { + return Integer.parseInt((String) value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Cannot convert String value '" + value + "' to int: " + e.getMessage()); + } + } + + throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to int"); } - /**json转实体类列表 - * @param json - * @param clazz - * @return + + /** + * Get an int value from a Map + * @param map Source map + * @param key The key + * @return The int value + * @throws IllegalArgumentException If value cannot be converted to int */ - public static List parseArray(String json, Class clazz) { - if (clazz == null || StringUtil.isEmpty(json, true)) { - Log.e(TAG, "parseArray clazz == null || StringUtil.isEmpty(json, true) >> return null;"); - } else { + public static Long getLong(Map map, String key) throws IllegalArgumentException { + Object value = map == null || key == null ? null : map.get(key); + if (value == null) { + return null; + } + + if (value instanceof Number) { + return ((Number) value).longValue(); + } + + if (value instanceof String) { try { - return com.alibaba.fastjson.JSON.parseArray(getCorrectJson(json, true), clazz); - } catch (Exception e) { - Log.i(TAG, "parseArray catch \n" + e.getMessage()); + return Long.parseLong((String) value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Cannot convert String value '" + value + "' to int: " + e.getMessage()); } } - return null; + + throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to int"); } - /**实体类转json - * @param obj - * @return + /** + * Get a long value from a Map + * @param map Source map + * @param key The key + * @return The long value + * @throws IllegalArgumentException If value cannot be converted to long */ - public static String toJSONString(Object obj) { - if (obj == null) { - return null; + public static long getLongValue(Map map, String key) throws IllegalArgumentException { + Object value = map == null || key == null ? null : map.get(key); + if (value == null) { + return 0; } - if (obj instanceof String) { - return (String) obj; + + if (value instanceof Number) { + return ((Number) value).longValue(); } - try { - return com.alibaba.fastjson.JSON.toJSONString(obj); - } catch (Exception e) { - Log.e(TAG, "toJSONString catch \n" + e.getMessage()); + + if (value instanceof String) { + try { + return Long.parseLong((String) value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Cannot convert String value '" + value + "' to long: " + e.getMessage()); + } } - return null; + + throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to long"); } - /**实体类转json - * @param obj - * @param features - * @return + /** + * Get a double value from a Map + * @param map Source map + * @param key The key + * @return The double value + * @throws IllegalArgumentException If value cannot be converted to double */ - public static String toJSONString(Object obj, SerializerFeature... features) { - if (obj == null) { + public static Float getFloat(Map map, String key) throws IllegalArgumentException { + Object value = map == null || key == null ? null : map.get(key); + if (value == null) { return null; } - if (obj instanceof String) { - return (String) obj; + + if (value instanceof Number) { + return ((Number) value).floatValue(); } - try { - return com.alibaba.fastjson.JSON.toJSONString(obj, features); - } catch (Exception e) { - Log.e(TAG, "toJSONString catch \n" + e.getMessage()); + + if (value instanceof String) { + try { + return Float.parseFloat((String) value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Cannot convert String value '" + value + "' to double: " + e.getMessage()); + } } - return null; + + throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to double"); } - /**格式化,显示更好看 - * @param json - * @return + /** + * Get a double value from a Map + * @param map Source map + * @param key The key + * @return The double value + * @throws IllegalArgumentException If value cannot be converted to double */ - public static String format(String json) { - return format(parse(json)); + public static float getFloatValue(Map map, String key) throws IllegalArgumentException { + Object value = map == null || key == null ? null : map.get(key); + if (value == null) { + return 0; + } + + if (value instanceof Number) { + return ((Number) value).floatValue(); + } + + if (value instanceof String) { + try { + return Float.parseFloat((String) value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Cannot convert String value '" + value + "' to double: " + e.getMessage()); + } + } + + throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to double"); } - /**格式化,显示更好看 - * @param object - * @return + + + /** + * Get a double value from a Map + * @param map Source map + * @param key The key + * @return The double value + * @throws IllegalArgumentException If value cannot be converted to double */ - public static String format(Object object) { - return toJSONString(object, SerializerFeature.PrettyFormat); + public static Double getDouble(Map map, String key) throws IllegalArgumentException { + Object value = map == null || key == null ? null : map.get(key); + if (value == null) { + return null; + } + + if (value instanceof Number) { + return ((Number) value).doubleValue(); + } + + if (value instanceof String) { + try { + return Double.parseDouble((String) value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Cannot convert String value '" + value + "' to double: " + e.getMessage()); + } + } + + throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to double"); } - /**判断是否为JSONObject - * @param obj instanceof String ? parseObject - * @return + /** + * Get a double value from a Map + * @param map Source map + * @param key The key + * @return The double value + * @throws IllegalArgumentException If value cannot be converted to double */ - public static boolean isJSONObject(Object obj) { - if (obj instanceof JSONObject) { - return true; + public static double getDoubleValue(Map map, String key) throws IllegalArgumentException { + Object value = map == null || key == null ? null : map.get(key); + if (value == null) { + return 0; } - if (obj instanceof String) { + + if (value instanceof Number) { + return ((Number) value).doubleValue(); + } + + if (value instanceof String) { try { - JSONObject json = parseObject((String) obj); - return json != null && json.isEmpty() == false; - } catch (Exception e) { - Log.e(TAG, "isJSONObject catch \n" + e.getMessage()); + return Double.parseDouble((String) value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Cannot convert String value '" + value + "' to double: " + e.getMessage()); } } - return false; + throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to double"); } - /**判断是否为JSONArray - * @param obj instanceof String ? parseArray - * @return + + + /** + * Get a boolean value from a Map + * @param map Source map + * @param key The key + * @return The boolean value + * @throws IllegalArgumentException If value cannot be converted to boolean */ - public static boolean isJSONArray(Object obj) { - if (obj instanceof JSONArray) { - return true; + public static Boolean getBoolean(Map map, String key) throws IllegalArgumentException { + Object value = map == null || key == null ? null : map.get(key); + if (value == null) { + return null; } - if (obj instanceof String) { - try { - JSONArray json = parseArray((String) obj); - return json != null && json.isEmpty() == false; - } catch (Exception e) { - Log.e(TAG, "isJSONArray catch \n" + e.getMessage()); + + if (value instanceof Boolean) { + return (Boolean) value; + } + + if (value instanceof String) { + String str = ((String) value).toLowerCase(); + if (str.equals("true") || str.equals("false")) { + return Boolean.parseBoolean(str); } + throw new IllegalArgumentException("Cannot convert String value '" + value + "' to boolean"); } - return false; + if (value instanceof Number) { + int intValue = ((Number) value).intValue(); + if (intValue == 0 || intValue == 1) { + return intValue != 0; + } + throw new IllegalArgumentException("Cannot convert Number value '" + value + "' to boolean. Only 0 and 1 are supported."); + } + + throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to boolean"); } - /**判断是否为 Boolean,Number,String 中的一种 - * @param obj - * @return + /** + * Get a boolean value from a Map + * @param map Source map + * @param key The key + * @return The boolean value + * @throws IllegalArgumentException If value cannot be converted to boolean */ - public static boolean isBooleanOrNumberOrString(Object obj) { - return obj instanceof Boolean || obj instanceof Number || obj instanceof String; + public static boolean getBooleanValue(Map map, String key) throws IllegalArgumentException { + Object value = map == null || key == null ? null : map.get(key); + if (value == null) { + return false; + } + + if (value instanceof Boolean) { + return (Boolean) value; + } + + if (value instanceof String) { + String str = ((String) value).toLowerCase(); + if (str.equals("true") || str.equals("false")) { + return Boolean.parseBoolean(str); + } + throw new IllegalArgumentException("Cannot convert String value '" + value + "' to boolean"); + } + + if (value instanceof Number) { + int intValue = ((Number) value).intValue(); + if (intValue == 0 || intValue == 1) { + return intValue != 0; + } + throw new IllegalArgumentException("Cannot convert Number value '" + value + "' to boolean. Only 0 and 1 are supported."); + } + + throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to boolean"); + } + + /** + * Get a string value from a Map + * @param map Source map + * @param key The key + * @return The string value + */ + public static String getString(Map map, String key) { + Object value = map == null || key == null ? null : map.get(key); + if (value == null) { + return null; + } + + return value.toString(); } } diff --git a/APIJSONORM/src/main/java/apijson/JSONArray.java b/APIJSONORM/src/main/java/apijson/JSONArray.java new file mode 100644 index 000000000..60c7926df --- /dev/null +++ b/APIJSONORM/src/main/java/apijson/JSONArray.java @@ -0,0 +1,376 @@ +/*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 { + private static final String TAG = "JSONArray"; + + private ArrayList 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 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 list = (List) 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 iterator() { + return list.iterator(); + } + + @Override + public Object[] toArray() { + return list.toArray(); + } + + @Override + public 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 listIterator() { + return list.listIterator(); + } + + @Override + public ListIterator listIterator(int index) { + int sz = size(); + if (index < 0) { + index += sz; + } + + return list.listIterator(index); + } + + @Override + public List 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 new file mode 100755 index 000000000..8e4f6c8cb --- /dev/null +++ b/APIJSONORM/src/main/java/apijson/JSONCreator.java @@ -0,0 +1,56 @@ +/*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 apijson.orm.SQLConfig; +import apijson.orm.SQLExecutor; + +import java.util.List; +import java.util.Map; + +/**SQL相关创建器 + * @author Lemon + */ +public interface JSONCreator, L extends List> { + + @NotNull + M createJSONObject(); + + @NotNull + default M createJSONObject(String key, Object value) { + M obj = createJSONObject(); + obj.put(key, value); + return obj; + } + + @NotNull + default M createJSONObject(Map map) { + M obj = createJSONObject(); + if (map != null && ! map.isEmpty()) { + obj.putAll(map); + } + return obj; + } + + @NotNull + L createJSONArray(); + + @NotNull + default L createJSONArray(Object obj){ + L arr = createJSONArray(); + arr.add(obj); + return arr; + } + + @NotNull + default L createJSONArray(List l){ + L arr = createJSONArray(); + if (l != null && ! l.isEmpty()) { + arr.addAll(l); + } + return arr; + } +} diff --git a/APIJSONORM/src/main/java/apijson/JSONField.java b/APIJSONORM/src/main/java/apijson/JSONField.java new file mode 100644 index 000000000..11a5cc309 --- /dev/null +++ b/APIJSONORM/src/main/java/apijson/JSONField.java @@ -0,0 +1,5 @@ +package apijson; + +public @interface JSONField { + boolean serialize() default true; +} diff --git a/APIJSONORM/src/main/java/apijson/JSONObject.java b/APIJSONORM/src/main/java/apijson/JSONObject.java index 0adf18365..05eb221d6 100755 --- a/APIJSONORM/src/main/java/apijson/JSONObject.java +++ b/APIJSONORM/src/main/java/apijson/JSONObject.java @@ -5,10 +5,8 @@ package apijson; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; + /**use this class instead of com.alibaba.fastjson.JSONObject * @author Lemon @@ -16,43 +14,57 @@ * @see #puts * @see #putsAll */ -public class JSONObject extends com.alibaba.fastjson.JSONObject { - private static final long serialVersionUID = 1L; - +public class JSONObject extends JSON implements Map { private static final String TAG = "JSONObject"; + private final LinkedHashMap map = new LinkedHashMap<>(); /**ordered */ public JSONObject() { - super(true); + super(); } /**transfer Object to JSONObject * @param object * @see {@link #JSONObject(Object)} */ public JSONObject(Object object) { - this(toJSONString(object)); + this(); + if (object instanceof Map) { + @SuppressWarnings("unchecked") + Map map = (Map) object; + putAll(map); + } else if (object != null) { + String json = JSON.toJSONString(object); + if (json != null) { + Map 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(parseObject(json)); + this(); + Map map = JSON.parseObject(json); + if (map != null) { + putAll(map); + } } /**transfer com.alibaba.fastjson.JSONObject to JSONObject * @param object * @see {@link #putsAll(Map)} */ - public JSONObject(com.alibaba.fastjson.JSONObject object) { + public JSONObject(Map object) { this(); putsAll(object); } - - //judge <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< public static final String KEY_ARRAY = "[]"; @@ -613,25 +625,6 @@ public JSONObject putsSearch(String key, String value, int type) { //Request >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - - - /**puts key-value in object into this - * @param map - * @return this - */ - public JSONObject putsAll(Map map) { - putAll(map); - return this; - } - @Override - public void putAll(Map map) { - if (map != null && map.isEmpty() == false) { - super.putAll(map); - } - } - - - /**put and return this * @param value must be annotated by {@link MethodAccess} * @return {@link #puts(String, Object)} @@ -679,9 +672,178 @@ public Object put(String key, Object value) { } key = value.getClass().getSimpleName(); } - return super.put(key, value); + + return map.put(key, value); + } + + /**puts key-value in object into this + * @param map + * @return this + */ + public JSONObject putsAll(Map 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 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 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 map) { + Set> set = map == null ? null : map.entrySet(); + if (set != null || set.isEmpty()) { + return; + } + + for (Entry 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 keySet() { + return map.keySet(); + } + + @Override + public Collection values() { + return map.values(); + } + + @Override + public Set> 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 new file mode 100755 index 000000000..f06b263a6 --- /dev/null +++ b/APIJSONORM/src/main/java/apijson/JSONParser.java @@ -0,0 +1,33 @@ +/*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.List; +import java.util.Map; + +/**SQL相关创建器 + * @author Lemon + */ +public interface JSONParser, L extends List> extends JSONCreator { + + Object parseJSON(Object json); + + M parseObject(Object json); + + T parseObject(Object json, Class clazz); + + L parseArray(Object json); + + List parseArray(Object json, Class clazz); + + default String format(Object obj) { + return toJSONString(obj, true); + } + default String toJSONString(Object obj) { + return toJSONString(obj, false); + } + String toJSONString(Object obj, boolean format); +} diff --git a/APIJSONORM/src/main/java/apijson/JSONRequest.java b/APIJSONORM/src/main/java/apijson/JSONRequest.java index ae5e19950..0d47e4392 100755 --- a/APIJSONORM/src/main/java/apijson/JSONRequest.java +++ b/APIJSONORM/src/main/java/apijson/JSONRequest.java @@ -15,7 +15,7 @@ * @author Lemon * @see #puts * @see #toArray - * @use JSONRequest request = new JSONRequest(...); + * @use JSONRequest request = JSON.createJSONObject(...); *
request.puts(...);//not a must *
request.toArray(...);//not a must */ diff --git a/APIJSONORM/src/main/java/apijson/JSONResponse.java b/APIJSONORM/src/main/java/apijson/JSONResponse.java index 21f3fe8f6..a405d346f 100755 --- a/APIJSONORM/src/main/java/apijson/JSONResponse.java +++ b/APIJSONORM/src/main/java/apijson/JSONResponse.java @@ -5,11 +5,9 @@ package apijson; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; +import java.util.*; -import java.util.List; -import java.util.Set; +import static apijson.JSON.parseObject; /**parser for response * @author Lemon @@ -19,7 +17,7 @@ *
User user = response.getObject(User.class);//not a must *
List commenntList = response.getList("Comment[]", Comment.class);//not a must */ -public class JSONResponse extends apijson.JSONObject { +public class JSONResponse, L extends List> extends apijson.JSONObject implements Map { private static final long serialVersionUID = 1L; // 节约性能和减少 bug,除了关键词 @key ,一般都符合变量命名规范,不符合也原样返回便于调试 @@ -38,12 +36,18 @@ public class JSONResponse extends apijson.JSONObject { public JSONResponse() { super(); } - public JSONResponse(String json) { + public JSONResponse(Object json) { this(parseObject(json)); } - public JSONResponse(JSONObject object) { + public JSONResponse(Object json, JSONParser parser) { + this(parseObject(json, parser)); + } + public JSONResponse(Map object) { super(format(object)); } + public JSONResponse(M object, JSONCreator creator) { + super(format(object, creator)); + } //状态信息,非GET请求获得的信息<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -92,9 +96,9 @@ public int getCode() { /**获取状态 * @return */ - public static int getCode(JSONObject reponse) { + public static int getCode(Map reponse) { try { - return reponse.getIntValue(KEY_CODE); + return JSON.getIntValue(reponse, KEY_CODE); } catch (Exception e) { //empty } @@ -107,11 +111,11 @@ public String getMsg() { return getString(KEY_MSG); } /**获取状态描述 - * @param reponse + * @param response * @return */ - public static String getMsg(JSONObject reponse) { - return reponse == null ? null : reponse.getString(KEY_MSG); + public static String getMsg(Map response) { + return response == null ? null : JSON.getString(response, KEY_MSG); } /**获取id * @return @@ -165,16 +169,20 @@ public static boolean isSuccess(int code) { * @param response * @return */ - public static boolean isSuccess(JSONResponse response) { + public static boolean isSuccess(JSONResponse response) { return response != null && response.isSuccess(); } /**是否成功 * @param response * @return */ - public static boolean isSuccess(JSONObject response) { - return response != null && isSuccess(response.getIntValue(KEY_CODE)); - } + public static boolean isSuccess(Map response) { + try { + return response != null && isSuccess(JSON.getIntValue(response, KEY_CODE)); + } catch (IllegalArgumentException e) { + return false; + } + } /**校验服务端是否存在table * @return @@ -193,7 +201,7 @@ public static boolean isExist(int count) { * @param response * @return */ - public static boolean isExist(JSONResponse response) { + public static boolean isExist(JSONResponse response) { return response != null && response.isExist(); } @@ -201,8 +209,15 @@ public static boolean isExist(JSONResponse response) { * @param key * @return */ - public JSONResponse getJSONResponse(String key) { - return getObject(key, JSONResponse.class); + public JSONResponse getJSONResponse(String key) { + return getObject(key, JSONResponse.class, null); + } + /**获取内部的JSONResponse + * @param key + * @return + */ + public JSONResponse getJSONResponse(String key, JSONParser parser) { + return getObject(key, JSONResponse.class, parser); } //cannot get javaBeanDeserizer // /**获取内部的JSONResponse @@ -210,7 +225,7 @@ public JSONResponse getJSONResponse(String key) { // * @param key // * @return // */ - // public static JSONResponse getJSONResponse(JSONObject response, String key) { + // public static JSONResponse getJSONResponse(JSONRequest response, String key) { // return response == null ? null : response.getObject(key, JSONResponse.class); // } //状态信息,非GET请求获得的信息>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -222,7 +237,15 @@ public JSONResponse getJSONResponse(String key) { * @return */ public T getObject(Class clazz) { - return getObject(clazz == null ? "" : clazz.getSimpleName(), clazz); + return getObject(clazz == null ? "" : clazz.getSimpleName(), clazz, (JSONParser) DEFAULT_JSON_PARSER); + } + /** + * key = clazz.getSimpleName() + * @param clazz + * @return + */ + public T getObject(Class clazz, JSONParser parser) { + return getObject(clazz == null ? "" : clazz.getSimpleName(), clazz, parser); } /** * @param key @@ -230,7 +253,15 @@ public T getObject(Class clazz) { * @return */ public T getObject(String key, Class clazz) { - return getObject(this, key, clazz); + return getObject(this, key, clazz, (JSONParser) DEFAULT_JSON_PARSER); + } + /** + * @param key + * @param clazz + * @return + */ + public T getObject(String key, Class clazz, JSONParser parser) { + return getObject(this, key, clazz, parser); } /** * @param object @@ -238,8 +269,9 @@ public T getObject(String key, Class clazz) { * @param clazz * @return */ - public static T getObject(JSONObject object, String key, Class clazz) { - return toObject(object == null ? null : object.getJSONObject(formatObjectKey(key)), clazz); + public static , L extends List> T getObject( + Map object, String key, Class clazz, JSONParser parser) { + return toObject(object == null ? null : JSON.get(object, formatObjectKey(key)), clazz, parser); } /** @@ -247,15 +279,23 @@ public static T getObject(JSONObject object, String key, Class clazz) { * @return */ public T toObject(Class clazz) { - return toObject(this, clazz); + return toObject(clazz, null); + } + /** + * @param clazz + * @return + */ + public T toObject(Class clazz, JSONParser parser) { + return toObject(this, clazz, parser); } /** * @param object * @param clazz * @return */ - public static T toObject(JSONObject object, Class clazz) { - return JSON.parseObject(JSON.toJSONString(object), clazz); + public static , L extends List> T toObject( + Map object, Class clazz, JSONParser parser) { + return parseObject(object, clazz, parser); } @@ -266,8 +306,8 @@ public static T toObject(JSONObject object, Class clazz) { * @param clazz * @return */ - public List getList(Class clazz) { - return getList(KEY_ARRAY, clazz); + public List getList(Class clazz, JSONParser> parser) { + return getList(KEY_ARRAY, clazz, parser); } /** * arrayObject = this @@ -275,8 +315,8 @@ public List getList(Class clazz) { * @param clazz * @return */ - public List getList(String key, Class clazz) { - return getList(this, key, clazz); + public List getList(String key, Class clazz, JSONParser> parser) { + return getList(this, key, clazz, parser); } /** @@ -285,8 +325,8 @@ public List getList(String key, Class clazz) { * @param clazz * @return */ - public static List getList(JSONObject object, Class clazz) { - return getList(object, KEY_ARRAY, clazz); + public static > List getList(Map object, Class clazz, JSONParser> parser) { + return getList(object, KEY_ARRAY, clazz, parser); } /** * @param object @@ -294,8 +334,8 @@ public static List getList(JSONObject object, Class clazz) { * @param clazz * @return */ - public static List getList(JSONObject object, String key, Class clazz) { - return object == null ? null : JSON.parseArray(object.getString(formatArrayKey(key)), clazz); + public static > List getList(Map object, String key, Class clazz, JSONParser> parser) { + return object == null ? null : JSON.parseArray(JSON.getString(object, formatArrayKey(key)), clazz, parser); } /** @@ -316,7 +356,7 @@ public JSONArray getArray(String key) { * @param object * @return */ - public static JSONArray getArray(JSONObject object) { + public static JSONArray getArray(Map object) { return getArray(object, KEY_ARRAY); } /** @@ -325,28 +365,48 @@ public static JSONArray getArray(JSONObject object) { * @param key * @return */ - public static JSONArray getArray(JSONObject object, String key) { - return object == null ? null : object.getJSONArray(formatArrayKey(key)); + public static JSONArray getArray(Map object, String key) { + return object == null ? null : JSON.get(object, formatArrayKey(key)); } // /** // * @return // */ - // public JSONObject format() { + // public JSONRequest format() { // return format(this); // } /**格式化key名称 * @param object * @return */ - public static JSONObject format(final JSONObject object) { + public static JSONObject format(final Map object) { + // return format(object, JSON.DEFAULT_JSON_CREATOR); + JSONObject obj = new JSONObject(object); + return format(obj, new JSONCreator() { + @Override + public JSONObject createJSONObject() { + return new JSONObject(); + } + + @Override + public JSONArray createJSONArray() { + return new JSONArray(); + } + }); + } + /**格式化key名称 + * @param object + * @return + */ + public static , L extends List> M format(final M object, @NotNull JSONCreator creator) { //太长查看不方便,不如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; } - JSONObject formatedObject = new JSONObject(true); + + M formatedObject = creator.createJSONObject(); Set set = object.keySet(); if (set != null) { @@ -355,11 +415,11 @@ public static JSONObject format(final JSONObject object) { for (String key : set) { value = object.get(key); - if (value instanceof JSONArray) {//JSONArray,遍历来format内部项 - formatedObject.put(formatArrayKey(key), format((JSONArray) value)); + if (value instanceof List) {//JSONArray,遍历来format内部项 + formatedObject.put(formatArrayKey(key), format((L) value, creator)); } - else if (value instanceof JSONObject) {//JSONObject,往下一级提取 - formatedObject.put(formatObjectKey(key), format((JSONObject) value)); + else if (value instanceof Map) {//JSONRequest,往下一级提取 + formatedObject.put(formatObjectKey(key), format((M) value, creator)); } else {//其它Object,直接填充 formatedObject.put(formatOtherKey(key), value); @@ -375,22 +435,37 @@ else if (value instanceof JSONObject) {//JSONObject,往下一级提取 * @param array * @return */ - public static JSONArray format(final JSONArray array) { + public static JSONArray format(final List array) { + // return format(array, JSON.DEFAULT_JSON_CREATOR); + JSONArray arr = new JSONArray(array); + return format(arr, new JSONCreator() { + @Override + public JSONObject createJSONObject() { + return new JSONObject(); + } + + @Override + public JSONArray createJSONArray() { + return new JSONArray(); + } + }); + } + public static , L extends List> L format(final L array, @NotNull JSONCreator creator) { //太长查看不方便,不如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; } - JSONArray formatedArray = new JSONArray(); + L formatedArray = creator.createJSONArray(); Object value; for (int i = 0; i < array.size(); i++) { value = array.get(i); - if (value instanceof JSONArray) {//JSONArray,遍历来format内部项 - formatedArray.add(format((JSONArray) value)); + if (value instanceof List) {//JSONArray,遍历来format内部项 + formatedArray.add(format((L) value, creator)); } - else if (value instanceof JSONObject) {//JSONObject,往下一级提取 - formatedArray.add(format((JSONObject) value)); + else if (value instanceof Map) {//JSONRequest,往下一级提取 + formatedArray.add(format((M) value, creator)); } else {//其它Object,直接填充 formatedArray.add(value); @@ -414,7 +489,7 @@ public static String getTableName(String fullName) { /**获取变量名 * @param fullName - * @return {@link #formatKey(String, boolean, boolean, boolean, boolean, boolean, boolean)} formatColon = true, formatAt = true, formatHyphen = true, firstCase = true + * @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)) { @@ -425,7 +500,7 @@ public static String getVariableName(String fullName) { /**格式化数组的名称 key[] => keyList; key:alias[] => aliasList; Table-column[] => tableColumnList * @param key empty ? "list" : key + "List" 且首字母小写 - * @return {@link #formatKey(String, boolean, boolean, boolean, boolean, boolean, boolean)} formatColon = false, formatAt = true, formatHyphen = true, firstCase = true + * @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)) { @@ -441,7 +516,7 @@ public static String formatArrayKey(String key) { /**格式化对象的名称 name => name; name:alias => alias * @param key name 或 name:alias - * @return {@link #formatKey(String, boolean, boolean, boolean, boolean, boolean, boolean)} formatColon = false, formatAt = true, formatHyphen = false, firstCase = true + * @return {@link #formatKey(String, boolean, boolean, boolean, boolean, boolean, Boolean)} formatColon = false, formatAt = true, formatHyphen = false, firstCase = true */ public static String formatObjectKey(String key) { int index = key == null ? -1 : key.indexOf(":"); @@ -454,7 +529,7 @@ public static String formatObjectKey(String key) { /**格式化普通值的名称 name => name; name:alias => alias * @param fullName name 或 name:alias - * @return {@link #formatKey(String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean)} formatColon = false, formatAt = true, formatHyphen = false, firstCase = false + * @return {@link #formatKey(String, boolean, boolean, boolean, boolean, boolean, Boolean)} formatColon = false, formatAt = true, formatHyphen = false, firstCase = false */ public static String formatOtherKey(String fullName) { return formatKey(fullName, false, true, IS_FORMAT_HYPHEN, IS_FORMAT_UNDERLINE, IS_FORMAT_DOLLAR diff --git a/APIJSONORM/src/main/java/apijson/Log.java b/APIJSONORM/src/main/java/apijson/Log.java index 0916af410..bd091c4e3 100755 --- a/APIJSONORM/src/main/java/apijson/Log.java +++ b/APIJSONORM/src/main/java/apijson/Log.java @@ -14,7 +14,7 @@ public class Log { public static boolean DEBUG = true; - public static final String VERSION = "7.9.0"; + public static final String VERSION = "8.0.0"; 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/orm/AbstractFunctionParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java index 25739bf17..76d6a4520 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java @@ -8,10 +8,6 @@ import apijson.*; import apijson.orm.exception.UnsupportedDataTypeException; import apijson.orm.script.ScriptExecutor; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.util.TypeUtils; import java.lang.invoke.WrongMethodTypeException; import java.lang.reflect.InvocationTargetException; @@ -20,12 +16,12 @@ import java.util.*; import static apijson.orm.AbstractSQLConfig.PATTERN_SCHEMA; -import static apijson.orm.SQLConfig.TYPE_ITEM; /**可远程调用的函数类 * @author Lemon */ -public class AbstractFunctionParser implements FunctionParser { +public abstract class AbstractFunctionParser, L extends List> + implements FunctionParser { private static final String TAG = "AbstractFunctionParser"; /**是否解析参数 key 的对应的值,不用手动编码 curObj.getString(key) @@ -41,50 +37,55 @@ public class AbstractFunctionParser implements FunctionParser< // // > - public static Map SCRIPT_EXECUTOR_MAP; - public static Map FUNCTION_MAP; + public static Map, ? extends List>> SCRIPT_EXECUTOR_MAP; + public static Map> FUNCTION_MAP; static { FUNCTION_MAP = new HashMap<>(); SCRIPT_EXECUTOR_MAP = new HashMap<>(); } + private Parser parser; private RequestMethod method; private String tag; private int version; - private JSONObject request; + private String key; + private String parentPath; + private String currentName; + private M request; + private M current; public AbstractFunctionParser() { this(null, null, 0, null); } - public AbstractFunctionParser(RequestMethod method, String tag, int version, @NotNull JSONObject request) { + public AbstractFunctionParser(RequestMethod method, String tag, int version, @NotNull M request) { setMethod(method == null ? RequestMethod.GET : method); setTag(tag); setVersion(version); setRequest(request); } - private Parser parser; - + @NotNull @Override - public Parser getParser() { + public Parser getParser() { return parser; } @Override - public AbstractFunctionParser setParser(Parser parser) { + public AbstractFunctionParser setParser(Parser parser) { this.parser = parser; return this; } + @NotNull @Override public RequestMethod getMethod() { - return method; + return method == null ? RequestMethod.GET : method; } @Override - public AbstractFunctionParser setMethod(RequestMethod method) { + public AbstractFunctionParser setMethod(RequestMethod method) { this.method = method; return this; } @@ -95,7 +96,7 @@ public String getTag() { } @Override - public AbstractFunctionParser setTag(String tag) { + public AbstractFunctionParser setTag(String tag) { this.tag = tag; return this; } @@ -106,73 +107,65 @@ public int getVersion() { } @Override - public AbstractFunctionParser setVersion(int version) { + public AbstractFunctionParser setVersion(int version) { this.version = version; return this; } - private String key; - @Override public String getKey() { return key; } @Override - public AbstractFunctionParser setKey(String key) { + public AbstractFunctionParser setKey(String key) { this.key = key; return this; } - private String parentPath; - @Override public String getParentPath() { return parentPath; } @Override - public AbstractFunctionParser setParentPath(String parentPath) { + public AbstractFunctionParser setParentPath(String parentPath) { this.parentPath = parentPath; return this; } - private String currentName; - @Override public String getCurrentName() { return currentName; } @Override - public AbstractFunctionParser setCurrentName(String currentName) { + public AbstractFunctionParser setCurrentName(String currentName) { this.currentName = currentName; return this; } @NotNull @Override - public JSONObject getRequest() { + public M getRequest() { return request; } @Override - public AbstractFunctionParser setRequest(@NotNull JSONObject request) { + public AbstractFunctionParser setRequest(@NotNull M request) { this.request = request; return this; } - private JSONObject currentObject; - @NotNull @Override - public JSONObject getCurrentObject() { - return currentObject; + public M getCurrentObject() { + return current; } @Override - public AbstractFunctionParser setCurrentObject(@NotNull JSONObject currentObject) { - this.currentObject = currentObject; + public AbstractFunctionParser setCurrentObject(@NotNull M current) { + this.current = current; return this; } @@ -245,16 +238,16 @@ public String getArgStr(String path) { * @param path * @return */ - public JSONObject getArgObj(String path) { - return getArgVal(path, JSONObject.class); + public Map getArgObj(String path) { + return getArgVal(path, Map.class); } /**根据路径取 JSONArray 值 * @param path * @return */ - public JSONArray getArgArr(String path) { - return getArgVal(path, JSONArray.class); + public List getArgArr(String path) { + return getArgVal(path, List.class); } /**根据路径取 List 值 @@ -289,22 +282,22 @@ public T getArgVal(String path) { * @param */ public T getArgVal(String path, Class clazz) { - return getArgVal(path, clazz, true); + return getArgVal(getCurrentObject(), path, clazz, true); } /**根据路径取值 * @param path * @param clazz - * @param tryAll false-仅当前对象,true-本次请求的全局对象以及 Parser 缓存值 + * @param tryAll false-仅当前对象,true-本次请求的全局对象以及 Parser 缓存值 * @return * @param */ - public T getArgVal(String path, Class clazz, boolean tryAll) { - T val = getArgVal(getCurrentObject(), path, clazz); + public T getArgVal(@NotNull M req, String path, Class clazz, boolean tryAll) { + T val = getArgValue(req, path, clazz); if (tryAll == false || val != null) { return val; } - Parser p = getParser(); + Parser p = getParser(); String targetPath = AbstractParser.getValuePath(getParentPath(), path); return p == null ? null : (T) p.getValueByPath(targetPath); } @@ -314,55 +307,110 @@ public T getArgVal(String path, Class clazz, boolean tryAl * @return * @param */ - public static T getArgVal(JSONObject obj, String path) { - return getArgVal(obj, path, null); + public static T getArgVal(Map obj, String path) { + return getArgValue(obj, path, null); } - public static T getArgVal(JSONObject obj, String path, Class clazz) { + + public static T getArgValue(Map obj, String path, Class clazz) { Object v = AbstractParser.getValue(obj, StringUtil.splitPath(path)); - return clazz == null ? (T) v : TypeUtils.cast(v, clazz, ParserConfig.getGlobalInstance()); + + if (clazz == null) { + return (T) v; + } + + // Simple type conversion + try { + if (v == null) { + return null; + } + if (clazz.isInstance(v)) { + return (T) v; + } + if (clazz == String.class) { + return (T) String.valueOf(v); + } + if (clazz == Boolean.class || clazz == boolean.class) { + return (T) Boolean.valueOf(String.valueOf(v)); + } + if (clazz == Integer.class || clazz == int.class) { + return (T) Integer.valueOf(String.valueOf(v)); + } + if (clazz == Long.class || clazz == long.class) { + return (T) Long.valueOf(String.valueOf(v)); + } + if (clazz == Double.class || clazz == double.class) { + return (T) Double.valueOf(String.valueOf(v)); + } + if (clazz == Float.class || clazz == float.class) { + return (T) Float.valueOf(String.valueOf(v)); + } + if (Map.class.isAssignableFrom(clazz)) { + if (v instanceof Map) { + return (T) v; + } + return (T) JSON.parseObject(v); + } + if (List.class.isAssignableFrom(clazz)) { + if (v instanceof List) { + return (T) v; + } + return (T) JSON.parseArray(v); + } + // Fallback to string conversion + return (T) v; + } catch (Exception e) { + return null; + } } /**反射调用 * @param function 例如get(object,key),参数只允许引用,不能直接传值 - * @param currentObject 不作为第一个参数,就不能远程调用invoke,避免死循环 - * @return {@link #invoke(String, JSONObject, boolean)} + * @param current 不作为第一个参数,就不能远程调用invoke,避免死循环 + * @return {@link #invoke(String, M, boolean)} */ @Override - public Object invoke(@NotNull String function, @NotNull JSONObject currentObject) throws Exception { - return invoke(function, currentObject, false); - } + public Object invoke(@NotNull String function, @NotNull M current) throws Exception { + return invoke(function, current, false); + } /**反射调用 * @param function 例如get(object,key),参数只允许引用,不能直接传值 - * @param currentObject 不作为第一个参数,就不能远程调用invoke,避免死循环 + * @param current 不作为第一个参数,就不能远程调用invoke,避免死循环 * @param containRaw 包含原始 SQL 片段 - * @return {@link #invoke(AbstractFunctionParser, String, JSONObject, boolean)} + * @return {@link #invoke(AbstractFunctionParser, String, M, boolean)} */ @Override - public Object invoke(@NotNull String function, @NotNull JSONObject currentObject, boolean containRaw) throws Exception { - return invoke(this, function, currentObject, containRaw); + public Object invoke(@NotNull String function, @NotNull M current, boolean containRaw) throws Exception { + if (StringUtil.isEmpty(function, true)) { + throw new IllegalArgumentException("字符 " + function + " 不合法!"); + } + + return invoke(this, function, current, containRaw); } /**反射调用 * @param parser * @param function 例如get(Map:map,key),参数只允许引用,不能直接传值 - * @param currentObject + * @param current * @return {@link #invoke(AbstractFunctionParser, String, Class[], Object[])} */ - public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull String function, @NotNull JSONObject currentObject, boolean containRaw) throws Exception { + @SuppressWarnings({"unchecked", "rawtypes"}) + public static , L extends List> Object invoke( + @NotNull AbstractFunctionParser parser, @NotNull String function + , @NotNull Map current, boolean containRaw) throws Exception { if (ENABLE_REMOTE_FUNCTION == false) { throw new UnsupportedOperationException("AbstractFunctionParser.ENABLE_REMOTE_FUNCTION" + " == false 时不支持远程函数!如需支持则设置 AbstractFunctionParser.ENABLE_REMOTE_FUNCTION = true !"); } - FunctionBean fb = parseFunction(function, currentObject, false, containRaw); + FunctionBean fb = parseFunction(function, current, false, containRaw); - JSONObject row = FUNCTION_MAP.get(fb.getMethod()); //FIXME fb.getSchema() + "." + fb.getMethod() + Map row = FUNCTION_MAP.get(fb.getMethod()); //FIXME fb.getSchema() + "." + fb.getMethod() if (row == null) { throw new UnsupportedOperationException("不允许调用远程函数 " + fb.getMethod() + " !"); } - String language = row.getString("language"); + String language = (String) row.get("language"); String lang = "java".equalsIgnoreCase(language) ? null : language; if (ENABLE_SCRIPT_FUNCTION == false && lang != null) { @@ -371,25 +419,25 @@ public static Object invoke(@NotNull AbstractFunctionParser 中注册!"); + throw new ClassNotFoundException("找不到脚本语言 " + lang + " 对应的执行引擎!请先依赖相关库并在后端 APIJSONFunctionParser 中注册!"); } - int version = row.getIntValue("version"); + int version = row.get("version") != null ? Integer.parseInt(row.get("version").toString()) : 0; if (parser.getVersion() < version) { throw new UnsupportedOperationException("不允许 version = " + parser.getVersion() + " 的请求调用远程函数 " + fb.getMethod() + " ! 必须满足 version >= " + version + " !"); } - String tag = row.getString("tag"); // TODO 改为 tags,类似 methods 支持多个 tag。或者干脆不要?因为目前非开放请求全都只能后端指定 + String tag = (String) row.get("tag"); // TODO 改为 tags,类似 methods 支持多个 tag。或者干脆不要?因为目前非开放请求全都只能后端指定 if (tag != null && tag.equals(parser.getTag()) == false) { throw new UnsupportedOperationException("不允许 tag = " + parser.getTag() + " 的请求调用远程函数 " + fb.getMethod() + " ! 必须满足 tag = " + tag + " !"); } - String[] methods = StringUtil.split(row.getString("methods")); + String[] methods = StringUtil.split((String) row.get("methods")); List ml = methods == null || methods.length <= 0 ? null : Arrays.asList(methods); if (ml != null && ml.contains(parser.getMethod().toString()) == false) { throw new UnsupportedOperationException("不允许 method = " + parser.getMethod() + " 的请求调用远程函数 " + fb.getMethod() + " ! 必须满足 method 在 " + Arrays.toString(methods) + "内 !"); } try { - return invoke(parser, fb.getMethod(), fb.getTypes(), fb.getValues(), row.getString("returnType"), currentObject, SCRIPT_EXECUTOR_MAP.get(lang)); + return invoke(parser, fb.getMethod(), fb.getTypes(), fb.getValues(), (String) row.get("returnType"), current, SCRIPT_EXECUTOR_MAP.get(lang)); } catch (Exception e) { if (e instanceof NoSuchMethodException) { @@ -419,10 +467,12 @@ public static Object invoke(@NotNull AbstractFunctionParser Object invoke(@NotNull AbstractFunctionParser parser, @NotNull String methodName + @SuppressWarnings({"unchecked", "rawtypes"}) + public static , L extends List> Object invoke( + @NotNull AbstractFunctionParser parser, @NotNull String methodName , @NotNull Class[] parameterTypes, @NotNull Object[] args) throws Exception { return invoke(parser, methodName, parameterTypes, args, null, null, null); } @@ -432,19 +482,21 @@ public static Object invoke(@NotNull AbstractFunctionParser Object invoke(@NotNull AbstractFunctionParser parser, @NotNull String methodName + @SuppressWarnings({"unchecked", "rawtypes"}) + public static , L extends List> Object invoke(@NotNull AbstractFunctionParser parser, @NotNull String methodName , @NotNull Class[] parameterTypes, @NotNull Object[] args, String returnType - , JSONObject currentObject, ScriptExecutor scriptExecutor) throws Exception { + , Map current, ScriptExecutor scriptExecutor) throws Exception { if (scriptExecutor != null) { - return invokeScript(parser, methodName, parameterTypes, args, returnType, currentObject, scriptExecutor); + return invokeScript(parser, methodName, parameterTypes, args, returnType, current, scriptExecutor); } - Method m = parser.getClass().getMethod(methodName, parameterTypes); // 不用判空,拿不到就会抛异常 + Class cls = parser.getClass(); + Method m = cls.getMethod(methodName, parameterTypes); // 不用判空,拿不到就会抛异常 if (Log.DEBUG) { String rt = Log.DEBUG && m.getReturnType() != null ? m.getReturnType().getSimpleName() : null; @@ -470,13 +522,16 @@ public static Object invoke(@NotNull AbstractFunctionParser Object invokeScript(@NotNull AbstractFunctionParser parser, @NotNull String methodName - , @NotNull Class[] parameterTypes, @NotNull Object[] args, String returnType, JSONObject currentObject, ScriptExecutor scriptExecutor) throws Exception { - Object result = scriptExecutor.execute(parser, currentObject, methodName, args); + @SuppressWarnings({"unchecked", "rawtypes"}) + public static , L extends List> Object invokeScript( + @NotNull AbstractFunctionParser parser, @NotNull String methodName + , @NotNull Class[] parameterTypes, @NotNull Object[] args, String returnType + , Map current, ScriptExecutor scriptExecutor) throws Exception { + Object result = scriptExecutor.execute(parser, current, methodName, args); if (Log.DEBUG && result != null) { Class rt = result.getClass(); // 作为远程函数的 js 类型应该只有 JSON 的几种类型 String fullReturnType = (StringUtil.isSmallName(returnType) @@ -516,7 +571,7 @@ public static Object invokeScript(@NotNull AbstractFunctionPa * @throws Exception */ @NotNull - public static FunctionBean parseFunction(@NotNull String function, @NotNull JSONObject request, boolean isSQLFunction) throws Exception { + public static FunctionBean parseFunction(@NotNull String function, @NotNull Map request, boolean isSQLFunction) throws Exception { return parseFunction(function, request, isSQLFunction, false); } /**解析函数,自动解析的值类型只支持 Boolean, Number, String, Map, List @@ -527,7 +582,7 @@ public static FunctionBean parseFunction(@NotNull String function, @NotNull JSON * @return * @throws Exception */ - public static FunctionBean parseFunction(@NotNull String function, @NotNull JSONObject request, boolean isSQLFunction, boolean containRaw) throws Exception { + public static FunctionBean parseFunction(@NotNull String function, @NotNull Map request, boolean isSQLFunction, boolean containRaw) throws Exception { int start = function.indexOf("("); int end = function.lastIndexOf(")"); @@ -572,7 +627,7 @@ public static FunctionBean parseFunction(@NotNull String function, @NotNull JSON } if (v instanceof Boolean) { - types[i] = Boolean.class; //只支持JSON的几种类型 + types[i] = Boolean.class; //只支持JSON的几种类型 } // 怎么都有 bug,如果是引用的值,很多情况下无法指定 // 用 1L 指定为 Long ? 其它的默认按长度分配为 Integer 或 Long? //else if (v instanceof Long || v instanceof Integer || v instanceof Short) { // types[i] = Long.class; @@ -591,7 +646,8 @@ else if (v instanceof Map) { // 泛型兼容? // JSONObject else if (v instanceof Collection) { // 泛型兼容? // JSONArray types[i] = List.class; //性能比较差 - values[i] = TypeUtils.cast(v, List.class, ParserConfig.getGlobalInstance()); + List list = new ArrayList<>((Collection) v); + values[i] = list; // TypeUtils.cast(v, List.class, ParserConfig.getGlobalInstance()); } else { throw new UnsupportedDataTypeException(keys[i] + ":value 中value不合法!远程函数 key():" @@ -601,7 +657,8 @@ else if (v instanceof Collection) { // 泛型兼容? // JSONArray } else { types = new Class[length + 1]; - types[0] = JSONObject.class; + //types[0] = Object.class; // 泛型擦除 JSON.JSON_OBJECT_CLASS; + types[0] = JSON.JSON_OBJECT_CLASS; values = new Object[length + 1]; values[0] = request; @@ -681,17 +738,17 @@ public static String getFunction(String method, String[] keys) { return f; } - public static T getArgValue(@NotNull JSONObject currentObject, String keyOrValue) { - return getArgValue(currentObject, keyOrValue, false); + public static T getArgValue(@NotNull Map current, String keyOrValue) { + return getArgValue(current, keyOrValue, false); } - public static T getArgValue(@NotNull JSONObject currentObject, String keyOrValue, boolean containRaw) { + public static T getArgValue(@NotNull Map current, String keyOrValue, boolean containRaw) { if (keyOrValue == null) { return null; } if (keyOrValue.endsWith("`") && keyOrValue.substring(1).indexOf("`") == keyOrValue.length() - 2) { - return (T) currentObject.get(keyOrValue.substring(1, keyOrValue.length() - 1)); + return (T) current.get(keyOrValue.substring(1, keyOrValue.length() - 1)); } if (keyOrValue.endsWith("'") && keyOrValue.substring(1).indexOf("'") == keyOrValue.length() - 2) { @@ -705,7 +762,7 @@ public static T getArgValue(@NotNull JSONObject currentObject, String keyOrV } if (StringUtil.isName(keyOrValue.startsWith("@") ? keyOrValue.substring(1) : keyOrValue)) { - return (T) currentObject.get(keyOrValue); + return (T) current.get(keyOrValue); } if ("true".equals(keyOrValue)) { @@ -717,7 +774,7 @@ public static T getArgValue(@NotNull JSONObject currentObject, String keyOrV // 性能更好,但居然非法格式也不报错 //try { - // val = Boolean.valueOf(keyOrValue); // JSON.parse(keyOrValue); + // val = Boolean.valueOf(keyOrValue); // parseJSON(keyOrValue); // return (T) val; //} //catch (Throwable e) { @@ -727,7 +784,7 @@ public static T getArgValue(@NotNull JSONObject currentObject, String keyOrV //} try { - val = Double.valueOf(keyOrValue); // JSON.parse(keyOrValue); + val = Double.valueOf(keyOrValue); // parseJSON(keyOrValue); return (T) val; } catch (Throwable e) { @@ -736,7 +793,7 @@ public static T getArgValue(@NotNull JSONObject currentObject, String keyOrV "} catch (Throwable e) = " + e.getMessage()); } - return (T) currentObject.get(keyOrValue); + return (T) current.get(keyOrValue); } public static class FunctionBean { @@ -825,4 +882,81 @@ public String toFunctionCallString(boolean useValue, String quote) { } + /** + * 获取JSON对象 + * @param TODO + * @param req + * @param key + * @param clazz + * @return + * @throws Exception + */ + public V getArgVal(@NotNull M req, String key, Class clazz) throws Exception { + // Convert to JSONObject for backward compatibility, replace with proper implementation later + return getArgVal(req, key, clazz, false); + } + + /** + * 获取参数值 + * @param key + * @param clazz 如果有clazz就返回对应的类型,否则返回原始类型 + * @param defaultValue + * @return + * @throws Exception + */ + public V getArgVal(String key, Class clazz, boolean defaultValue) throws Exception { + Object obj = parser != null && apijson.JSONObject.isArrayKey(key) ? AbstractParser.getValue(request, key.split("\\,")) : request.get(key); + + if (clazz == null) { + return (V) obj; + } + + // Replace TypeUtils with appropriate casting method + try { + if (obj == null) { + return null; + } + if (clazz.isInstance(obj)) { + return (V) obj; + } + if (clazz == String.class) { + return (V) String.valueOf(obj); + } + if (clazz == Boolean.class || clazz == boolean.class) { + return (V) Boolean.valueOf(String.valueOf(obj)); + } + if (clazz == Integer.class || clazz == int.class) { + return (V) Integer.valueOf(String.valueOf(obj)); + } + if (clazz == Long.class || clazz == long.class) { + return (V) Long.valueOf(String.valueOf(obj)); + } + if (clazz == Double.class || clazz == double.class) { + return (V) Double.valueOf(String.valueOf(obj)); + } + if (clazz == Float.class || clazz == float.class) { + return (V) Float.valueOf(String.valueOf(obj)); + } + if (Map.class.isAssignableFrom(clazz)) { + if (obj instanceof Map) { + return (V) obj; + } + return (V) JSON.parseObject(obj); + } + if (List.class.isAssignableFrom(clazz)) { + if (obj instanceof List) { + return (V) obj; + } + return (V) JSON.parseArray(obj); + } + // Fallback to string conversion + return (V) obj; + } catch (Exception e) { + if (defaultValue) { + return null; + } + throw e; + } + } + } \ No newline at end of file diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java index 0a35761cb..9bca5becb 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java @@ -5,29 +5,22 @@ package apijson.orm; -import apijson.JSONResponse; -import apijson.Log; -import apijson.NotNull; -import apijson.RequestMethod; -import apijson.StringUtil; +import apijson.*; import apijson.orm.AbstractFunctionParser.FunctionBean; import apijson.orm.exception.ConflictException; import apijson.orm.exception.CommonException; import apijson.orm.exception.NotExistException; import apijson.orm.exception.UnsupportedDataTypeException; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.serializer.SerializerFeature; import java.rmi.ServerException; import java.util.*; 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.JSONRequest.KEY_QUERY; +import static apijson.JSONRequest.*; import static apijson.RequestMethod.POST; import static apijson.RequestMethod.PUT; import static apijson.orm.SQLConfig.TYPE_ITEM; @@ -36,29 +29,30 @@ /**简化Parser,getObject和getArray(getArrayConfig)都能用 * @author Lemon */ -public abstract class AbstractObjectParser implements ObjectParser { +public abstract class AbstractObjectParser, L extends List> + implements ObjectParser { private static final String TAG = "AbstractObjectParser"; @NotNull - protected AbstractParser parser; + protected AbstractParser parser; @Override - public AbstractParser getParser() { + public AbstractParser getParser() { return parser; } @Override - public AbstractObjectParser setParser(Parser parser) { - this.parser = (AbstractParser) parser; + public AbstractObjectParser setParser(Parser parser) { + this.parser = (AbstractParser) parser; return this; } - protected JSONObject request;//不用final是为了recycle + protected M request;//不用final是为了recycle protected String parentPath;//不用final是为了recycle - protected SQLConfig arrayConfig;//不用final是为了recycle + protected SQLConfig arrayConfig;//不用final是为了recycle protected boolean isSubquery; protected final int type; protected final String arrayTable; - protected final List joinList; + protected final List> joinList; protected final boolean isTable; protected final boolean isArrayMainTable; @@ -70,10 +64,10 @@ public AbstractObjectParser setParser(Parser parser) { /**for single object */ - public AbstractObjectParser(@NotNull JSONObject request, String parentPath, SQLConfig arrayConfig + public AbstractObjectParser(@NotNull M request, String parentPath, SQLConfig arrayConfig , boolean isSubquery, boolean isTable, boolean isArrayMainTable) throws Exception { if (request == null) { - throw new IllegalArgumentException(TAG + ".ObjectParser request == null!!!"); + throw new IllegalArgumentException(TAG + ".ObjectParser request == null!!!"); } this.request = request; this.parentPath = parentPath; @@ -98,15 +92,15 @@ public AbstractObjectParser(@NotNull JSONObject request, String parentPath, SQLC this.drop = false; } else { - this.tri = request.getBooleanValue(KEY_TRY); - this.drop = request.getBooleanValue(KEY_DROP); + this.tri = getBooleanValue(request, KEY_TRY); + this.drop = getBooleanValue(request, KEY_DROP); request.remove(KEY_TRY); request.remove(KEY_DROP); } if (isTable) { - String raw = request.getString(JSONRequest.KEY_RAW); + String raw = getString(request, apijson.JSONObject.KEY_RAW); String[] rks = StringUtil.split(raw); rawKeyList = rks == null || rks.length <= 0 ? null : Arrays.asList(rks); } @@ -118,19 +112,19 @@ public String getParentPath() { } @Override - public AbstractObjectParser setParentPath(String parentPath) { + public AbstractObjectParser setParentPath(String parentPath) { this.parentPath = parentPath; return this; } - protected JSONObject cache; + protected M cache; @Override - public JSONObject getCache() { + public M getCache() { return cache; } @Override - public AbstractObjectParser setCache(JSONObject cache) { + public AbstractObjectParser setCache(M cache) { this.cache = cache; return this; } @@ -139,7 +133,7 @@ public AbstractObjectParser setCache(JSONObject cache) { public int getPosition() { return position; } - public AbstractObjectParser setPosition(int position) { + public AbstractObjectParser setPosition(int position) { this.position = position; return this; } @@ -167,9 +161,9 @@ public boolean isBreakParse() { protected boolean isReuse; protected String path; - protected JSONObject response; - protected JSONObject sqlRequest; - protected JSONObject sqlResponse; + protected M response; + protected M sqlRequest; + protected M sqlResponse; /** * 自定义关键词 */ @@ -185,7 +179,7 @@ public boolean isBreakParse() { /** * 子对象 */ - protected Map childMap; + protected Map childMap; private int objectCount; private int arrayCount; @@ -197,7 +191,7 @@ public boolean isBreakParse() { * @throws Exception */ @Override - public AbstractObjectParser parse(String name, boolean isReuse) throws Exception { + public AbstractObjectParser parse(String name, boolean isReuse) throws Exception { if (isInvalidate() == false) { this.isReuse = isReuse; this.name = name; @@ -207,17 +201,17 @@ public AbstractObjectParser parse(String name, boolean isReuse) throws Exception this.table = tentry.getKey(); this.alias = tentry.getValue(); - Log.d(TAG, "AbstractObjectParser parentPath = " + parentPath + "; name = " + name + "; table = " + table + "; alias = " + alias); - Log.d(TAG, "AbstractObjectParser type = " + type + "; isTable = " + isTable + "; isArrayMainTable = " + isArrayMainTable); - Log.d(TAG, "AbstractObjectParser isEmpty = " + request.isEmpty() + "; tri = " + tri + "; drop = " + drop); + Log.d(TAG, "AbstractObjectParser parentPath = " + parentPath + "; name = " + name + "; table = " + table + "; alias = " + alias); + Log.d(TAG, "AbstractObjectParser type = " + type + "; isTable = " + isTable + "; isArrayMainTable = " + isArrayMainTable); + Log.d(TAG, "AbstractObjectParser isEmpty = " + request.isEmpty() + "; tri = " + tri + "; drop = " + drop); breakParse = false; - response = new JSONObject(true); // must init + response = JSON.createJSONObject(); // must init sqlResponse = null; // must init if (isReuse == false) { - sqlRequest = new JSONObject(true); // must init + sqlRequest = JSON.createJSONObject(); // must init customMap = null; // must init functionMap = null; // must init @@ -227,14 +221,14 @@ public AbstractObjectParser parse(String name, boolean isReuse) throws Exception if (set != null && set.isEmpty() == false) { // 判断换取少几个变量的初始化是否值得? if (isTable) { // 非Table下必须保证原有顺序!否则 count,page 会丢, total@:"/[]/total" 会在[]:{}前执行! customMap = new LinkedHashMap(); - childMap = new LinkedHashMap(); + childMap = new LinkedHashMap(); } functionMap = new LinkedHashMap>();//必须执行 // 条件 <<<<<<<<<<<<<<<<<<< List whereList = null; if (method == PUT) { // 这里只有PUTArray需要处理 || method == DELETE) { - String[] combine = StringUtil.split(request.getString(KEY_COMBINE)); + String[] combine = StringUtil.split(getString(request, KEY_COMBINE)); if (combine != null) { String w; for (int i = 0; i < combine.length; i++) { // 去除 &,|,! 前缀 @@ -246,16 +240,16 @@ public AbstractObjectParser parse(String name, boolean isReuse) throws Exception } // Arrays.asList() 返回值不支持 add 方法! whereList = new ArrayList(Arrays.asList(combine != null ? combine : new String[]{})); - whereList.add(apijson.JSONRequest.KEY_ID); - whereList.add(apijson.JSONRequest.KEY_ID_IN); - // whereList.add(apijson.JSONRequest.KEY_USER_ID); - // whereList.add(apijson.JSONRequest.KEY_USER_ID_IN); + 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); } // 条件>>>>>>>>>>>>>>>>>>> int index = 0; // hasOtherKeyNotFun = false; - JSONObject viceItem = null; + M viceItem = null; for (Entry entry : set) { if (isBreakParse()) { @@ -273,8 +267,8 @@ public AbstractObjectParser parse(String name, boolean isReuse) throws Exception // 没有执行校验流程的情况,比如url head, sql@子查询, sql@ method=GET Object obj = key.endsWith("@") ? request.get(key) : null; - if (obj instanceof JSONObject) { - ((JSONObject) obj).put(apijson.JSONObject.KEY_METHOD, GET); + if (obj instanceof Map) { + ((Map) obj).put(apijson.JSONObject.KEY_METHOD, GET); } try { @@ -283,36 +277,36 @@ public AbstractObjectParser parse(String name, boolean isReuse) throws Exception // hasOtherKeyNotFun = true; // } - if (startsWithAt || key.endsWith("@") || (key.endsWith("<>") && value instanceof JSONObject)) { + if (startsWithAt || key.endsWith("@") || (key.endsWith("<>") && value instanceof Map)) { if (onParse(key, value) == false) { invalidate(); } } - else if (value instanceof JSONObject) { // JSONObject,往下一级提取 + else if (value instanceof Map) { // JSONRequest,往下一级提取 if (childMap != null) { // 添加到childMap,最后再解析 - childMap.put(key, (JSONObject) value); + childMap.put(key, (M) value); } else { // 直接解析并替换原来的,[]:{} 内必须直接解析,否则会因为丢掉count等属性,并且total@:"/[]/total"必须在[]:{} 后! - JSON cache = index <= 0 || type != TYPE_ITEM || viceItem == null ? null : viceItem.getJSONObject(key); - JSON result = onChildParse(index, key, (JSONObject) value, cache); + Object cache = index <= 0 || type != TYPE_ITEM || viceItem == null ? null : JSON.get(viceItem, key); + Object result = onChildParse(index, key, (M) value, cache); if (index <= 0 && type == TYPE_ITEM) { - JSONObject mainItem = (JSONObject) result; - viceItem = result == null ? null : (JSONObject) mainItem.remove(AbstractSQLExecutor.KEY_VICE_ITEM); + M mainItem = (M) result; + viceItem = result == null ? null : (M) mainItem.remove(AbstractSQLExecutor.KEY_VICE_ITEM); } response.put(key, result); index ++; } } - else if ((_method == POST || _method == PUT) && value instanceof JSONArray - && JSONRequest.isTableArray(key)) { // JSONArray,批量新增或修改,往下一级提取 - onTableArrayParse(key, (JSONArray) value); + else if ((_method == POST || _method == PUT) && value instanceof List + && apijson.JSONObject.isTableArray(key)) { // L,批量新增或修改,往下一级提取 + onTableArrayParse(key, (L) value); } - else if (_method == PUT && value instanceof JSONArray && (whereList == null || whereList.contains(key) == false) - && StringUtil.isName(key.replaceFirst("[+-]$", ""))) { // PUT JSONArray - onPUTArrayParse(key, (JSONArray) value); + else if (_method == PUT && value instanceof List && (whereList == null || whereList.contains(key) == false) + && StringUtil.isName(key.replaceFirst("[+-]$", ""))) { // PUT L + onPUTArrayParse(key, (L) value); } - else { // JSONArray 或其它 Object,直接填充 + else { // L 或其它 Object,直接填充 if (onParse(key, value) == false) { invalidate(); } @@ -332,38 +326,38 @@ else if (_method == PUT && value instanceof JSONArray && (whereList == null || w String db = parser.getGlobalDatabase(); if (db != null) { - sqlRequest.putIfAbsent(JSONRequest.KEY_DATABASE, db); + sqlRequest.putIfAbsent(apijson.JSONObject.KEY_DATABASE, db); } String ds = parser.getGlobalDatasource(); if (ds != null) { - sqlRequest.putIfAbsent(JSONRequest.KEY_DATASOURCE, ds); + sqlRequest.putIfAbsent(apijson.JSONObject.KEY_DATASOURCE, ds); } String ns = parser.getGlobalNamespace(); if (ns != null) { - sqlRequest.putIfAbsent(JSONRequest.KEY_NAMESPACE, ns); + sqlRequest.putIfAbsent(apijson.JSONObject.KEY_NAMESPACE, ns); } String cl = parser.getGlobalCatalog(); if (cl != null) { - sqlRequest.putIfAbsent(JSONRequest.KEY_CATALOG, cl); + sqlRequest.putIfAbsent(apijson.JSONObject.KEY_CATALOG, cl); } String sch = parser.getGlobalSchema(); if (sch != null) { - sqlRequest.putIfAbsent(JSONRequest.KEY_SCHEMA, sch); + sqlRequest.putIfAbsent(apijson.JSONObject.KEY_SCHEMA, sch); } if (isSubquery == false) { // 解决 SQL 语法报错,子查询不能 EXPLAIN Boolean exp = parser.getGlobalExplain(); if (sch != null) { - sqlRequest.putIfAbsent(JSONRequest.KEY_EXPLAIN, exp); + sqlRequest.putIfAbsent(apijson.JSONObject.KEY_EXPLAIN, exp); } String cache = parser.getGlobalCache(); if (cache != null) { - sqlRequest.putIfAbsent(JSONRequest.KEY_CACHE, cache); + sqlRequest.putIfAbsent(apijson.JSONObject.KEY_CACHE, cache); } } } @@ -396,36 +390,35 @@ else if (_method == PUT && value instanceof JSONArray && (whereList == null || w @Override public boolean onParse(@NotNull String key, @NotNull Object value) throws Exception { if (key.endsWith("@")) { // StringUtil.isPath((String) value)) { - // [] 内主表 position > 0 时,用来生成 SQLConfig 的键值对全都忽略,不解析 - if (value instanceof JSONObject) { // key{}@ getRealKey, SQL 子查询对象,JSONObject -> SQLConfig.getSQL + // [] 内主表 position > 0 时,用来生成 SQLConfig 的键值对全都忽略,不解析 + if (value instanceof Map) { // key{}@ getRealKey, SQL 子查询对象,JSONRequest -> SQLConfig.getSQL String replaceKey = key.substring(0, key.length() - 1); - JSONObject subquery = (JSONObject) value; - String range = subquery.getString(JSONRequest.KEY_SUBQUERY_RANGE); - if (range != null && JSONRequest.SUBQUERY_RANGE_ALL.equals(range) == false - && JSONRequest.SUBQUERY_RANGE_ANY.equals(range) == false) { + M subquery = (M) value; + String range = getString(subquery, KEY_SUBQUERY_RANGE); + if (range != null && SUBQUERY_RANGE_ALL.equals(range) == false && SUBQUERY_RANGE_ANY.equals(range) == false) { throw new IllegalArgumentException("子查询 " + path + "/" + key + ":{ range:value } 中 value 只能为 [" - + JSONRequest.SUBQUERY_RANGE_ALL + ", " + JSONRequest.SUBQUERY_RANGE_ANY + "] 中的一个!"); + + SUBQUERY_RANGE_ALL + ", " + SUBQUERY_RANGE_ANY + "] 中的一个!"); } - JSONArray arr = parser.onArrayParse(subquery, path, key, true, null); + L arr = parser.onArrayParse(subquery, path, key, true, null); - JSONObject obj = arr == null || arr.isEmpty() ? null : arr.getJSONObject(0); + M obj = arr == null || arr.isEmpty() ? null : JSON.get(arr, 0); if (obj == null) { throw new Exception("服务器内部错误,解析子查询 " + path + "/" + key + ":{ } 为 Subquery 对象失败!"); } - String from = subquery.getString(JSONRequest.KEY_SUBQUERY_FROM); + String from = getString(subquery, apijson.JSONRequest.KEY_SUBQUERY_FROM); boolean isEmpty = StringUtil.isEmpty(from); - JSONObject arrObj = isEmpty ? null : obj.getJSONObject(from); + M arrObj = isEmpty ? null : JSON.get(obj, from); if (isEmpty) { Set> set = obj.entrySet(); for (Entry e : set) { String k = e == null ? null : e.getKey(); Object v = k == null ? null : e.getValue(); - if (v instanceof JSONObject && JSONRequest.isTableKey(k)) { + if (v instanceof Map && apijson.JSONObject.isTableKey(k)) { from = k; - arrObj = (JSONObject) v; + arrObj = (M) v; break; } } @@ -436,7 +429,7 @@ public boolean onParse(@NotNull String key, @NotNull Object value) throws Except + key + ":{ from:value } 中 value 对应的主表对象 " + from + ":{} 不存在!"); } - SQLConfig cfg = (SQLConfig) arrObj.get(AbstractParser.KEY_CONFIG); + SQLConfig cfg = (SQLConfig) arrObj.get(AbstractParser.KEY_CONFIG); if (cfg == null) { throw new NotExistException(TAG + ".onParse cfg == null"); } @@ -474,9 +467,9 @@ else if (value instanceof String) { // //key{}@ getRealKey, 引用赋值路径 } // 非查询关键词 @key 不影响查询,直接跳过 - if (isTable && (key.startsWith("@") == false || JSONRequest.TABLE_KEY_LIST.contains(key))) { + if (isTable && (key.startsWith("@") == false || apijson.JSONObject.TABLE_KEY_LIST.contains(key))) { Log.e(TAG, "onParse isTable && (key.startsWith(@) == false" - + " || JSONRequest.TABLE_KEY_LIST.contains(key)) >> return null;"); + + " || apijson.JSONObject.TABLE_KEY_LIST.contains(key)) >> return null;"); // FIXME getCache() != null 时 return true,解决 RIGHT/OUTER/FOREIGN JOIN 主表无数据导致副表数据也不返回 return false; // 获取不到就不用再做无效的 query 了。不考虑 Table:{Table:{}} 嵌套 } @@ -488,18 +481,18 @@ else if (value instanceof String) { // //key{}@ getRealKey, 引用赋值路径 // if (target instanceof Map) { // target 可能是从 requestObject 里取出的 {} // if (isTable || targetPath.endsWith("[]/" + JSONResponse.KEY_INFO) == false) { // Log.d(TAG, "onParse target instanceof Map >> return false;"); -// return false; // FIXME 这个判断现在来看是否还有必要?为啥不允许为 JSONObject ?以前可能因为防止二次遍历再解析,现在只有一次遍历 +// return false; // FIXME 这个判断现在来看是否还有必要?为啥不允许为 JSONRequest ?以前可能因为防止二次遍历再解析,现在只有一次遍历 // } // } // -// // FIXME 这个判断现在来看是否还有必要?为啥不允许为 JSONObject ?以前可能因为防止二次遍历再解析,现在只有一次遍历 +// // FIXME 这个判断现在来看是否还有必要?为啥不允许为 JSONRequest ?以前可能因为防止二次遍历再解析,现在只有一次遍历 // if (targetPath.equals(target)) { // 必须 valuePath 和保证 getValueByPath 传进去的一致! // Log.d(TAG, "onParse targetPath.equals(target) >>"); // // //非查询关键词 @key 不影响查询,直接跳过 -// if (isTable && (key.startsWith("@") == false || JSONRequest.TABLE_KEY_LIST.contains(key))) { +// if (isTable && (key.startsWith("@") == false || apijson.JSONObject.TABLE_KEY_LIST.contains(key))) { // Log.e(TAG, "onParse isTable && (key.startsWith(@) == false" -// + " || JSONRequest.TABLE_KEY_LIST.contains(key)) >> return null;"); +// + " || apijson.JSONObject.TABLE_KEY_LIST.contains(key)) >> return null;"); // return false;//获取不到就不用再做无效的query了。不考虑 Table:{Table:{}}嵌套 // } else { // Log.d(TAG, "onParse isTable(table) == false >> return true;"); @@ -554,7 +547,7 @@ else if (isPlus) { functionMap.put(type, map); } } - else if (isTable && key.startsWith("@") && JSONRequest.TABLE_KEY_LIST.contains(key) == false) { + else if (isTable && key.startsWith("@") && apijson.JSONObject.TABLE_KEY_LIST.contains(key) == false) { customMap.put(key, value); } else { @@ -575,11 +568,11 @@ else if (isTable && key.startsWith("@") && JSONRequest.TABLE_KEY_LIST.contains(k * @throws Exception */ @Override - public JSON onChildParse(int index, String key, JSONObject value, JSON cache) throws Exception { + public Object onChildParse(int index, String key, M value, Object cache) throws Exception { boolean isFirst = index <= 0; boolean isMain = isFirst && type == TYPE_ITEM; - JSON child; + Object child; boolean isEmpty; if (apijson.JSONObject.isArrayKey(key)) { // APIJSON Array @@ -597,9 +590,9 @@ public JSON onChildParse(int index, String key, JSONObject value, JSON cache) th } } - String query = value.getString(KEY_QUERY); - child = parser.onArrayParse(value, path, key, isSubquery, cache instanceof JSONArray ? (JSONArray) cache : null); - isEmpty = child == null || ((JSONArray) child).isEmpty(); + String query = getString(value, KEY_QUERY); + child = parser.onArrayParse(value, path, key, isSubquery, cache instanceof List ? (L) cache : null); + isEmpty = child == null || ((List) child).isEmpty(); if ("2".equals(query) || "ALL".equals(query)) { // 不判断 isEmpty,因为分页数据可能只是某页没有 String totalKey = JSONResponse.formatArrayKey(key) + "Total"; @@ -619,7 +612,7 @@ public JSON onChildParse(int index, String key, JSONObject value, JSON cache) th } } else { //APIJSON Object - boolean isTableKey = JSONRequest.isTableKey(Pair.parseEntry(key, true).getKey()); + boolean isTableKey = apijson.JSONObject.isTableKey(Pair.parseEntry(key, true).getKey()); if (type == TYPE_ITEM && isTableKey == false) { throw new IllegalArgumentException(parentPath + "/" + key + ":{} 不合法!" + "数组 []:{} 中每个 key:{} 都必须是表 TableKey:{} 或 数组 arrayKey[]:{} !"); @@ -636,16 +629,16 @@ public JSON onChildParse(int index, String key, JSONObject value, JSON cache) th } child = parser.onObjectParse(value, path, key, isMain ? arrayConfig.setType(SQLConfig.TYPE_ITEM_CHILD_0) : null - , isSubquery, cache instanceof JSONObject ? (JSONObject) cache : null); + , isSubquery, cache instanceof Map ? (M) cache : null); - isEmpty = child == null || ((JSONObject) child).isEmpty(); + isEmpty = child == null || ((Map) child).isEmpty(); if (isFirst && isEmpty) { invalidate(); } } // Log.i(TAG, "onChildParse ObjectParser.onParse key = " + key + "; child = " + child); - return isEmpty ? null : child;//只添加! isChildEmpty的值,可能数据库返回数据不够count + return isEmpty ? null : child; // 只添加! isChildEmpty的值,可能数据库返回数据不够count } @@ -657,7 +650,7 @@ public JSON onChildParse(int index, String key, JSONObject value, JSON cache) th * @throws Exception */ @Override - public void onPUTArrayParse(@NotNull String key, @NotNull JSONArray array) throws Exception { + public void onPUTArrayParse(@NotNull String key, @NotNull L array) throws Exception { if (isTable == false || array.isEmpty()) { sqlRequest.put(key, array); Log.e(TAG, "onPUTArrayParse isTable == false || array == null || array.isEmpty() >> return;"); @@ -673,15 +666,15 @@ public void onPUTArrayParse(@NotNull String key, @NotNull JSONArray array) throw sqlRequest.put(key, array); return; } - String realKey = AbstractSQLConfig.getRealKey(method, key, false, false); + String realKey = AbstractSQLConfig.gainRealKey(method, key, false, false); //GET > add all 或 remove all > PUT > remove key //GET <<<<<<<<<<<<<<<<<<<<<<<<< - JSONObject rq = new JSONObject(true); - rq.put(JSONRequest.KEY_ID, request.get(JSONRequest.KEY_ID)); - rq.put(JSONRequest.KEY_COLUMN, realKey); - JSONObject rp = parseResponse(RequestMethod.GET, table, null, rq, null, false); + M rq = JSON.createJSONObject(); + rq.put(apijson.JSONObject.KEY_ID, request.get(apijson.JSONObject.KEY_ID)); + rq.put(apijson.JSONObject.KEY_COLUMN, realKey); + M rp = parseResponse(RequestMethod.GET, table, null, rq, null, false); //GET >>>>>>>>>>>>>>>>>>>>>>>>> @@ -689,22 +682,22 @@ public void onPUTArrayParse(@NotNull String key, @NotNull JSONArray array) throw Object target = rp == null ? null : rp.get(realKey); if (target instanceof String) { try { - target = JSON.parse((String) target); + target = parseJSON((String) target); } catch (Throwable e) { if (Log.DEBUG) { Log.e(TAG, "try {\n" + - "\t\t\t\ttarget = JSON.parse((String) target);\n" + + "\t\t\t\ttarget = parseJSON((String) target);\n" + "\t\t\t}\n" + "\t\t\tcatch (Throwable e) = " + e.getMessage()); } } } - if (apijson.JSON.isBooleanOrNumberOrString(target)) { + if (apijson.JSON.isBoolOrNumOrStr(target)) { throw new NullPointerException("PUT " + path + ", " + realKey + " 类型为 " + target.getClass().getSimpleName() + "," + "不支持 Boolean, String, Number 等类型字段使用 'key+': [] 或 'key-': [] !" - + "对应字段在数据库的值必须为 JSONArray, JSONObject 中的一种!" - + "值为 JSONObject 类型时传参必须是 'key+': [{'key': value, 'key2': value2}] 或 'key-': ['key', 'key2'] !" + + "对应字段在数据库的值必须为 L, JSONRequest 中的一种!" + + "值为 JSONRequest 类型时传参必须是 'key+': [{'key': value, 'key2': value2}] 或 'key-': ['key', 'key2'] !" ); } @@ -717,12 +710,12 @@ public void onPUTArrayParse(@NotNull String key, @NotNull JSONArray array) throw if (isAdd == false) { throw new NullPointerException("PUT " + path + ", " + realKey + (target == null ? " 值为 null,不支持移除!" : " 类型为 " + target.getClass().getSimpleName() + ",不支持这样移除!") - + "对应字段在数据库的值必须为 JSONArray, JSONObject 中的一种,且 key- 移除时,本身的值不能为 null!" - + "值为 JSONObject 类型时传参必须是 'key+': [{'key': value, 'key2': value2}] 或 'key-': ['key', 'key2'] !" + + "对应字段在数据库的值必须为 L, JSONRequest 中的一种,且 key- 移除时,本身的值不能为 null!" + + "值为 JSONRequest 类型时传参必须是 'key+': [{'key': value, 'key2': value2}] 或 'key-': ['key', 'key2'] !" ); } - targetArray = new JSONArray(); + targetArray = JSON.createJSONArray(); } for (int i = 0; i < array.size(); i++) { @@ -739,7 +732,7 @@ public void onPUTArrayParse(@NotNull String key, @NotNull JSONArray array) throw targetArray.add(obj); } else { if (obj != null && obj instanceof Map == false) { - throw new ConflictException("PUT " + path + ", " + key + "/" + i + " 必须为 JSONObject {} !"); + throw new ConflictException("PUT " + path + ", " + key + "/" + i + " 必须为 JSONRequest {} !"); } targetObj.putAll((Map) obj); } @@ -764,23 +757,23 @@ public void onPUTArrayParse(@NotNull String key, @NotNull JSONArray array) throw //add all 或 remove all >>>>>>>>>>>>>>>>>>>>>>>>> //PUT <<<<<<<<<<<<<<<<<<<<<<<<< - sqlRequest.put(realKey, targetArray != null ? targetArray : JSON.toJSONString(targetObj, SerializerFeature.WriteMapNullValue)); + sqlRequest.put(realKey, targetArray != null ? targetArray : JSON.toJSONString(targetObj)); // FIXME, SerializerFeature.WriteMapNullValue)); //PUT >>>>>>>>>>>>>>>>>>>>>>>>> } @Override - public void onTableArrayParse(String key, JSONArray valueArray) throws Exception { - String childKey = key.substring(0, key.length() - JSONRequest.KEY_ARRAY.length()); + public void onTableArrayParse(String key, L valueArray) throws Exception { + String childKey = key.substring(0, key.length() - apijson.JSONObject.KEY_ARRAY.length()); int allCount = 0; - JSONArray ids = new JSONArray(); + L ids = JSON.createJSONArray(); int version = parser.getVersion(); int maxUpdateCount = parser.getMaxUpdateCount(); - SQLConfig cfg = null; // 不能污染当前的配置 getSQLConfig(); + SQLConfig cfg = null; // 不能污染当前的配置 getSQLConfig(); if (cfg == null) { // TODO 每次都创建成本比较高,是否新增 defaultInstance 或者 configInstance 用来专门 getIdKey 等? cfg = parser.createSQLConfig(); } @@ -790,16 +783,16 @@ public void onTableArrayParse(String key, JSONArray valueArray) throws Exception cfg.setTable(childKey); // Request 表 structure 中配置 "ALLOW_PARTIAL_UPDATE_FAILED": "Table[],key[],key:alias[]" 自动配置 boolean allowPartialFailed = cfg.allowPartialUpdateFailed(); - JSONArray failedIds = allowPartialFailed ? new JSONArray() : null; + L failedIds = allowPartialFailed ? JSON.createJSONArray() : null; int firstFailIndex = -1; - JSONObject firstFailReq = null; + M firstFailReq = null; Throwable firstFailThrow = null; for (int i = 0; i < valueArray.size(); i++) { //只要有一条失败,则抛出异常,全部失败 //TODO 改成一条多 VALUES 的 SQL 性能更高,报错也更会更好处理,更人性化 - JSONObject item; + M item; try { - item = valueArray.getJSONObject(i); + item = JSON.get(valueArray, i); if (item == null) { throw new NullPointerException(); } @@ -811,14 +804,16 @@ public void onTableArrayParse(String key, JSONArray valueArray) throws Exception } Object id = item.get(idKey); - JSONObject req = new JSONRequest(childKey, item); - JSONObject result = null; + M req = JSON.createJSONObject(); + req.put(childKey, item); + + M result = null; try { if (isNeedVerifyContent) { req = parser.parseCorrectRequest(method, childKey, version, "", req, maxUpdateCount, parser); } //parser.getMaxSQLCount() ? 可能恶意调用接口,把数据库拖死 - result = (JSONObject) onChildParse(0, "" + i, req, null); + result = (M) onChildParse(0, "" + i, req, null); } catch (Exception e) { if (allowPartialFailed == false) { @@ -827,14 +822,14 @@ public void onTableArrayParse(String key, JSONArray valueArray) throws Exception if (firstFailThrow == null) { firstFailThrow = e; - firstFailReq = valueArray.getJSONObject(i); // item + firstFailReq = JSON.get(valueArray, i); // item } } - result = result == null ? null : result.getJSONObject(childKey); + result = result == null ? null : JSON.get(result, childKey); boolean success = JSONResponse.isSuccess(result); - int count = result == null ? 0 : result.getIntValue(JSONResponse.KEY_COUNT); + int count = result == null ? 0 : getIntValue(result, JSONResponse.KEY_COUNT); if (id == null && result != null) { id = result.get(idKey); } @@ -849,7 +844,7 @@ public void onTableArrayParse(String key, JSONArray valueArray) throws Exception else { throw new ServerException( "批量新增/修改失败!" + key + "/" + i + ":" + (success ? "成功但 count != 1 !" - : (result == null ? "null" : result.getString(JSONResponse.KEY_MSG)) + : (result == null ? "null" : getString(result, JSONResponse.KEY_MSG)) )); } } @@ -864,19 +859,19 @@ public void onTableArrayParse(String key, JSONArray valueArray) throws Exception + "第 " + firstFailIndex + " 项失败原因:" + (firstFailThrow == null ? "" : firstFailThrow.getMessage())); } - JSONObject allResult = AbstractParser.newSuccessResult(); + M allResult = getParser().newSuccessResult(); if (failedCount > 0) { allResult.put("failedCount", failedCount); allResult.put("failedIdList", failedIds); - JSONObject failObj = new JSONObject(true); + M failObj = JSON.createJSONObject(); failObj.put("index", firstFailIndex); failObj.put(childKey, firstFailReq); if (firstFailThrow instanceof CommonException && firstFailThrow.getCause() != null) { firstFailThrow = firstFailThrow.getCause(); } - JSONObject obj = firstFailThrow == null ? failObj : AbstractParser.extendErrorResult(failObj, firstFailThrow, parser.isRoot()); + M obj = firstFailThrow == null ? failObj : getParser().extendErrorResult(failObj, firstFailThrow, parser.isRoot()); if (Log.DEBUG && firstFailThrow != null) { obj.put("trace:throw", firstFailThrow.getClass().getName()); obj.put("trace:stack", firstFailThrow.getStackTrace()); @@ -892,19 +887,19 @@ public void onTableArrayParse(String key, JSONArray valueArray) throws Exception @Override - public JSONObject parseResponse(RequestMethod method, String table, String alias - , JSONObject request, List joinList, boolean isProcedure) throws Exception { - SQLConfig config = newSQLConfig(method, table, alias, request, joinList, isProcedure) + public M parseResponse(RequestMethod method, String table, String alias + , M request, List> joinList, boolean isProcedure) throws Exception { + SQLConfig config = newSQLConfig(method, table, alias, request, joinList, isProcedure) .setParser(parser) .setObjectParser(this); return parseResponse(config, isProcedure); } @Override - public JSONObject parseResponse(SQLConfig config, boolean isProcedure) throws Exception { + public M parseResponse(SQLConfig config, boolean isProcedure) throws Exception { if (parser.getSQLExecutor() == null) { parser.createSQLExecutor(); } - if (parser != null && config.getParser() == null) { + if (parser != null && config.gainParser() == null) { config.setParser(parser); } return parser.getSQLExecutor().execute(config, isProcedure); @@ -912,8 +907,8 @@ public JSONObject parseResponse(SQLConfig config, boolean isProcedure) throws @Override - public SQLConfig newSQLConfig(boolean isProcedure) throws Exception { - String raw = Log.DEBUG == false || sqlRequest == null ? null : sqlRequest.getString(apijson.JSONRequest.KEY_RAW); + public SQLConfig newSQLConfig(boolean isProcedure) throws Exception { + String raw = Log.DEBUG == false || sqlRequest == null ? null : getString(sqlRequest, apijson.JSONObject.KEY_RAW); String[] keys = raw == null ? null : StringUtil.split(raw); if (keys != null && keys.length > 0) { boolean allow = AbstractSQLConfig.ALLOW_MISSING_KEY_4_COMBINE; @@ -931,7 +926,7 @@ public SQLConfig newSQLConfig(boolean isProcedure) throws Exception { } if (parser instanceof AbstractParser) { - ((AbstractParser) parser).putWarnIfNeed(JSONRequest.KEY_RAW, msg); + ((AbstractParser) parser).putWarnIfNeed(apijson.JSONObject.KEY_RAW, msg); } break; } @@ -947,12 +942,12 @@ public SQLConfig newSQLConfig(boolean isProcedure) throws Exception { * @throws Exception */ @Override - public AbstractObjectParser setSQLConfig() throws Exception { + public AbstractObjectParser setSQLConfig() throws Exception { return setSQLConfig(RequestMethod.isQueryMethod(method) ? 1 : 0, 0, 0); } @Override - public AbstractObjectParser setSQLConfig(int count, int page, int position) throws Exception { + public AbstractObjectParser setSQLConfig(int count, int page, int position) throws Exception { if (isTable == false || isReuse) { return setPosition(position); } @@ -978,16 +973,17 @@ public AbstractObjectParser setSQLConfig(int count, int page, int position) thro - protected SQLConfig sqlConfig = null;//array item复用 + protected SQLConfig sqlConfig = null;//array item复用 /**SQL查询,for array item * @return this * @throws Exception */ @Override - public AbstractObjectParser executeSQL() throws Exception { + public AbstractObjectParser executeSQL() throws Exception { //执行SQL操作数据库 if (isTable == false) {//提高性能 - sqlResponse = new JSONObject(sqlRequest); + sqlResponse = JSON.createJSONObject(); + sqlResponse.putAll(sqlRequest); } else { try { @@ -1025,7 +1021,7 @@ public AbstractObjectParser executeSQL() throws Exception { * @throws Exception */ @Override - public JSONObject response() throws Exception { + public M response() throws Exception { if (sqlResponse == null || sqlResponse.isEmpty()) { if (isTable) {//Table自身都获取不到值,则里面的Child都无意义,不需要再解析 return null; // response; @@ -1061,7 +1057,7 @@ public void onFunctionResponse(String type) throws Exception { Set> functionSet = map == null ? null : map.entrySet(); if (functionSet != null && functionSet.isEmpty() == false) { boolean isMinus = "-".equals(type); - JSONObject json = isMinus ? sqlRequest : response; // key-():function 是实时执行,而不是在这里批量执行 + M json = isMinus ? sqlRequest : response; // key-():function 是实时执行,而不是在这里批量执行 for (Entry entry : functionSet) { parseFunction(entry.getKey(), entry.getKey(), entry.getValue(), this.type == TYPE_ITEM ? path : parentPath, name, json, isMinus); @@ -1070,11 +1066,11 @@ public void onFunctionResponse(String type) throws Exception { } - //public void parseFunction(String key, String value, String parentPath, String currentName, JSONObject currentObject) throws Exception { + //public void parseFunction(String key, String value, String parentPath, String currentName, JSONRequest currentObject) throws Exception { // parseFunction(key, value, parentPath, currentName, currentObject, false); //} public void parseFunction(String rawKey, String key, String value, String parentPath - , String currentName, JSONObject currentObject, boolean isMinus) throws Exception { + , String currentName, M currentObject, boolean isMinus) throws Exception { Object result; boolean containRaw = rawKeyList != null && rawKeyList.contains(rawKey); @@ -1082,7 +1078,7 @@ public void parseFunction(String rawKey, String key, String value, String parent if (isProcedure) { FunctionBean fb = AbstractFunctionParser.parseFunction(value, currentObject, true, containRaw); - SQLConfig config = newSQLConfig(true); + SQLConfig config = newSQLConfig(true); String sch = fb.getSchema(); if (StringUtil.isNotEmpty(sch, true)) { config.setSchema(sch); @@ -1096,7 +1092,7 @@ public void parseFunction(String rawKey, String key, String value, String parent result = parser.onFunctionParse(key, value, parentPath, currentName, currentObject, containRaw); } - String k = AbstractSQLConfig.getRealKey(method, key, false, false); + String k = AbstractSQLConfig.gainRealKey(method, key, false, false); if (isProcedure == false && isMinus) { if (result != null) { @@ -1118,14 +1114,14 @@ public void parseFunction(String rawKey, String key, String value, String parent @Override public void onChildResponse() throws Exception { //把isTable时取出去child解析后重新添加回来 - Set> set = childMap == null ? null : childMap.entrySet(); + Set> set = childMap == null ? null : childMap.entrySet(); if (set != null) { int index = 0; - for (Entry entry : set) { + for (Entry entry : set) { Object child = entry == null ? null : onChildParse(index, entry.getKey(), entry.getValue(), null); if (child == null - || (child instanceof JSONObject && ((JSONObject) child).isEmpty()) - || (child instanceof JSONArray && ((JSONArray) child).isEmpty()) + || (child instanceof Map && ((M) child).isEmpty()) + || (child instanceof List && ((L) child).isEmpty()) ) { continue; } @@ -1145,10 +1141,10 @@ public Object onReferenceParse(@NotNull String path) { @SuppressWarnings("unchecked") @Override - public JSONObject onSQLExecute() throws Exception { + public M onSQLExecute() throws Exception { int position = getPosition(); - JSONObject result = getCache(); + M result = getCache(); if (result != null) { parser.putQueryResult(path, result); } @@ -1160,7 +1156,7 @@ else if (isArrayMainTable && position > 0) { // 数组主表使用专门的缓 boolean isSimpleArray = false; // 提取并缓存数组主表的列表数据 - List rawList = result == null ? null : (List) result.remove(AbstractSQLExecutor.KEY_RAW_LIST); + List rawList = result == null ? null : (List) result.remove(AbstractSQLExecutor.KEY_RAW_LIST); if (isArrayMainTable && position == 0 && rawList != null) { @@ -1169,14 +1165,14 @@ else if (isArrayMainTable && position > 0) { // 数组主表使用专门的缓 && (childMap == null || childMap.isEmpty()) && (table.equals(arrayTable)); - // APP JOIN 副表时副表返回了这个字段 rawList = (List) result.remove(AbstractSQLExecutor.KEY_RAW_LIST); + // APP JOIN 副表时副表返回了这个字段 rawList = (List) result.remove(AbstractSQLExecutor.KEY_RAW_LIST); String arrayPath = parentPath.substring(0, parentPath.lastIndexOf("[]") + 2); if (isSimpleArray == false) { long startTime = System.currentTimeMillis(); for (int i = 1; i < rawList.size(); i++) { // 从 1 开始,0 已经处理过 - JSONObject obj = rawList.get(i); + M obj = rawList.get(i); if (obj != null) { // obj.remove(AbstractSQLExecutor.KEY_VICE_ITEM); @@ -1249,12 +1245,9 @@ public void recycle() { - - - protected RequestMethod method; @Override - public AbstractObjectParser setMethod(RequestMethod method) { + public AbstractObjectParser setMethod(RequestMethod method) { if (this.method != method) { this.method = method; sqlConfig = null; @@ -1268,8 +1261,6 @@ public RequestMethod getMethod() { } - - @Override public boolean isTable() { return isTable; @@ -1286,27 +1277,27 @@ public String getTable() { public String getAlias() { return alias; } + @Override - public SQLConfig getArrayConfig() { + public SQLConfig getArrayConfig() { return arrayConfig; } - @Override - public SQLConfig getSQLConfig() { + public SQLConfig getSQLConfig() { return sqlConfig; } @Override - public JSONObject getResponse() { + public M getResponse() { return response; } @Override - public JSONObject getSqlRequest() { + public M getSQLRequest() { return sqlRequest; } @Override - public JSONObject getSqlResponse() { + public M getSQLResponse() { return sqlResponse; } @@ -1319,9 +1310,8 @@ public Map> getFunctionMap() { return functionMap; } @Override - public Map getChildMap() { + public Map getChildMap() { return childMap; } - } diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java index 061e32d11..f2401eeae 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java @@ -5,9 +5,8 @@ package apijson.orm; +import apijson.*; import apijson.orm.exception.ConflictException; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; import java.io.UnsupportedEncodingException; import java.lang.management.ManagementFactory; @@ -25,25 +24,20 @@ import javax.management.Query; -import apijson.JSON; -import apijson.JSONRequest; -import apijson.JSONResponse; -import apijson.Log; -import apijson.NotNull; -import apijson.RequestMethod; -import apijson.StringUtil; import apijson.orm.exception.CommonException; import apijson.orm.exception.UnsupportedDataTypeException; +import static apijson.JSON.*; import static apijson.JSONObject.KEY_COMBINE; import static apijson.JSONObject.KEY_EXPLAIN; import static apijson.RequestMethod.CRUD; import static apijson.RequestMethod.GET; -/**Parser for parsing request to JSONObject +/**Parser for parsing request to JSONRequest * @author Lemon */ -public abstract class AbstractParser implements Parser, ParserCreator, VerifierCreator, SQLCreator { +public abstract class AbstractParser, L extends List> + implements Parser, ParserCreator, VerifierCreator, SQLCreator { protected static final String TAG = "AbstractParser"; /** @@ -122,7 +116,6 @@ public int getMaxQueryDepth() { return MAX_QUERY_DEPTH; } - /** * method = null */ @@ -152,7 +145,7 @@ public AbstractParser(RequestMethod method, boolean needVerify) { public boolean isRoot() { return isRoot; } - public AbstractParser setRoot(boolean isRoot) { + public AbstractParser setRoot(boolean isRoot) { this.isRoot = isRoot; return this; } @@ -166,7 +159,7 @@ public AbstractParser setRoot(boolean isRoot) { public String getWarn(String type) { return warnMap == null ? null : warnMap.get(type); } - public AbstractParser putWarnIfNeed(String type, String warn) { + public AbstractParser putWarnIfNeed(String type, String warn) { if (Log.DEBUG) { String w = getWarn(type); if (StringUtil.isEmpty(w, true)) { @@ -175,7 +168,7 @@ public AbstractParser putWarnIfNeed(String type, String warn) { } return this; } - public AbstractParser putWarn(String type, String warn) { + public AbstractParser putWarn(String type, String warn) { if (warnMap == null) { warnMap = new LinkedHashMap<>(); } @@ -231,7 +224,7 @@ public List getContactIdList() { return visitor; } @Override - public AbstractParser setVisitor(@NotNull Visitor visitor) { + public AbstractParser setVisitor(@NotNull Visitor visitor) { this.visitor = visitor; return this; } @@ -244,7 +237,7 @@ public RequestMethod getMethod() { } @NotNull @Override - public AbstractParser setMethod(RequestMethod method) { + public AbstractParser setMethod(RequestMethod method) { this.requestMethod = method == null ? GET : method; this.transactionIsolation = RequestMethod.isQueryMethod(method) ? Connection.TRANSACTION_NONE : Connection.TRANSACTION_REPEATABLE_READ; return this; @@ -256,7 +249,7 @@ public int getVersion() { return version; } @Override - public AbstractParser setVersion(int version) { + public AbstractParser setVersion(int version) { this.version = version; return this; } @@ -267,7 +260,7 @@ public String getTag() { return tag; } @Override - public AbstractParser setTag(String tag) { + public AbstractParser setTag(String tag) { this.tag = tag; return this; } @@ -276,24 +269,24 @@ public AbstractParser setTag(String tag) { public String getRequestURL() { return requestURL; } - public AbstractParser setRequestURL(String requestURL) { + public AbstractParser setRequestURL(String requestURL) { this.requestURL = requestURL; return this; } - protected JSONObject requestObject; + protected M requestObject; @Override - public JSONObject getRequest() { + public M getRequest() { return requestObject; } @Override - public AbstractParser setRequest(JSONObject request) { + public AbstractParser setRequest(M request) { this.requestObject = request; return this; } protected Boolean globalFormat; - public AbstractParser setGlobalFormat(Boolean globalFormat) { + public AbstractParser setGlobalFormat(Boolean globalFormat) { this.globalFormat = globalFormat; return this; } @@ -302,7 +295,7 @@ public Boolean getGlobalFormat() { return globalFormat; } protected String globalRole; - public AbstractParser setGlobalRole(String globalRole) { + public AbstractParser setGlobalRole(String globalRole) { this.globalRole = globalRole; return this; } @@ -311,7 +304,7 @@ public String getGlobalRole() { return globalRole; } protected String globalDatabase; - public AbstractParser setGlobalDatabase(String globalDatabase) { + public AbstractParser setGlobalDatabase(String globalDatabase) { this.globalDatabase = globalDatabase; return this; } @@ -325,13 +318,13 @@ public String getGlobalDatabase() { public String getGlobalDatasource() { return globalDatasource; } - public AbstractParser setGlobalDatasource(String globalDatasource) { + public AbstractParser setGlobalDatasource(String globalDatasource) { this.globalDatasource = globalDatasource; return this; } protected String globalNamespace; - public AbstractParser setGlobalNamespace(String globalNamespace) { + public AbstractParser setGlobalNamespace(String globalNamespace) { this.globalNamespace = globalNamespace; return this; } @@ -341,7 +334,7 @@ public String getGlobalNamespace() { } protected String globalCatalog; - public AbstractParser setGlobalCatalog(String globalCatalog) { + public AbstractParser setGlobalCatalog(String globalCatalog) { this.globalCatalog = globalCatalog; return this; } @@ -351,7 +344,7 @@ public String getGlobalCatalog() { } protected String globalSchema; - public AbstractParser setGlobalSchema(String globalSchema) { + public AbstractParser setGlobalSchema(String globalSchema) { this.globalSchema = globalSchema; return this; } @@ -361,7 +354,7 @@ public String getGlobalSchema() { } protected Boolean globalExplain; - public AbstractParser setGlobalExplain(Boolean globalExplain) { + public AbstractParser setGlobalExplain(Boolean globalExplain) { this.globalExplain = globalExplain; return this; } @@ -370,7 +363,7 @@ public Boolean getGlobalExplain() { return globalExplain; } protected String globalCache; - public AbstractParser setGlobalCache(String globalCache) { + public AbstractParser setGlobalCache(String globalCache) { this.globalCache = globalCache; return this; } @@ -380,7 +373,7 @@ public String getGlobalCache() { } @Override - public AbstractParser setNeedVerify(boolean needVerify) { + public AbstractParser setNeedVerify(boolean needVerify) { setNeedVerifyLogin(needVerify); setNeedVerifyRole(needVerify); setNeedVerifyContent(needVerify); @@ -393,7 +386,7 @@ public boolean isNeedVerifyLogin() { return needVerifyLogin; } @Override - public AbstractParser setNeedVerifyLogin(boolean needVerifyLogin) { + public AbstractParser setNeedVerifyLogin(boolean needVerifyLogin) { this.needVerifyLogin = needVerifyLogin; return this; } @@ -403,7 +396,7 @@ public boolean isNeedVerifyRole() { return needVerifyRole; } @Override - public AbstractParser setNeedVerifyRole(boolean needVerifyRole) { + public AbstractParser setNeedVerifyRole(boolean needVerifyRole) { this.needVerifyRole = needVerifyRole; return this; } @@ -413,18 +406,18 @@ public boolean isNeedVerifyContent() { return needVerifyContent; } @Override - public AbstractParser setNeedVerifyContent(boolean needVerifyContent) { + public AbstractParser setNeedVerifyContent(boolean needVerifyContent) { this.needVerifyContent = needVerifyContent; return this; } - protected SQLExecutor sqlExecutor; - protected Verifier verifier; + protected SQLExecutor sqlExecutor; + protected Verifier verifier; protected Map queryResultMap;//path-result @Override - public SQLExecutor getSQLExecutor() { + public SQLExecutor getSQLExecutor() { if (sqlExecutor == null) { sqlExecutor = createSQLExecutor(); sqlExecutor.setParser(this); @@ -432,7 +425,7 @@ public SQLExecutor getSQLExecutor() { return sqlExecutor; } @Override - public Verifier getVerifier() { + public Verifier getVerifier() { if (verifier == null) { verifier = createVerifier().setVisitor(getVisitor()); } @@ -453,7 +446,7 @@ public String parse(String request) { */ @NotNull @Override - public String parse(JSONObject request) { + public String parse(M request) { return JSON.toJSONString(parseResponse(request)); } @@ -463,12 +456,15 @@ public String parse(JSONObject request) { */ @NotNull @Override - public JSONObject parseResponse(String request) { + public M parseResponse(String request) { Log.d(TAG, "\n\n\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n" + requestMethod + "/parseResponse request = \n" + request + "\n\n"); try { - requestObject = parseRequest(request); + requestObject = (M) JSON.parseObject(request); + if (requestObject == null) { + throw new UnsupportedEncodingException("JSON格式不合法!"); + } } catch (Exception e) { return newErrorResult(e, isRoot); } @@ -485,19 +481,19 @@ public JSONObject parseResponse(String request) { */ @NotNull @Override - public JSONObject parseResponse(JSONObject request) { + public M parseResponse(M request) { long startTime = System.currentTimeMillis(); Log.d(TAG, "parseResponse startTime = " + startTime + "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n\n "); requestObject = request; try { - setVersion(requestObject.getIntValue(JSONRequest.KEY_VERSION)); - requestObject.remove(JSONRequest.KEY_VERSION); + setVersion(getIntValue(requestObject, apijson.JSONRequest.KEY_VERSION)); + requestObject.remove(apijson.JSONRequest.KEY_VERSION); if (getMethod() != RequestMethod.CRUD) { - setTag(requestObject.getString(JSONRequest.KEY_TAG)); - requestObject.remove(JSONRequest.KEY_TAG); + setTag(getString(requestObject, apijson.JSONRequest.KEY_TAG)); + requestObject.remove(apijson.JSONRequest.KEY_TAG); } } catch (Exception e) { return extendErrorResult(requestObject, e, requestMethod, getRequestURL(), isRoot); @@ -521,33 +517,33 @@ public JSONObject parseResponse(JSONObject request) { //必须在parseCorrectRequest后面,因为parseCorrectRequest可能会添加 @role if (isNeedVerifyRole() && globalRole == null) { try { - setGlobalRole(requestObject.getString(JSONRequest.KEY_ROLE)); - requestObject.remove(JSONRequest.KEY_ROLE); + setGlobalRole(getString(requestObject, apijson.JSONObject.KEY_ROLE)); + requestObject.remove(apijson.JSONObject.KEY_ROLE); } catch (Exception e) { return extendErrorResult(requestObject, e, requestMethod, getRequestURL(), isRoot); } } try { - setGlobalDatabase(requestObject.getString(JSONRequest.KEY_DATABASE)); - setGlobalDatasource(requestObject.getString(JSONRequest.KEY_DATASOURCE)); - setGlobalNamespace(requestObject.getString(JSONRequest.KEY_NAMESPACE)); - setGlobalCatalog(requestObject.getString(JSONRequest.KEY_CATALOG)); - setGlobalSchema(requestObject.getString(JSONRequest.KEY_SCHEMA)); - - setGlobalExplain(requestObject.getBoolean(JSONRequest.KEY_EXPLAIN)); - setGlobalCache(requestObject.getString(JSONRequest.KEY_CACHE)); - setGlobalFormat(requestObject.getBoolean(JSONRequest.KEY_FORMAT)); - - requestObject.remove(JSONRequest.KEY_DATABASE); - requestObject.remove(JSONRequest.KEY_DATASOURCE); - requestObject.remove(JSONRequest.KEY_NAMESPACE); - requestObject.remove(JSONRequest.KEY_CATALOG); - requestObject.remove(JSONRequest.KEY_SCHEMA); - - requestObject.remove(JSONRequest.KEY_EXPLAIN); - requestObject.remove(JSONRequest.KEY_CACHE); - requestObject.remove(JSONRequest.KEY_FORMAT); + 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); } catch (Exception e) { return extendErrorResult(requestObject, e, requestMethod, getRequestURL(), isRoot); } @@ -579,7 +575,17 @@ public JSONObject parseResponse(JSONObject request) { requestObject = error == null ? extendSuccessResult(requestObject, warn, isRoot) : extendErrorResult(requestObject, error, requestMethod, getRequestURL(), isRoot); - JSONObject res = (globalFormat != null && globalFormat) && JSONResponse.isSuccess(requestObject) ? new JSONResponse(requestObject) : requestObject; + M res = (globalFormat != null && globalFormat) && JSONResponse.isSuccess(requestObject) ? JSONResponse.format(requestObject, new JSONCreator>() { + @Override + public M createJSONObject() { + return JSON.createJSONObject(); + } + + @Override + public List createJSONArray() { + return JSON.createJSONArray(); + } + }) : requestObject; long endTime = System.currentTimeMillis(); long duration = endTime - startTime; @@ -635,7 +641,7 @@ public void onVerifyContent() throws Exception { * @throws Exception */ @Override - public void onVerifyRole(@NotNull SQLConfig config) throws Exception { + public void onVerifyRole(@NotNull SQLConfig config) throws Exception { if (Log.DEBUG) { Log.i(TAG, "onVerifyRole config = " + JSON.toJSONString(config)); } @@ -654,23 +660,9 @@ public void onVerifyRole(@NotNull SQLConfig config) throws Exception { } - /**解析请求JSONObject - * @param request => URLDecoder.decode(request, UTF_8); - * @return - * @throws Exception - */ - @NotNull - public static JSONObject parseRequest(String request) throws Exception { - JSONObject obj = JSON.parseObject(request); - if (obj == null) { - throw new UnsupportedEncodingException("JSON格式不合法!"); - } - return obj; - } - @Override - public JSONObject parseCorrectRequest(RequestMethod method, String tag, int version, String name, @NotNull JSONObject request - , int maxUpdateCount, SQLCreator creator) throws Exception { + public M parseCorrectRequest(RequestMethod method, String tag, int version, String name, @NotNull M request + , int maxUpdateCount, SQLCreator creator) throws Exception { if (RequestMethod.isPublicMethod(method)) { return request;//需要指定JSON结构的get请求可以改为post请求。一般只有对安全性要求高的才会指定,而这种情况用明文的GET方式几乎肯定不安全 @@ -684,38 +676,38 @@ public JSONObject parseCorrectRequest(RequestMethod method, String tag, int vers * @param tag * @return */ - public static JSONObject wrapRequest(RequestMethod method, String tag, JSONObject object, boolean isStructure) { + public M wrapRequest(RequestMethod method, String tag, M object, boolean isStructure, JSONCreator creator) { boolean putTag = ! isStructure; if (object == null || object.containsKey(tag)) { //tag 是 Table 名或 Table[] if (putTag) { if (object == null) { - object = new JSONObject(true); + object = creator.createJSONObject(); } - object.put(JSONRequest.KEY_TAG, tag); + object.put(apijson.JSONRequest.KEY_TAG, tag); } return object; } boolean isDiffArrayKey = tag.endsWith(":[]"); - boolean isArrayKey = isDiffArrayKey || JSONRequest.isArrayKey(tag); + boolean isArrayKey = isDiffArrayKey || apijson.JSONObject.isArrayKey(tag); String key = isArrayKey ? tag.substring(0, tag.length() - (isDiffArrayKey ? 3 : 2)) : tag; - JSONObject target = object; + M target = object; if (apijson.JSONObject.isTableKey(key)) { if (isDiffArrayKey) { //自动为 tag = Comment:[] 的 { ... } 新增键值对为 { "Comment[]":[], "TYPE": { "Comment[]": "OBJECT[]" } ... } if (isStructure && (method == RequestMethod.POST || method == RequestMethod.PUT)) { String arrKey = key + "[]"; if (target.containsKey(arrKey) == false) { - target.put(arrKey, new JSONArray()); + target.put(arrKey, JSON.createJSONArray()); } try { - JSONObject type = target.getJSONObject(Operation.TYPE.name()); + Map type = JSON.get(target, Operation.TYPE.name()); if (type == null || (type.containsKey(arrKey) == false)) { if (type == null) { - type = new JSONObject(true); + type = new LinkedHashMap(); } type.put(arrKey, "OBJECT[]"); @@ -723,24 +715,24 @@ public static JSONObject wrapRequest(RequestMethod method, String tag, JSONObjec } } catch (Throwable e) { - Log.w(TAG, "wrapRequest try { JSONObject type = target.getJSONObject(Operation.TYPE.name()); } catch (Exception e) = " + e.getMessage()); + Log.w(TAG, "wrapRequest try { Map type = target.getJSONObject(Operation.TYPE.name()); } catch (Exception e) = " + e.getMessage()); } } } else { //自动为 tag = Comment 的 { ... } 包一层为 { "Comment": { ... } } if (isArrayKey == false || RequestMethod.isGetMethod(method, true)) { - target = new JSONObject(true); + target = creator.createJSONObject(); target.put(tag, object); } else if (target.containsKey(key) == false) { - target = new JSONObject(true); + target = creator.createJSONObject(); target.put(key, object); } } } if (putTag) { - target.put(JSONRequest.KEY_TAG, tag); + target.put(apijson.JSONRequest.KEY_TAG, tag); } return target; @@ -752,7 +744,7 @@ else if (target.containsKey(key) == false) { * @param msg * @return */ - public static JSONObject newResult(int code, String msg) { + public M newResult(int code, String msg) { return newResult(code, msg, null); } @@ -764,7 +756,7 @@ public static JSONObject newResult(int code, String msg) { * @param warn * @return */ - public static JSONObject newResult(int code, String msg, String warn) { + public M newResult(int code, String msg, String warn) { return newResult(code, msg, warn, false); } @@ -777,7 +769,7 @@ public static JSONObject newResult(int code, String msg, String warn) { * @param isRoot * @return */ - public static JSONObject newResult(int code, String msg, String warn, boolean isRoot) { + public M newResult(int code, String msg, String warn, boolean isRoot) { return extendResult(null, code, msg, warn, isRoot); } @@ -789,7 +781,7 @@ public static JSONObject newResult(int code, String msg, String warn, boolean is * @param msg * @return */ - public static JSONObject extendResult(JSONObject object, int code, String msg, String warn, boolean isRoot) { + public M extendResult(M object, int code, String msg, String warn, boolean isRoot) { int index = Log.DEBUG == false || isRoot == false || msg == null ? -1 : msg.lastIndexOf(Log.KEY_SYSTEM_INFO_DIVIDER); String debug = Log.DEBUG == false || isRoot == false ? null : (index >= 0 ? msg.substring(index + Log.KEY_SYSTEM_INFO_DIVIDER.length()).trim() : " \n提 bug 请发请求和响应的【完整截屏】,没图的自行解决!" @@ -808,7 +800,7 @@ public static JSONObject extendResult(JSONObject object, int code, String msg, S msg = index >= 0 ? msg.substring(0, index) : msg; if (object == null) { - object = new JSONObject(true); + object = JSON.createJSONObject(); } if (object.get(JSONResponse.KEY_OK) == null) { @@ -818,7 +810,7 @@ public static JSONObject extendResult(JSONObject object, int code, String msg, S object.put(JSONResponse.KEY_CODE, code); } - String m = StringUtil.get(object.getString(JSONResponse.KEY_MSG)); + String m = StringUtil.get(getString(object, JSONResponse.KEY_MSG)); if (m.isEmpty() == false) { msg = m + " ;\n " + StringUtil.get(msg); } @@ -841,11 +833,11 @@ public static JSONObject extendResult(JSONObject object, int code, String msg, S * @param object * @return */ - public static JSONObject extendSuccessResult(JSONObject object) { + public M extendSuccessResult(M object) { return extendSuccessResult(object, false); } - public static JSONObject extendSuccessResult(JSONObject object, boolean isRoot) { + public M extendSuccessResult(M object, boolean isRoot) { return extendSuccessResult(object, null, isRoot); } @@ -854,14 +846,14 @@ public static JSONObject extendSuccessResult(JSONObject object, boolean isRoot) * @param isRoot * @return */ - public static JSONObject extendSuccessResult(JSONObject object, String warn, boolean isRoot) { + public M extendSuccessResult(M object, String warn, boolean isRoot) { return extendResult(object, JSONResponse.CODE_SUCCESS, JSONResponse.MSG_SUCCEED, warn, isRoot); } /**获取请求成功的状态内容 * @return */ - public static JSONObject newSuccessResult() { + public M newSuccessResult() { return newSuccessResult(null); } @@ -869,7 +861,7 @@ public static JSONObject newSuccessResult() { * @param warn * @return */ - public static JSONObject newSuccessResult(String warn) { + public M newSuccessResult(String warn) { return newSuccessResult(warn, false); } @@ -878,7 +870,7 @@ public static JSONObject newSuccessResult(String warn) { * @param isRoot * @return */ - public static JSONObject newSuccessResult(String warn, boolean isRoot) { + public M newSuccessResult(String warn, boolean isRoot) { return newResult(JSONResponse.CODE_SUCCESS, JSONResponse.MSG_SUCCEED, warn, isRoot); } @@ -887,7 +879,7 @@ public static JSONObject newSuccessResult(String warn, boolean isRoot) { * @param e * @return */ - public static JSONObject extendErrorResult(JSONObject object, Throwable e) { + public M extendErrorResult(M object, Throwable e) { return extendErrorResult(object, e, false); } /**添加请求成功的状态内容 @@ -896,14 +888,14 @@ public static JSONObject extendErrorResult(JSONObject object, Throwable e) { * @param isRoot * @return */ - public static JSONObject extendErrorResult(JSONObject object, Throwable e, boolean isRoot) { + public M extendErrorResult(M object, Throwable e, boolean isRoot) { return extendErrorResult(object, e, null, null, isRoot); } /**添加请求成功的状态内容 * @param object * @return */ - public static JSONObject extendErrorResult(JSONObject object, Throwable e, RequestMethod requestMethod, String url, boolean isRoot) { + public M extendErrorResult(M object, Throwable e, RequestMethod requestMethod, String url, boolean isRoot) { String msg = CommonException.getMsg(e); if (Log.DEBUG && isRoot) { @@ -984,7 +976,7 @@ public static JSONObject extendErrorResult(JSONObject object, Throwable e, Reque * @param e * @return */ - public static JSONObject newErrorResult(Exception e) { + public M newErrorResult(Exception e) { return newErrorResult(e, false); } /**新建错误状态内容 @@ -992,7 +984,7 @@ public static JSONObject newErrorResult(Exception e) { * @param isRoot * @return */ - public static JSONObject newErrorResult(Exception e, boolean isRoot) { + public M newErrorResult(Exception e, boolean isRoot) { if (e != null) { // if (Log.DEBUG) { e.printStackTrace(); @@ -1013,7 +1005,7 @@ public static JSONObject newErrorResult(Exception e, boolean isRoot) { * @throws Exception */ @Override - public JSONObject parseCorrectRequest() throws Exception { + public M parseCorrectRequest() throws Exception { return parseCorrectRequest(requestMethod, tag, version, "", requestObject, getMaxUpdateCount(), this); } @@ -1027,18 +1019,18 @@ public JSONObject parseCorrectRequest() throws Exception { * @throws Exception */ @Override - public JSONObject getStructure(@NotNull String table, String method, String tag, int version) throws Exception { + public M getStructure(@NotNull String table, String method, String tag, int version) throws Exception { String cacheKey = AbstractVerifier.getCacheKeyForRequest(method, tag); - SortedMap versionedMap = AbstractVerifier.REQUEST_MAP.get(cacheKey); + SortedMap> versionedMap = (SortedMap>) AbstractVerifier.REQUEST_MAP.get(cacheKey); - JSONObject result = versionedMap == null ? null : versionedMap.get(Integer.valueOf(version)); + Map result = versionedMap == null ? null : versionedMap.get(Integer.valueOf(version)); if (result == null) { // version <= 0 时使用最新,version > 0 时使用 > version 的最接近版本(最小版本) - Set> set = versionedMap == null ? null : versionedMap.entrySet(); + Set>> set = versionedMap == null ? null : versionedMap.entrySet(); if (set != null && set.isEmpty() == false) { - Entry maxEntry = null; + Entry> maxEntry = null; - for (Entry entry : set) { + for (Entry> entry : set) { if (entry == null || entry.getKey() == null || entry.getValue() == null) { continue; } @@ -1076,19 +1068,19 @@ public JSONObject getStructure(@NotNull String table, String method, String tag, } // 获取指定的JSON结构 <<<<<<<<<<<<<< - SQLConfig config = createSQLConfig().setMethod(GET).setTable(table); + SQLConfig config = createSQLConfig().setMethod(GET).setTable(table); config.setPrepared(false); config.setColumn(Arrays.asList("structure")); Map where = new HashMap(); where.put("method", method); - where.put(JSONRequest.KEY_TAG, tag); + where.put(apijson.JSONRequest.KEY_TAG, tag); if (version > 0) { - where.put(JSONRequest.KEY_VERSION + ">=", version); + where.put(apijson.JSONRequest.KEY_VERSION + ">=", version); } config.setWhere(where); - config.setOrder(JSONRequest.KEY_VERSION + (version > 0 ? "+" : "-")); + config.setOrder(apijson.JSONRequest.KEY_VERSION + (version > 0 ? "+" : "-")); config.setCount(1); // too many connections error: 不try-catch,可以让客户端看到是服务器内部异常 @@ -1099,14 +1091,14 @@ public JSONObject getStructure(@NotNull String table, String method, String tag, // AbstractVerifier.REQUEST_MAP.put(cacheKey, versionedMap); } - return getJSONObject(result, "structure"); //解决返回值套了一层 "structure":{} + return JSON.get(result, "structure"); //解决返回值套了一层 "structure":{} } - protected Map arrayObjectParserCacheMap = new HashMap<>(); + protected Map> arrayObjectParserCacheMap = new HashMap<>(); - // protected SQLConfig itemConfig; + // protected SQLConfig itemConfig; /**获取单个对象,该对象处于parentObject内 * @param request parentObject 的 value * @param parentPath parentObject 的路径 @@ -1118,8 +1110,8 @@ public JSONObject getStructure(@NotNull String table, String method, String tag, * @throws Exception */ @Override - public JSONObject onObjectParse(final JSONObject request, String parentPath, String name - , final SQLConfig arrayConfig, boolean isSubquery, JSONObject cache) throws Exception { + public M onObjectParse(final M request, String parentPath, String name + , final SQLConfig arrayConfig, boolean isSubquery, M cache) throws Exception { if (Log.DEBUG) { Log.i(TAG, "\ngetObject: parentPath = " + parentPath @@ -1152,7 +1144,7 @@ public JSONObject onObjectParse(final JSONObject request, String parentPath, Str boolean isArrayMainTable = isSubquery == false && isTable && type == SQLConfig.TYPE_ITEM_CHILD_0 && arrayConfig != null && RequestMethod.isGetMethod(arrayConfig.getMethod(), true); boolean isReuse = isArrayMainTable && position > 0; - ObjectParser op = null; + ObjectParser op = null; if (isReuse) { // 数组主表使用专门的缓存数据 op = arrayObjectParserCacheMap.get(parentPath.substring(0, parentPath.lastIndexOf("[]") + 2)); op.setParentPath(parentPath); @@ -1167,7 +1159,7 @@ public JSONObject onObjectParse(final JSONObject request, String parentPath, Str op.setCache(cache); op = op.parse(name, isReuse); - JSONObject response = null; + M response = null; if (op != null) {//SQL查询结果为空时,functionMap和customMap没有意义 if (arrayConfig == null) { //Common @@ -1177,16 +1169,16 @@ public JSONObject onObjectParse(final JSONObject request, String parentPath, Str int query = arrayConfig.getQuery(); //total 这里不能用arrayConfig.getType(),因为在createObjectParser.onChildParse传到onObjectParse时已被改掉 - if (type == SQLConfig.TYPE_ITEM_CHILD_0 && query != JSONRequest.QUERY_TABLE && position == 0) { + if (type == SQLConfig.TYPE_ITEM_CHILD_0 && query != apijson.JSONRequest.QUERY_TABLE && position == 0) { //TODO 应在这里判断 @column 中是否有聚合函数,而不是 AbstractSQLConfig.getColumnString - JSONObject rp; + Map rp; Boolean compat = arrayConfig.getCompat(); if (compat != null && compat) { // 解决对聚合函数字段通过 query:2 分页查总数返回值错误 // 这里可能改变了内部的一些数据,下方通过 arrayConfig 还原 - SQLConfig cfg = op.setSQLConfig(0, 0, 0).getSQLConfig(); + SQLConfig cfg = op.setSQLConfig(0, 0, 0).getSQLConfig(); boolean isExplain = cfg.isExplain(); cfg.setExplain(false); @@ -1194,7 +1186,7 @@ public JSONObject onObjectParse(final JSONObject request, String parentPath, Str subqy.setFrom(cfg.getTable()); subqy.setConfig(cfg); - SQLConfig countSQLCfg = createSQLConfig(); + SQLConfig countSQLCfg = createSQLConfig(); countSQLCfg.setColumn(Arrays.asList("count(*):count")); countSQLCfg.setFrom(subqy); @@ -1205,14 +1197,14 @@ public JSONObject onObjectParse(final JSONObject request, String parentPath, Str else { // 对聚合函数字段通过 query:2 分页查总数返回值错误 RequestMethod method = op.getMethod(); - rp = op.setMethod(RequestMethod.HEAD).setSQLConfig().executeSQL().getSqlResponse(); + rp = op.setMethod(RequestMethod.HEAD).setSQLConfig().executeSQL().getSQLResponse(); op.setMethod(method); } if (rp != null) { int index = parentPath.lastIndexOf("]/"); if (index >= 0) { - int total = rp.getIntValue(JSONResponse.KEY_COUNT); + int total = getIntValue(rp, JSONResponse.KEY_COUNT); String pathPrefix = parentPath.substring(0, index) + "]/"; putQueryResult(pathPrefix + JSONResponse.KEY_TOTAL, total); @@ -1229,15 +1221,15 @@ public JSONObject onObjectParse(final JSONObject request, String parentPath, Str page += min; max += min; - JSONObject pagination = new JSONObject(true); + M pagination = JSON.createJSONObject(); Object explain = rp.get(JSONResponse.KEY_EXPLAIN); - if (explain instanceof JSONObject) { + if (explain instanceof Map) { pagination.put(JSONResponse.KEY_EXPLAIN, explain); } pagination.put(JSONResponse.KEY_TOTAL, total); - pagination.put(JSONRequest.KEY_COUNT, count); - pagination.put(JSONRequest.KEY_PAGE, page); + pagination.put(apijson.JSONRequest.KEY_COUNT, count); + pagination.put(apijson.JSONRequest.KEY_PAGE, page); pagination.put(JSONResponse.KEY_MAX, max); pagination.put(JSONResponse.KEY_MORE, page < max); pagination.put(JSONResponse.KEY_FIRST, page == min); @@ -1246,7 +1238,7 @@ public JSONObject onObjectParse(final JSONObject request, String parentPath, Str putQueryResult(pathPrefix + JSONResponse.KEY_INFO, pagination); if (total <= count*(page - min)) { - query = JSONRequest.QUERY_TOTAL;//数量不够了,不再往后查询 + query = apijson.JSONRequest.QUERY_TOTAL;//数量不够了,不再往后查询 } } } @@ -1255,7 +1247,7 @@ public JSONObject onObjectParse(final JSONObject request, String parentPath, Str } //Table - if (query == JSONRequest.QUERY_TOTAL) { + if (query == apijson.JSONRequest.QUERY_TOTAL) { response = null;//不再往后查询 } else { response = op @@ -1290,14 +1282,14 @@ public JSONObject onObjectParse(final JSONObject request, String parentPath, Str * @throws Exception */ @Override - public JSONArray onArrayParse(JSONObject request, String parentPath, String name, boolean isSubquery, JSONArray cache) throws Exception { + public L onArrayParse(M request, String parentPath, String name, boolean isSubquery, L cache) throws Exception { if (Log.DEBUG) { Log.i(TAG, "\n\n\n onArrayParse parentPath = " + parentPath + "; name = " + name + "; request = " + JSON.toJSONString(request)); } //不能允许GETS,否则会被通过"[]":{"@role":"ADMIN"},"Table":{},"tag":"Table"绕过权限并能批量查询 - RequestMethod _method = request.get(apijson.JSONObject.KEY_METHOD) == null ? requestMethod : RequestMethod.valueOf(request.getString(apijson.JSONObject.KEY_METHOD)); + RequestMethod _method = request.get(apijson.JSONObject.KEY_METHOD) == null ? requestMethod : RequestMethod.valueOf(getString(request, apijson.JSONObject.KEY_METHOD)); if (isSubquery == false && RequestMethod.isGetMethod(_method, true) == false) { throw new UnsupportedOperationException("key[]:{} 只支持 GET, GETS 方法!其它方法不允许传 " + name + ":{} 等这种 key[]:{} 格式!"); } @@ -1308,32 +1300,32 @@ public JSONArray onArrayParse(JSONObject request, String parentPath, String name //不能改变,因为后面可能继续用到,导致1以上都改变 []:{0:{Comment[]:{0:{Comment:{}},1:{...},...}},1:{...},...} - final String query = request.getString(JSONRequest.KEY_QUERY); - final Boolean compat = request.getBoolean(JSONRequest.KEY_COMPAT); - final Integer count = request.getInteger(JSONRequest.KEY_COUNT); //TODO 如果不想用默认数量可以改成 getIntValue(JSONRequest.KEY_COUNT); - final Integer page = request.getInteger(JSONRequest.KEY_PAGE); - final Object join = request.get(JSONRequest.KEY_JOIN); + final String query = getString(request, apijson.JSONRequest.KEY_QUERY); + final Boolean compat = getBoolean(request, apijson.JSONRequest.KEY_COMPAT); + final Integer count = getInteger(request, apijson.JSONRequest.KEY_COUNT); //TODO 如果不想用默认数量可以改成 getIntValue(apijson.JSONRequest.KEY_COUNT); + final Integer page = getInteger(request, apijson.JSONRequest.KEY_PAGE); + final Object join = request.get(apijson.JSONRequest.KEY_JOIN); int query2; if (query == null) { - query2 = JSONRequest.QUERY_TABLE; + query2 = apijson.JSONRequest.QUERY_TABLE; } else { switch (query) { case "0": - case JSONRequest.QUERY_TABLE_STRING: - query2 = JSONRequest.QUERY_TABLE; + case apijson.JSONRequest.QUERY_TABLE_STRING: + query2 = apijson.JSONRequest.QUERY_TABLE; break; case "1": - case JSONRequest.QUERY_TOTAL_STRING: - query2 = JSONRequest.QUERY_TOTAL; + case apijson.JSONRequest.QUERY_TOTAL_STRING: + query2 = apijson.JSONRequest.QUERY_TOTAL; break; case "2": - case JSONRequest.QUERY_ALL_STRING: - query2 = JSONRequest.QUERY_ALL; + case apijson.JSONRequest.QUERY_ALL_STRING: + query2 = apijson.JSONRequest.QUERY_ALL; break; default: - throw new IllegalArgumentException(path + "/" + JSONRequest.KEY_QUERY + ":value 中 value 的值不合法!必须在 [0, 1, 2] 或 [TABLE, TOTAL, ALL] 内 !"); + throw new IllegalArgumentException(path + "/" + apijson.JSONRequest.KEY_QUERY + ":value 中 value 的值不合法!必须在 [0, 1, 2] 或 [TABLE, TOTAL, ALL] 内 !"); } } @@ -1342,7 +1334,7 @@ public JSONArray onArrayParse(JSONObject request, String parentPath, String name int maxPage = getMaxQueryPage(); if (page2 < 0 || page2 > maxPage) { - throw new IllegalArgumentException(path + "/" + JSONRequest.KEY_PAGE + ":value 中 value 的值不合法!必须在 " + minPage + "-" + maxPage + " 内 !"); + throw new IllegalArgumentException(path + "/" + apijson.JSONRequest.KEY_PAGE + ":value 中 value 的值不合法!必须在 " + minPage + "-" + maxPage + " 内 !"); } //不用total限制数量了,只用中断机制,total只在query = 1,2的时候才获取 @@ -1350,14 +1342,14 @@ public JSONArray onArrayParse(JSONObject request, String parentPath, String name int max = isSubquery ? count2 : getMaxQueryCount(); if (count2 < 0 || count2 > max) { - throw new IllegalArgumentException(path + "/" + JSONRequest.KEY_COUNT + ":value 中 value 的值不合法!必须在 0-" + max + " 内 !"); + throw new IllegalArgumentException(path + "/" + apijson.JSONRequest.KEY_COUNT + ":value 中 value 的值不合法!必须在 0-" + max + " 内 !"); } - request.remove(JSONRequest.KEY_QUERY); - request.remove(JSONRequest.KEY_COMPAT); - request.remove(JSONRequest.KEY_COUNT); - request.remove(JSONRequest.KEY_PAGE); - request.remove(JSONRequest.KEY_JOIN); + request.remove(apijson.JSONRequest.KEY_QUERY); + request.remove(apijson.JSONRequest.KEY_COMPAT); + request.remove(apijson.JSONRequest.KEY_COUNT); + request.remove(apijson.JSONRequest.KEY_PAGE); + request.remove(apijson.JSONRequest.KEY_JOIN); Log.d(TAG, "onArrayParse query = " + query + "; count = " + count + "; page = " + page + "; join = " + join); if (request.isEmpty()) { // 如果条件成立,说明所有的 parentPath/name:request 中request都无效!!! 后续都不执行,没必要还原数组关键词浪费性能 @@ -1365,7 +1357,7 @@ public JSONArray onArrayParse(JSONObject request, String parentPath, String name return null; } - JSONArray response = null; + L response = null; try { int size = count2 == 0 ? max : count2; //count为每页数量,size为第page页实际数量,max(size) = count Log.d(TAG, "onArrayParse size = " + size + "; page = " + page2); @@ -1381,15 +1373,15 @@ public JSONArray onArrayParse(JSONObject request, String parentPath, String name if (childKeys == null || childKeys.length <= 0 || request.containsKey(childKeys[0]) == false) { childKeys = null; } - else if (childKeys.length == 1 && JSONRequest.isTableKey(childKeys[0])) { // 可能无需提取,直接返回 rawList 即可 + else if (childKeys.length == 1 && apijson.JSONObject.isTableKey(childKeys[0])) { // 可能无需提取,直接返回 rawList 即可 arrTableKey = childKeys[0]; } //Table<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - List joinList = onJoinParse(join, request); - SQLConfig config = createSQLConfig() + List> joinList = onJoinParse(join, request); + SQLConfig config = createSQLConfig() .setMethod(requestMethod) .setCount(size) .setPage(page2) @@ -1398,11 +1390,11 @@ else if (childKeys.length == 1 && JSONRequest.isTableKey(childKeys[0])) { // .setTable(arrTableKey) .setJoinList(joinList); - JSONObject parent; + Map parent; boolean isExtract = true; - response = new JSONArray(); + response = JSON.createJSONArray(); //生成size个 for (int i = 0; i < (isSubquery ? 1 : size); i++) { parent = onObjectParse(request, isSubquery ? parentPath : path, isSubquery ? name : "" + i, config.setType(SQLConfig.TYPE_ITEM).setPosition(i), isSubquery, null); @@ -1413,18 +1405,18 @@ else if (childKeys.length == 1 && JSONRequest.isTableKey(childKeys[0])) { // long startTime = System.currentTimeMillis(); /* 这里优化了 Table[]: { Table:{} } 这种情况下的性能 - * 如果把 List 改成 JSONArray 来减少以下 addAll 一次复制,则会导致 AbstractSQLExecutor 等其它很多地方 get 要改为 getJSONObject, - * 修改类型会导致不兼容旧版依赖 ORM 的项目,而且整体上性能只有特殊情况下性能提升,其它非特殊情况下因为多出很多 instanceof JSONObject 的判断而降低了性能。 + * 如果把 List> 改成 L 来减少以下 addAll 一次复制,则会导致 AbstractSQLExecutor 等其它很多地方 get 要改为 getJSONObject, + * 修改类型会导致不兼容旧版依赖 ORM 的项目,而且整体上性能只有特殊情况下性能提升,其它非特殊情况下因为多出很多 instanceof Map 的判断而降低了性能。 */ - JSONObject fo = i != 0 || arrTableKey == null ? null : parent.getJSONObject(arrTableKey); + Map fo = i != 0 || arrTableKey == null ? null : JSON.get(parent, arrTableKey); @SuppressWarnings("unchecked") - List list = fo == null ? null : (List) fo.remove(AbstractSQLExecutor.KEY_RAW_LIST); + List> list = fo == null ? null : (List>) fo.remove(AbstractSQLExecutor.KEY_RAW_LIST); if (list != null && list.isEmpty() == false && (joinList == null || joinList.isEmpty())) { isExtract = false; list.set(0, fo); // 不知道为啥第 0 项也加了 @RAW@LIST - response.addAll(list); // List cannot match List response = new JSONArray(list); + response.addAll(list); // List> cannot match List response = JSON.createJSONArray(list); long endTime = System.currentTimeMillis(); // 0ms Log.d(TAG, "\n onArrayParse <<<<<<<<<<<<<<<<<<<<<<<<<<<<\n for (int i = 0; i < (isSubquery ? 1 : size); i++) " @@ -1469,11 +1461,11 @@ else if (childKeys.length == 1 && JSONRequest.isTableKey(childKeys[0])) { // } finally { //后面还可能用到,要还原 - request.put(JSONRequest.KEY_QUERY, query); - request.put(JSONRequest.KEY_COMPAT, compat); - request.put(JSONRequest.KEY_COUNT, count); - request.put(JSONRequest.KEY_PAGE, page); - request.put(JSONRequest.KEY_JOIN, join); + request.put(apijson.JSONRequest.KEY_QUERY, query); + request.put(apijson.JSONRequest.KEY_COMPAT, compat); + request.put(apijson.JSONRequest.KEY_COUNT, count); + request.put(apijson.JSONRequest.KEY_PAGE, page); + request.put(apijson.JSONRequest.KEY_JOIN, join); } if (Log.DEBUG) { @@ -1487,26 +1479,26 @@ else if (childKeys.length == 1 && JSONRequest.isTableKey(childKeys[0])) { // private static final List JOIN_COPY_KEY_LIST; static { // TODO 不全 JOIN_COPY_KEY_LIST = new ArrayList(); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_ROLE); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_DATABASE); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_NAMESPACE); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_CATALOG); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_SCHEMA); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_DATASOURCE); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_COLUMN); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_NULL); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_CAST); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_COMBINE); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_GROUP); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_HAVING); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_HAVING_AND); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_SAMPLE); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_LATEST); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_PARTITION); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_FILL); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_ORDER); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_KEY); - JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_RAW); + 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 多表同时筛选 @@ -1515,23 +1507,23 @@ else if (childKeys.length == 1 && JSONRequest.isTableKey(childKeys[0])) { // * @return * @throws Exception */ - private List onJoinParse(Object join, JSONObject request) throws Exception { - JSONObject joinMap = null; + private List> onJoinParse(Object join, M request) throws Exception { + Map joinMap = null; - if (join instanceof JSONObject) { - joinMap = (JSONObject) join; + if (join instanceof Map) { + joinMap = (M) join; } else if (join instanceof String) { String[] sArr = request == null || request.isEmpty() ? null : StringUtil.split((String) join); if (sArr != null && sArr.length > 0) { - joinMap = new JSONObject(true); //注意:这里必须要保证join连接顺序,保证后边遍历是按照join参数的顺序生成的SQL + joinMap = new LinkedHashMap(); //注意:这里必须要保证join连接顺序,保证后边遍历是按照join参数的顺序生成的SQL for (int i = 0; i < sArr.length; i++) { - joinMap.put(sArr[i], new JSONObject()); + joinMap.put(sArr[i], new LinkedHashMap()); } } } else if (join != null){ - throw new UnsupportedDataTypeException(TAG + ".onJoinParse join 只能是 String 或 JSONObject 类型!"); + throw new UnsupportedDataTypeException(TAG + ".onJoinParse join 只能是 String 或 Map 类型!"); } Set> set = joinMap == null ? null : joinMap.entrySet(); @@ -1540,21 +1532,21 @@ else if (join != null){ return null; } - List joinList = new ArrayList<>(); + List> joinList = new ArrayList<>(); for (Entry e : set) { // { &/User:{}, == false) { + throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":value 中value不合法!" + "必须为 &/Table0/key0, ( ) <> () * @@ -1567,8 +1559,8 @@ 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 && JSONRequest.isArrayKey(arrKey) == false) { - throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + " 不是合法的数组 key[] !" + + if (arrKey != null && apijson.JSONObject.isArrayKey(arrKey) == false) { + throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + " 不是合法的数组 key[] !" + "@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中不能有 join: value 键值对!"); } @@ -1577,75 +1569,75 @@ else if (join != null){ apijson.orm.Entry entry = Pair.parseEntry(tableKey, true); String table = entry.getKey(); // User if (StringUtil.isName(table) == false) { - throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":value 中 value 的 Table 值 " + table + " 不合法!" + throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":value 中 value 的 Table 值 " + table + " 不合法!" + "必须为 &/Table0, 格式!" + e2.getMessage()); } if (arrKey != null) { - if (parentPathObj.get(JSONRequest.KEY_JOIN) != null) { - throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + ":{ join: value } 中 value 不合法!" + + if (parentPathObj.get(apijson.JSONRequest.KEY_JOIN) != null) { + throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + ":{ join: value } 中 value 不合法!" + "@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中不能有 join: value 键值对!"); } - Integer subPage = parentPathObj.getInteger(JSONRequest.KEY_PAGE); + Integer subPage = getInteger(parentPathObj, apijson.JSONRequest.KEY_PAGE); if (subPage != null && subPage != 0) { - throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + ":{ page: value } 中 value 不合法!" + + throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + ":{ page: value } 中 value 不合法!" + "@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中 page 值只能为 null 或 0 !"); } } boolean isAppJoin = "@".equals(joinType); - JSONObject refObj = new JSONObject(tableObj.size(), true); + M refObj = JSON.createJSONObject(); String key = index < 0 ? null : path.substring(index + 1); // id@ if (key != null) { // 指定某个 key 为 JOIN ON 条件 if (key.indexOf("@") != key.length() - 1) { - throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":" + e.getKey() + " 中 " + key + " 不合法!" + throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":" + e.getKey() + " 中 " + key + " 不合法!" + "必须为 &/Table0,> tableSet = tableObj.entrySet(); // 取出所有 join 条件 - JSONObject requestObj = new JSONObject(true); // (JSONObject) obj.clone(); + M requestObj = JSON.createJSONObject(); // (Map) obj.clone(); boolean matchSingle = false; for (Entry tableEntry : tableSet) { @@ -1670,15 +1662,15 @@ else if (join != null){ apijson.orm.Entry te = tk == null || p.substring(ind2 + 1).indexOf("/") >= 0 ? null : Pair.parseEntry(tk, true); - if (te != null && JSONRequest.isTableKey(te.getKey()) && request.get(tk) instanceof JSONObject) { + if (te != null && apijson.JSONObject.isTableKey(te.getKey()) && request.get(tk) instanceof Map) { if (isAppJoin) { if (refObj.size() >= 1) { - throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":" + e.getKey() + " 中 " + k + " 不合法!" + throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":" + e.getKey() + " 中 " + k + " 不合法!" + "@ APP JOIN 必须有且只有一个引用赋值键值对!"); } if (StringUtil.isName(k.substring(0, k.length() - 1)) == false) { - throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 中 " + k + " 不合法 !" + + throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 中 " + k + " 不合法 !" + "@ APP JOIN 只允许 key@:/Table/refKey 这种 = 等价连接!"); } } @@ -1694,7 +1686,7 @@ else if (join != null){ continue; } - throw new UnsupportedOperationException(table + "/" + k + " 不合法!" + JSONRequest.KEY_JOIN + " 关联的 Table 中," + throw new UnsupportedOperationException(table + "/" + k + " 不合法!" + apijson.JSONRequest.KEY_JOIN + " 关联的 Table 中," + "join: ?/Table/key 时只能有 1 个 key@:value;join: ?/Table 时所有 key@:value 要么是符合 join 格式,要么能直接解析成具体值!"); // TODO 支持 join on } @@ -1705,7 +1697,7 @@ else if (join != null){ } else { if (k.endsWith("@")) { - throw new UnsupportedOperationException(table + "/" + k + " 不合法!" + JSONRequest.KEY_JOIN + " 关联的 Table 中," + throw new UnsupportedOperationException(table + "/" + k + " 不合法!" + apijson.JSONRequest.KEY_JOIN + " 关联的 Table 中," + "join: ?/Table/key 时只能有 1 个 key@:value;join: ?/Table 时所有 key@:value 要么是符合 join 格式,要么能直接解析成具体值!"); // TODO 支持 join on } @@ -1717,21 +1709,24 @@ else if (join != null){ Set> refSet = refObj.entrySet(); if (refSet.isEmpty() && "*".equals(joinType) == false) { - throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":value 中 value 的 alias 值 " + alias + " 不合法!" + throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":value 中 value 的 alias 值 " + alias + " 不合法!" + "必须为 &/Table0, j = new Join<>(); j.setPath(e.getKey()); j.setJoinType(joinType); j.setTable(table); j.setAlias(alias); - j.setOuter((JSONObject) outer); + + M outerObj = (M) JSON.createJSONObject((Map) outer); + j.setOuter(outerObj); j.setRequest(requestObj); + if (arrKey != null) { - Integer count = parentPathObj.getInteger(JSONRequest.KEY_COUNT); + Integer count = getInteger(parentPathObj, apijson.JSONRequest.KEY_COUNT); j.setCount(count == null ? getDefaultQueryCount() : count); } @@ -1773,22 +1768,22 @@ else if (join != null){ } //对引用的JSONObject添加条件 - JSONObject targetObj; + Map targetObj; try { - targetObj = request.getJSONObject(targetTableKey); + targetObj = JSON.get(request, targetTableKey); } catch (Exception e2) { - throw new IllegalArgumentException(e.getKey() + ":'/targetTable/targetKey' 中路径对应的 '" + targetTableKey + "':value 中 value 类型不合法!必须是 {} 这种 JSONObject 格式!" + e2.getMessage()); + throw new IllegalArgumentException(e.getKey() + ":'/targetTable/targetKey' 中路径对应的 '" + targetTableKey + "':value 中 value 类型不合法!必须是 {} 这种 Map 格式!" + e2.getMessage()); } if (targetObj == null) { - throw new IllegalArgumentException(e.getKey() + ":'/targetTable/targetKey' 中路径对应的对象 '" + targetTableKey + "':{} 不存在或值为 null !必须是 {} 这种 JSONObject 格式!"); + throw new IllegalArgumentException(e.getKey() + ":'/targetTable/targetKey' 中路径对应的对象 '" + targetTableKey + "':{} 不存在或值为 null !必须是 {} 这种 Map 格式!"); } Join.On on = new Join.On(); on.setKeyAndType(j.getJoinType(), j.getTable(), originKey); if (StringUtil.isName(on.getKey()) == false) { - throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":value 中 value 的 key@ 中 key 值 " + on.getKey() + " 不合法!必须满足英文单词变量名格式!"); + throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":value 中 value 的 key@ 中 key 值 " + on.getKey() + " 不合法!必须满足英文单词变量名格式!"); } on.setOriginKey(originKey); @@ -1807,7 +1802,7 @@ else if (join != null){ // onList.add(table + "." + key + " = " + targetTable + "." + targetKey); // ON User.id = Moment.userId // 保证和 SQLExcecutor 缓存的 Config 里 where 顺序一致,生成的 SQL 也就一致 <<<<<<<<< - // AbstractSQLConfig.newSQLConfig 中强制把 id, id{}, userId, userId{} 放到了最前面 tableObj.put(key, tableObj.remove(key)); + // AbstractSQLConfig.newSQLConfig 中强制把 id, id{}, userId, userId{} 放到了最前面 tableObj.put(key, tableObj.remove(key)); if (refObj.size() != tableObj.size()) { // 把 key 强制放最前,AbstractSQLExcecutor 中 config.putWhere 也是放尽可能最前 refObj.putAll(tableObj); @@ -1819,8 +1814,8 @@ else if (join != null){ // 保证和 SQLExcecutor 缓存的 Config 里 where 顺序一致,生成的 SQL 也就一致 >>>>>>>>> } - //拼接多个 SQLConfig 的SQL语句,然后执行,再把结果分别缓存(Moment, User等)到 SQLExecutor 的 cacheMap - // AbstractSQLConfig config0 = null; + //拼接多个 SQLConfig 的SQL语句,然后执行,再把结果分别缓存(Moment, User等)到 SQLExecutor 的 cacheMap + // AbstractSQLConfig config0 = null; // String sql = "SELECT " + config0.getColumnString() + " FROM " + config0.getTable() + " INNER JOIN " + targetTable + " ON " // + onList.get(0) + config0.getGroupString() + config0.getHavingString() + config0.getOrderString(); @@ -1832,7 +1827,7 @@ else if (join != null){ * @param pathKeys * @return */ - public static V getValue(JSONObject parent, String[] pathKeys) { + public static V getValue(Map parent, String[] pathKeys) { if (parent == null || pathKeys == null || pathKeys.length <= 0) { Log.w(TAG, "getChild parent == null || pathKeys == null || pathKeys.length <= 0 >> return parent;"); return (V) parent; @@ -1846,7 +1841,7 @@ public static V getValue(JSONObject parent, String[] pathKeys } String k = getDecodedKey(pathKeys[i]); - parent = getJSONObject(parent, k); + parent = JSON.get(parent, k); } return parent == null ? null : (V) parent.get(getDecodedKey(pathKeys[last])); @@ -1955,16 +1950,16 @@ public Object getValueByPath(String valuePath) { } //取出key被valuePath包含的result,再从里面获取key对应的value - JSONObject parent = null; + Map parent = null; String[] keys = null; - for (Entry entry : queryResultMap.entrySet()){ + for (Entry entry : queryResultMap.entrySet()){ String path = entry.getKey(); if (valuePath.startsWith(path + "/")) { try { - parent = (JSONObject) entry.getValue(); + parent = (M) entry.getValue(); } catch (Exception e) { - Log.e(TAG, "getValueByPath try { parent = (JSONObject) queryResultMap.get(path); } catch { " - + "\n parent not instanceof JSONObject!"); + Log.e(TAG, "getValueByPath try { parent = (Map) queryResultMap.get(path); } catch { " + + "\n parent not instanceof Map!"); parent = null; } if (parent != null) { @@ -1983,7 +1978,8 @@ public Object getValueByPath(String valuePath) { } String k = getDecodedKey(keys[i]); - parent = getJSONObject(parent, k); + Object p = parent.get(k); + parent = p instanceof Map ? (Map) p : null; } } @@ -2023,44 +2019,31 @@ public static String getDecodedKey(String key) { //依赖引用关系 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - - - public static JSONObject getJSONObject(JSONObject object, String key) { - try { - return object.getJSONObject(key); - } catch (Exception e) { - Log.i(TAG, "getJSONObject try { return object.getJSONObject(key);" - + " } catch (Exception e) { \n" + e.getMessage()); - } - return null; - } - - public static final String KEY_CONFIG = "config"; public static final String KEY_SQL = "sql"; - protected Map> arrayMainCacheMap = new HashMap<>(); - public void putArrayMainCache(String arrayPath, List mainTableDataList) { + protected Map> arrayMainCacheMap = new HashMap<>(); + public void putArrayMainCache(String arrayPath, List mainTableDataList) { arrayMainCacheMap.put(arrayPath, mainTableDataList); } - public List getArrayMainCache(String arrayPath) { + public List getArrayMainCache(String arrayPath) { return arrayMainCacheMap.get(arrayPath); } - public JSONObject getArrayMainCacheItem(String arrayPath, int position) { - List list = getArrayMainCache(arrayPath); + public M getArrayMainCacheItem(String arrayPath, int position) { + List list = getArrayMainCache(arrayPath); return list == null || position >= list.size() ? null : list.get(position); } - /**执行 SQL 并返回 JSONObject + /**执行 SQL 并返回 Map * @param config * @return * @throws Exception */ @Override - public JSONObject executeSQL(SQLConfig config, boolean isSubquery) throws Exception { + public M executeSQL(SQLConfig config, boolean isSubquery) throws Exception { if (config == null) { Log.d(TAG, "executeSQL config == null >> return null;"); return null; @@ -2071,44 +2054,44 @@ public JSONObject executeSQL(SQLConfig config, boolean isSubquery) throws Exc config.setTag(getTag()); if (isSubquery) { - JSONObject sqlObj = new JSONObject(true); + M sqlObj = JSON.createJSONObject(); sqlObj.put(KEY_CONFIG, config); return sqlObj;//容易丢失信息 JSON.parseObject(config); } try { - JSONObject result; + M result; boolean explain = config.isExplain(); if (explain) { //如果先执行 explain,则 execute 会死循环,所以只能先执行非 explain config.setExplain(false); //对下面 config.getSQL(false); 生效 - JSONObject res = getSQLExecutor().execute(config, false); + M res = getSQLExecutor().execute(config, false); //如果是查询方法,才能执行explain if (RequestMethod.isQueryMethod(config.getMethod()) && config.isElasticsearch() == false){ config.setExplain(explain); - JSONObject explainResult = config.isMain() && config.getPosition() != 0 ? null : getSQLExecutor().execute(config, false); + Map explainResult = config.isMain() && config.getPosition() != 0 ? null : getSQLExecutor().execute(config, false); if (explainResult == null) { result = res; } else { - result = new JSONObject(true); + result = JSON.createJSONObject(); result.put(KEY_EXPLAIN, explainResult); result.putAll(res); } } else {//如果是更新请求,不执行explain,但可以返回sql - result = new JSONObject(true); - result.put(KEY_SQL, config.getSQL(false)); + result = JSON.createJSONObject(); + result.put(KEY_SQL, config.gainSQL(false)); result.putAll(res); } } else { sqlExecutor = getSQLExecutor(); result = sqlExecutor.execute(config, false); - // FIXME 改为直接在 sqlExecutor 内加好,最后 Parser 取结果,可以解决并发执行导致内部计算出错 + // FIXME 改为直接在 sqlExecutor 内加好,最后 Parser 取结果,可以解决并发执行导致内部计算出错 // executedSQLDuration += sqlExecutor.getExecutedSQLDuration() + sqlExecutor.getSqlResultDuration(); } @@ -2229,8 +2212,8 @@ protected void onClose() { queryResultMap = null; } - private void setOpMethod(JSONObject request, ObjectParser op, String key) { - String _method = key == null ? null : request.getString(apijson.JSONObject.KEY_METHOD); + private void setOpMethod(Map request, ObjectParser op, String key) { + String _method = key == null ? null : getString(request, apijson.JSONObject.KEY_METHOD); if (_method != null) { RequestMethod method = RequestMethod.valueOf(_method); // 必须精准匹配,避免缓存命中率低 this.setMethod(method); @@ -2238,9 +2221,9 @@ private void setOpMethod(JSONObject request, ObjectParser op, String key) { } } - protected JSONObject getRequestStructure(RequestMethod method, String tag, int version) throws Exception { + protected M getRequestStructure(RequestMethod method, String tag, int version) throws Exception { // 获取指定的JSON结构 <<<<<<<<<<<< - JSONObject object = null; + M object = null; String error = ""; try { object = getStructure("Request", method.name(), tag, version); @@ -2254,8 +2237,8 @@ protected JSONObject getRequestStructure(RequestMethod method, String tag, int v return object; } - protected JSONObject batchVerify(RequestMethod method, String tag, int version, String name, @NotNull JSONObject request, int maxUpdateCount, SQLCreator creator) throws Exception { - JSONObject correctRequest = new JSONObject(true); + protected M batchVerify(RequestMethod method, String tag, int version, String name, @NotNull M request, int maxUpdateCount, SQLCreator creator) throws Exception { + M correctRequest = JSON.createJSONObject(); List removeTmpKeys = new ArrayList<>(); // 请求json里面的临时变量,不需要带入后面的业务中,比如 @post、@get等 Set reqSet = request == null ? null : request.keySet(); @@ -2269,34 +2252,34 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, throw new IllegalArgumentException("对象名重复,请添加别名区分 ! 重复对象名为: " + key); } - boolean isPost = apijson.orm.JSONRequest.KEY_POST.equals(key); + boolean isPost = apijson.JSONObject.KEY_POST.equals(key); // @post、@get 等 RequestMethod try { - RequestMethod keyMethod = isPost ? RequestMethod.POST : JSONRequest.KEY_METHOD_ENUM_MAP.get(key); + RequestMethod keyMethod = isPost ? RequestMethod.POST : apijson.JSONObject.KEY_METHOD_ENUM_MAP.get(key); if (keyMethod != null) { // 如果不匹配,异常不处理即可 removeTmpKeys.add(key); Object val = request.get(key); - JSONObject obj = val instanceof JSONObject ? request.getJSONObject(key) : null; + Map obj = val instanceof Map ? JSON.get(request, key) : null; if (obj == null) { if (val instanceof String) { String[] tbls = StringUtil.split((String) val); if (tbls != null && tbls.length > 0) { - obj = new JSONObject(true); + obj = new LinkedHashMap(); for (int i = 0; i < tbls.length; i++) { String tbl = tbls[i]; if (obj.containsKey(tbl)) { throw new ConflictException(key + ": value 中 " + tbl + " 已经存在,不能重复!"); } - obj.put(tbl, isPost && JSONRequest.isTableArray(tbl) + obj.put(tbl, isPost && apijson.JSONObject.isTableArray(tbl) ? tbl.substring(0, tbl.length() - 2) + ":[]" : ""); } } } else { - throw new IllegalArgumentException(key + ": value 中 value 类型错误,只能是 String 或 JSONObject {} !"); + throw new IllegalArgumentException(key + ": value 中 value 类型错误,只能是 String 或 Map {} !"); } } @@ -2313,13 +2296,13 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, keyObjectAttributesMap.put(objKey, objAttrMap); Object objVal = objEntry.getValue(); - JSONObject objAttrJson = objVal instanceof JSONObject ? obj.getJSONObject(objKey) : null; + Map objAttrJson = objVal instanceof Map ? JSON.getMap(obj, objKey) : null; if (objAttrJson == null) { if (objVal instanceof String) { - objAttrMap.put(JSONRequest.KEY_TAG, "".equals(objVal) ? objKey : objVal); + objAttrMap.put(apijson.JSONRequest.KEY_TAG, "".equals(objVal) ? objKey : objVal); } else { - throw new IllegalArgumentException(key + ": { " + objKey + ": value 中 value 类型错误,只能是 String 或 JSONObject {} !"); + throw new IllegalArgumentException(key + ": { " + objKey + ": value 中 value 类型错误,只能是 String 或 Map {} !"); } } else { @@ -2336,11 +2319,11 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, case apijson.JSONObject.KEY_DATASOURCE: case apijson.JSONObject.KEY_SCHEMA: case apijson.JSONObject.KEY_DATABASE: - case JSONRequest.KEY_VERSION: + case apijson.JSONRequest.KEY_VERSION: case apijson.JSONObject.KEY_ROLE: objAttrMap.put(objAttrKey, entry.getValue()); break; - case JSONRequest.KEY_TAG: + case apijson.JSONRequest.KEY_TAG: hasTag = true; objAttrMap.put(objAttrKey, entry.getValue()); break; @@ -2350,7 +2333,7 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, } if (hasTag == false) { - objAttrMap.put(JSONRequest.KEY_TAG, isPost && JSONRequest.isTableArray(objKey) + objAttrMap.put(apijson.JSONRequest.KEY_TAG, isPost && apijson.JSONObject.isTableArray(objKey) ? objKey.substring(0, objKey.length() - 2) + ":[]" : objKey); } } @@ -2360,23 +2343,23 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, // 1、非crud,对于没有显式声明操作方法的,直接用 URL(/get, /post 等) 对应的默认操作方法 // 2、crud, 没有声明就用 GET - // 3、兼容 sql@ JSONObject,设置 GET方法 + // 3、兼容 sql@ Map,设置 GET方法 // 将method 设置到每个object, op执行会解析 Object obj = request.get(key); - if (obj instanceof JSONObject) { + if (obj instanceof Map) { Map attrMap = keyObjectAttributesMap.get(key); if (attrMap == null) { // 数组会解析为对象进行校验,做一下兼容 if (keyObjectAttributesMap.get(key + apijson.JSONObject.KEY_ARRAY) == null) { if (method == RequestMethod.CRUD || key.endsWith("@")) { - ((JSONObject) obj).put(apijson.JSONObject.KEY_METHOD, GET); + ((Map) obj).put(apijson.JSONObject.KEY_METHOD, GET); Map objAttrMap = new HashMap<>(); objAttrMap.put(apijson.JSONObject.KEY_METHOD, GET); keyObjectAttributesMap.put(key, objAttrMap); } else { - ((JSONObject) obj).put(apijson.JSONObject.KEY_METHOD, method); + ((Map) obj).put(apijson.JSONObject.KEY_METHOD, method); Map objAttrMap = new HashMap<>(); objAttrMap.put(apijson.JSONObject.KEY_METHOD, method); keyObjectAttributesMap.put(key, objAttrMap); @@ -2386,7 +2369,7 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, 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.JSONObject.VERSION, request); + setRequestAttribute(key, true, apijson.JSONRequest.KEY_VERSION, request); setRequestAttribute(key, true, apijson.JSONObject.KEY_ROLE, request); } } else { @@ -2394,7 +2377,7 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, 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.JSONObject.VERSION, request); + setRequestAttribute(key, false, apijson.JSONRequest.KEY_VERSION, request); setRequestAttribute(key, false, apijson.JSONObject.KEY_ROLE, request); } } @@ -2404,13 +2387,13 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, continue; } - if (obj instanceof JSONObject || obj instanceof JSONArray) { + if (obj instanceof Map || obj instanceof List) { RequestMethod _method; - if (obj instanceof JSONObject) { - JSONObject tblObj = request.getJSONObject(key); - String mn = tblObj == null ? null : tblObj.getString(apijson.JSONObject.KEY_METHOD); + if (obj instanceof Map) { + Map tblObj = JSON.getMap(request, key); + String mn = tblObj == null ? null : getString(tblObj, apijson.JSONObject.KEY_METHOD); _method = mn == null ? null : RequestMethod.valueOf(mn); - String combine = _method == null ? null : tblObj.getString(KEY_COMBINE); + String combine = _method == null ? null : getString(tblObj, KEY_COMBINE); if (combine != null && RequestMethod.isPublicMethod(_method) == false) { throw new IllegalArgumentException(key + ":{} 里的 @combine:value 不合法!开放请求 GET、HEAD 才允许传 @combine:value !"); } @@ -2446,18 +2429,18 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, } if (tag != null && ! tag.contains(":")) { - JSONObject object = getRequestStructure(_method, tag, version); - JSONObject ret = objectVerify(_method, tag, version, name, request, maxUpdateCount, creator, object); + M object = getRequestStructure(_method, tag, version); + M ret = objectVerify(_method, tag, version, name, request, maxUpdateCount, creator, object); correctRequest.putAll(ret); break; } String _tag = buildTag(request, key, method, tag); - JSONObject object = getRequestStructure(_method, _tag, version); + M object = getRequestStructure(_method, _tag, version); if (method == RequestMethod.CRUD && StringUtil.isEmpty(tag, true)) { - JSONObject requestItem = new JSONObject(); + M requestItem = JSON.createJSONObject(); requestItem.put(key, obj); - JSONObject ret = objectVerify(_method, _tag, version, name, requestItem, maxUpdateCount, creator, object); + Map ret = objectVerify(_method, _tag, version, name, requestItem, maxUpdateCount, creator, object); correctRequest.put(key, ret.get(key)); } else { return objectVerify(_method, _tag, version, name, request, maxUpdateCount, creator, object); @@ -2490,10 +2473,10 @@ public static > E getEnum(final Class enumClass, final Stri } } - protected void setRequestAttribute(String key, boolean isArray, String attrKey, @NotNull JSONObject request) { + protected void setRequestAttribute(String key, boolean isArray, String attrKey, @NotNull Map request) { Map attrMap = keyObjectAttributesMap.get(isArray ? key + apijson.JSONObject.KEY_ARRAY : key); Object attrVal = attrMap == null ? null : attrMap.get(attrKey); - JSONObject obj = attrVal == null ? null : request.getJSONObject(key); + Map obj = attrVal == null ? null : JSON.get(request, key); if (obj != null && obj.get(attrKey) == null) { // 如果对象内部已经包含该属性,不覆盖 @@ -2501,10 +2484,10 @@ protected void setRequestAttribute(String key, boolean isArray, String attrKey, } } - protected String buildTag(JSONObject request, String key, RequestMethod method, String tag) { + protected String buildTag(Map request, String key, RequestMethod method, String tag) { if (method == RequestMethod.CRUD) { Map attrMap = keyObjectAttributesMap.get(key); - Object _tag = attrMap == null ? null : attrMap.get(JSONRequest.KEY_TAG); + Object _tag = attrMap == null ? null : attrMap.get(apijson.JSONRequest.KEY_TAG); return _tag != null ? _tag.toString() : StringUtil.isEmpty(tag) ? key : tag; } else { if (StringUtil.isEmpty(tag, true)) { @@ -2515,11 +2498,21 @@ protected String buildTag(JSONObject request, String key, RequestMethod method, } - protected JSONObject objectVerify(RequestMethod method, String tag, int version, String name, @NotNull JSONObject request - , int maxUpdateCount, SQLCreator creator, JSONObject object) throws Exception { + protected M objectVerify(RequestMethod method, String tag, int version, String name, @NotNull M request + , int maxUpdateCount, SQLCreator creator, M object) throws Exception { // 获取指定的JSON结构 >>>>>>>>>>>>>> - JSONObject target = wrapRequest(method, tag, object, true); - // JSONObject clone 浅拷贝没用,Structure.parse 会导致 structure 里面被清空,第二次从缓存里取到的就是 {} + M target = wrapRequest(method, tag, object, true, new JSONCreator() { + @Override + public M createJSONObject() { + return JSON.createJSONObject(); + } + + @Override + public L createJSONArray() { + return JSON.createJSONArray(); + } + }); + // Map clone 浅拷贝没用,Structure.parse 会导致 structure 里面被清空,第二次从缓存里取到的就是 {} return getVerifier().verifyRequest(method, name, target, request, maxUpdateCount, getGlobalDatabase(), getGlobalSchema(), creator); } @@ -2530,7 +2523,7 @@ protected JSONObject objectVerify(RequestMethod method, String tag, int version, * @return */ public RequestMethod getRealMethod(RequestMethod method, String key, Object value) { - if (method == CRUD && (value instanceof JSONObject || value instanceof JSONArray)) { + if (method == CRUD && (value instanceof Map || value instanceof List)) { Map attrMap = keyObjectAttributesMap.get(key); Object _method = attrMap == null ? null : attrMap.get(apijson.JSONObject.KEY_METHOD); if (_method instanceof RequestMethod) { diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java index 4dd665edf..cc8d72f81 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java @@ -5,21 +5,11 @@ package apijson.orm; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.annotation.JSONField; - import java.util.*; import java.util.Map.Entry; import java.util.regex.Pattern; -import apijson.JSON; -import apijson.JSONResponse; -import apijson.Log; -import apijson.NotNull; -import apijson.RequestMethod; -import apijson.SQL; -import apijson.StringUtil; +import apijson.*; import apijson.orm.Join.On; import apijson.orm.exception.NotExistException; import apijson.orm.exception.UnsupportedDataTypeException; @@ -40,6 +30,8 @@ import apijson.orm.model.Table; import apijson.orm.model.TestRecord; +import static apijson.JSON.getBoolean; +import static apijson.JSON.getString; import static apijson.JSONObject.*; import static apijson.RequestMethod.DELETE; import static apijson.RequestMethod.GET; @@ -53,7 +45,8 @@ /**config sql for JSON Request * @author Lemon */ -public abstract class AbstractSQLConfig implements SQLConfig { +public abstract class AbstractSQLConfig, L extends List> + implements SQLConfig { private static final String TAG = "AbstractSQLConfig"; /** @@ -815,39 +808,39 @@ public abstract class AbstractSQLConfig implements SQLConfig parser; + private Parser parser; @Override - public Parser getParser() { + public Parser gainParser() { if (parser == null && objectParser != null) { parser = objectParser.getParser(); } return parser; } @Override - public AbstractSQLConfig setParser(Parser parser) { + public AbstractSQLConfig setParser(Parser parser) { this.parser = parser; return this; } - public AbstractSQLConfig putWarnIfNeed(String type, String warn) { + public AbstractSQLConfig putWarnIfNeed(String type, String warn) { if (Log.DEBUG && parser instanceof AbstractParser) { - ((AbstractParser) parser).putWarnIfNeed(type, warn); + ((AbstractParser) parser).putWarnIfNeed(type, warn); } return this; } - public AbstractSQLConfig putWarn(String type, String warn) { + public AbstractSQLConfig putWarn(String type, String warn) { if (Log.DEBUG && parser instanceof AbstractParser) { - ((AbstractParser) parser).putWarn(type, warn); + ((AbstractParser) parser).putWarn(type, warn); } return this; } - private ObjectParser objectParser; + private ObjectParser objectParser; @Override - public ObjectParser getObjectParser() { + public ObjectParser gainObjectParser() { return objectParser; } @Override - public AbstractSQLConfig setObjectParser(ObjectParser objectParser) { + public AbstractSQLConfig setObjectParser(ObjectParser objectParser) { this.objectParser = objectParser; return this; } @@ -861,7 +854,7 @@ public int getVersion() { return version; } @Override - public AbstractSQLConfig setVersion(int version) { + public AbstractSQLConfig setVersion(int version) { this.version = version; return this; } @@ -875,19 +868,19 @@ public String getTag() { return tag; } @Override - public AbstractSQLConfig setTag(String tag) { + public AbstractSQLConfig setTag(String tag) { this.tag = tag; return this; } // mysql8版本以上,子查询支持with as表达式 - private List withAsExprSqlList = null; + private List withAsExprSQLList = null; protected List withAsExprPreparedValueList = new ArrayList<>(); private int[] dbVersionNums = null; @Override - public int[] getDBVersionNums() { + public int[] gainDBVersionNums() { if (dbVersionNums == null || dbVersionNums.length <= 0) { - dbVersionNums = SQLConfig.super.getDBVersionNums(); + dbVersionNums = SQLConfig.super.gainDBVersionNums(); } return dbVersionNums; } @@ -915,7 +908,6 @@ public String getUserIdKey() { return KEY_USER_ID; } - private RequestMethod method; //操作方法 private boolean prepared = true; //预编译 private boolean main = true; @@ -949,7 +941,7 @@ public String getUserIdKey() { private Map keyMap; //字段名映射,支持 name_tag:(name,tag) 多字段 IN,year:left(date,4) 截取日期年份等 private List raw; //需要保留原始 SQL 的字段,','分隔 private List json; //需要转为 JSON 的字段,','分隔 - private Subquery from; //子查询临时表 + private Subquery from; //子查询临时表 private List column; //表内字段名(或函数名,仅查询操作可用)的字符串数组,','分隔 private List> values; //对应表内字段的值的字符串数组,','分隔 private List nulls; @@ -963,19 +955,19 @@ public String getUserIdKey() { private int count; //Table数量 private int page; //Table所在页码 private int position; //Table在[]中的位置 - private int query; //JSONRequest.query - private Boolean compat; //JSONRequest.compat query total + private int query; //apijson.JSONRequest.QUERY + private Boolean compat; //apijson.JSONObject.compat query total private int type; //ObjectParser.type private int cache; private boolean explain; - private List joinList; //连表 配置列表 + private List> joinList; //连表 配置列表 //array item >>>>>>>>>> private boolean test; //测试 private String procedure; - public AbstractSQLConfig setProcedure(String procedure) { + public AbstractSQLConfig setProcedure(String procedure) { this.procedure = procedure; return this; } @@ -1005,7 +997,7 @@ public RequestMethod getMethod() { return method; } @Override - public AbstractSQLConfig setMethod(RequestMethod method) { + public AbstractSQLConfig setMethod(RequestMethod method) { this.method = method; return this; } @@ -1014,7 +1006,7 @@ public boolean isPrepared() { return prepared && ! isMongoDB(); // MongoDB JDBC 还不支持预编译; } @Override - public AbstractSQLConfig setPrepared(boolean prepared) { + public AbstractSQLConfig setPrepared(boolean prepared) { this.prepared = prepared; return this; } @@ -1023,7 +1015,7 @@ public boolean isMain() { return main; } @Override - public AbstractSQLConfig setMain(boolean main) { + public AbstractSQLConfig setMain(boolean main) { this.main = main; return this; } @@ -1034,7 +1026,7 @@ public Object getId() { return id; } @Override - public AbstractSQLConfig setId(Object id) { + public AbstractSQLConfig setId(Object id) { this.id = id; return this; } @@ -1044,7 +1036,7 @@ public Object getIdIn() { return idIn; } @Override - public AbstractSQLConfig setIdIn(Object idIn) { + public AbstractSQLConfig setIdIn(Object idIn) { this.idIn = idIn; return this; } @@ -1055,7 +1047,7 @@ public Object getUserId() { return userId; } @Override - public AbstractSQLConfig setUserId(Object userId) { + public AbstractSQLConfig setUserId(Object userId) { this.userId = userId; return this; } @@ -1065,7 +1057,7 @@ public Object getUserIdIn() { return userIdIn; } @Override - public AbstractSQLConfig setUserIdIn(Object userIdIn) { + public AbstractSQLConfig setUserIdIn(Object userIdIn) { this.userIdIn = userIdIn; return this; } @@ -1076,7 +1068,7 @@ public String getRole() { return role; } @Override - public AbstractSQLConfig setRole(String role) { + public AbstractSQLConfig setRole(String role) { this.role = role; return this; } @@ -1086,7 +1078,7 @@ public boolean isDistinct() { return distinct; } @Override - public AbstractSQLConfig setDistinct(boolean distinct) { + public AbstractSQLConfig setDistinct(boolean distinct) { this.distinct = distinct; return this; } @@ -1096,7 +1088,7 @@ public String getDatabase() { return database; } @Override - public AbstractSQLConfig setDatabase(String database) { + public AbstractSQLConfig setDatabase(String database) { this.database = database; return this; } @@ -1104,7 +1096,7 @@ public AbstractSQLConfig setDatabase(String database) { * @return db == null ? DEFAULT_DATABASE : db */ @NotNull - public String getSQLDatabase() { + public String gainSQLDatabase() { String db = getDatabase(); return db == null ? DEFAULT_DATABASE : db; // "" 表示已设置,不需要用全局默认的 StringUtil.isEmpty(db, false)) { } @@ -1124,7 +1116,7 @@ public boolean isPSQL() { // 兼容 PostgreSQL 语法,但不一定可以使用 @Override public boolean isMySQL() { - return isMySQL(getSQLDatabase()); + return isMySQL(gainSQLDatabase()); } public static boolean isMySQL(String db) { return DATABASE_MYSQL.equals(db); @@ -1132,7 +1124,7 @@ public static boolean isMySQL(String db) { @Override public boolean isPostgreSQL() { - return isPostgreSQL(getSQLDatabase()); + return isPostgreSQL(gainSQLDatabase()); } public static boolean isPostgreSQL(String db) { return DATABASE_POSTGRESQL.equals(db); @@ -1140,7 +1132,7 @@ public static boolean isPostgreSQL(String db) { @Override public boolean isSQLServer() { - return isSQLServer(getSQLDatabase()); + return isSQLServer(gainSQLDatabase()); } public static boolean isSQLServer(String db) { return DATABASE_SQLSERVER.equals(db); @@ -1148,7 +1140,7 @@ public static boolean isSQLServer(String db) { @Override public boolean isOracle() { - return isOracle(getSQLDatabase()); + return isOracle(gainSQLDatabase()); } public static boolean isOracle(String db) { return DATABASE_ORACLE.equals(db); @@ -1156,7 +1148,7 @@ public static boolean isOracle(String db) { @Override public boolean isDb2() { - return isDb2(getSQLDatabase()); + return isDb2(gainSQLDatabase()); } public static boolean isDb2(String db) { return DATABASE_DB2.equals(db); @@ -1164,7 +1156,7 @@ public static boolean isDb2(String db) { @Override public boolean isMariaDB() { - return isMariaDB(getSQLDatabase()); + return isMariaDB(gainSQLDatabase()); } public static boolean isMariaDB(String db) { return DATABASE_MARIADB.equals(db); @@ -1172,7 +1164,7 @@ public static boolean isMariaDB(String db) { @Override public boolean isTiDB() { - return isTiDB(getSQLDatabase()); + return isTiDB(gainSQLDatabase()); } public static boolean isTiDB(String db) { return DATABASE_TIDB.equals(db); @@ -1180,7 +1172,7 @@ public static boolean isTiDB(String db) { @Override public boolean isCockroachDB() { - return isCockroachDB(getSQLDatabase()); + return isCockroachDB(gainSQLDatabase()); } public static boolean isCockroachDB(String db) { return DATABASE_COCKROACHDB.equals(db); @@ -1188,7 +1180,7 @@ public static boolean isCockroachDB(String db) { @Override public boolean isDameng() { - return isDameng(getSQLDatabase()); + return isDameng(gainSQLDatabase()); } public static boolean isDameng(String db) { return DATABASE_DAMENG.equals(db); @@ -1196,7 +1188,7 @@ public static boolean isDameng(String db) { @Override public boolean isKingBase() { - return isKingBase(getSQLDatabase()); + return isKingBase(gainSQLDatabase()); } public static boolean isKingBase(String db) { return DATABASE_KINGBASE.equals(db); @@ -1204,7 +1196,7 @@ public static boolean isKingBase(String db) { @Override public boolean isElasticsearch() { - return isElasticsearch(getSQLDatabase()); + return isElasticsearch(gainSQLDatabase()); } public static boolean isElasticsearch(String db) { return DATABASE_ELASTICSEARCH.equals(db); @@ -1212,7 +1204,7 @@ public static boolean isElasticsearch(String db) { @Override public boolean isManticore() { - return isManticore(getSQLDatabase()); + return isManticore(gainSQLDatabase()); } public static boolean isManticore(String db) { return DATABASE_MANTICORE.equals(db); @@ -1220,7 +1212,7 @@ public static boolean isManticore(String db) { @Override public boolean isClickHouse() { - return isClickHouse(getSQLDatabase()); + return isClickHouse(gainSQLDatabase()); } public static boolean isClickHouse(String db) { return DATABASE_CLICKHOUSE.equals(db); @@ -1228,7 +1220,7 @@ public static boolean isClickHouse(String db) { @Override public boolean isHive() { - return isHive(getSQLDatabase()); + return isHive(gainSQLDatabase()); } public static boolean isHive(String db) { return DATABASE_HIVE.equals(db); @@ -1236,7 +1228,7 @@ public static boolean isHive(String db) { @Override public boolean isPresto() { - return isPresto(getSQLDatabase()); + return isPresto(gainSQLDatabase()); } public static boolean isPresto(String db) { return DATABASE_PRESTO.equals(db); @@ -1244,7 +1236,7 @@ public static boolean isPresto(String db) { @Override public boolean isTrino() { - return isTrino(getSQLDatabase()); + return isTrino(gainSQLDatabase()); } public static boolean isTrino(String db) { return DATABASE_TRINO.equals(db); @@ -1252,7 +1244,7 @@ public static boolean isTrino(String db) { @Override public boolean isSnowflake() { - return isSnowflake(getSQLDatabase()); + return isSnowflake(gainSQLDatabase()); } public static boolean isSnowflake(String db) { return DATABASE_SNOWFLAKE.equals(db); @@ -1260,7 +1252,7 @@ public static boolean isSnowflake(String db) { @Override public boolean isDatabricks() { - return isDatabricks(getSQLDatabase()); + return isDatabricks(gainSQLDatabase()); } public static boolean isDatabricks(String db) { return DATABASE_DATABRICKS.equals(db); @@ -1268,7 +1260,7 @@ public static boolean isDatabricks(String db) { @Override public boolean isCassandra() { - return isCassandra(getSQLDatabase()); + return isCassandra(gainSQLDatabase()); } public static boolean isCassandra(String db) { return DATABASE_CASSANDRA.equals(db); @@ -1276,7 +1268,7 @@ public static boolean isCassandra(String db) { @Override public boolean isMilvus() { - return isMilvus(getSQLDatabase()); + return isMilvus(gainSQLDatabase()); } public static boolean isMilvus(String db) { return DATABASE_MILVUS.equals(db); @@ -1284,7 +1276,7 @@ public static boolean isMilvus(String db) { @Override public boolean isInfluxDB() { - return isInfluxDB(getSQLDatabase()); + return isInfluxDB(gainSQLDatabase()); } public static boolean isInfluxDB(String db) { return DATABASE_INFLUXDB.equals(db); @@ -1292,7 +1284,7 @@ public static boolean isInfluxDB(String db) { @Override public boolean isTDengine() { - return isTDengine(getSQLDatabase()); + return isTDengine(gainSQLDatabase()); } public static boolean isTDengine(String db) { return DATABASE_TDENGINE.equals(db); @@ -1300,7 +1292,7 @@ public static boolean isTDengine(String db) { @Override public boolean isTimescaleDB() { - return isTimescaleDB(getSQLDatabase()); + return isTimescaleDB(gainSQLDatabase()); } public static boolean isTimescaleDB(String db) { return DATABASE_TIMESCALEDB.equals(db); @@ -1308,7 +1300,7 @@ public static boolean isTimescaleDB(String db) { @Override public boolean isQuestDB() { - return isQuestDB(getSQLDatabase()); + return isQuestDB(gainSQLDatabase()); } public static boolean isQuestDB(String db) { return DATABASE_QUESTDB.equals(db); @@ -1325,7 +1317,7 @@ public static boolean isIoTDB(String db) { @Override public boolean isRedis() { - return isRedis(getSQLDatabase()); + return isRedis(gainSQLDatabase()); } public static boolean isRedis(String db) { return DATABASE_REDIS.equals(db); @@ -1333,7 +1325,7 @@ public static boolean isRedis(String db) { @Override public boolean isMongoDB() { - return isMongoDB(getSQLDatabase()); + return isMongoDB(gainSQLDatabase()); } public static boolean isMongoDB(String db) { return DATABASE_MONGODB.equals(db); @@ -1341,7 +1333,7 @@ public static boolean isMongoDB(String db) { @Override public boolean isKafka() { - return isKafka(getSQLDatabase()); + return isKafka(gainSQLDatabase()); } public static boolean isKafka(String db) { return DATABASE_KAFKA.equals(db); @@ -1349,7 +1341,7 @@ public static boolean isKafka(String db) { @Override public boolean isMQ() { - return isMQ(getSQLDatabase()); + return isMQ(gainSQLDatabase()); } public static boolean isMQ(String db) { return DATABASE_MQ.equals(db) || isKafka(db); @@ -1357,7 +1349,7 @@ public static boolean isMQ(String db) { @Override public boolean isSQLite() { - return isSQLite(getSQLDatabase()); + return isSQLite(gainSQLDatabase()); } public static boolean isSQLite(String db) { return DATABASE_SQLITE.equals(db); @@ -1365,7 +1357,7 @@ public static boolean isSQLite(String db) { @Override public boolean isDuckDB() { - return isDuckDB(getSQLDatabase()); + return isDuckDB(gainSQLDatabase()); } public static boolean isDuckDB(String db) { return DATABASE_DUCKDB.equals(db); @@ -1373,7 +1365,7 @@ public static boolean isDuckDB(String db) { @Override public boolean isSurrealDB() { - return isSurrealDB(getSQLDatabase()); + return isSurrealDB(gainSQLDatabase()); } public static boolean isSurrealDB(String db) { return DATABASE_SURREALDB.equals(db); @@ -1381,7 +1373,7 @@ public static boolean isSurrealDB(String db) { @Override public boolean isOpenGauss() { - return isOpenGauss(getSQLDatabase()); + return isOpenGauss(gainSQLDatabase()); } public static boolean isOpenGauss(String db) { return DATABASE_OPENGAUSS.equals(db); @@ -1412,14 +1404,14 @@ public String getNamespace() { } @Override - public AbstractSQLConfig setNamespace(String namespace) { + public AbstractSQLConfig setNamespace(String namespace) { this.namespace = namespace; return this; } @Override - public String getSQLCatalog() { + public String gainSQLCatalog() { String catalog = getCatalog(); // 前端传参 @catalog 优先 return catalog == null ? DEFAULT_CATALOG : catalog; // 最后代码默认兜底配置 } @@ -1430,14 +1422,14 @@ public String getCatalog() { } @Override - public AbstractSQLConfig setCatalog(String catalog) { + public AbstractSQLConfig setCatalog(String catalog) { this.catalog = catalog; return this; } @NotNull @Override - public String getSQLSchema() { + public String gainSQLSchema() { String table = getTable(); // FIXME 全部默认填充判断是 系统表 则不填充 // 强制,避免因为全局默认的 @schema 自动填充进来,导致这几个类的 schema 为 sys 等其它值 if (Table.TAG.equals(table) || Column.TAG.equals(table)) { @@ -1467,7 +1459,7 @@ public String getSchema() { } @Override - public AbstractSQLConfig setSchema(String schema) { + public AbstractSQLConfig setSchema(String schema) { if (schema != null) { AbstractFunctionParser.verifySchema(schema, getTable()); } @@ -1480,14 +1472,14 @@ public String getDatasource() { return datasource; } @Override - public AbstractSQLConfig setDatasource(String datasource) { + public AbstractSQLConfig setDatasource(String datasource) { this.datasource = datasource; return this; } /**请求传进来的Table名 * @return - * @see {@link #getSQLTable()} + * @see {@link #gainSQLTable()} */ @Override public String getTable() { @@ -1497,9 +1489,8 @@ public String getTable() { * 通过 {@link #TABLE_KEY_MAP} 映射 * @return */ - @JSONField(serialize = false) @Override - public String getSQLTable() { + public String gainSQLTable() { // 如果要强制小写,则可在子类重写这个方法再 toLowerCase // return DATABASE_POSTGRESQL.equals(getDatabase()) ? t.toLowerCase() : t; String ot = getTable(); @@ -1508,28 +1499,27 @@ public String getSQLTable() { } - @JSONField(serialize = false) @Override - public String getTablePath() { + public String gainTablePath() { String q = getQuote(); String ns = isSurrealDB() ? getSQLNamespace() : null; - String cl = isPSQL() ? getSQLCatalog() : null; - String sch = getSQLSchema(); - String sqlTable = getSQLTable(); + String cl = isPSQL() ? gainSQLCatalog() : null; + String sch = gainSQLSchema(); + String sqlTable = gainSQLTable(); return (StringUtil.isEmpty(ns, true) ? "" : q + ns + q + ".") + (StringUtil.isEmpty(cl, true) ? "" : q + cl + q + ".") + (StringUtil.isEmpty(sch, true) ? "" : q + sch + q + ".") - + q + sqlTable + q + (isKeyPrefix() ? getAs() + q + getSQLAlias() + q : ""); + + q + sqlTable + q + (isKeyPrefix() ? gainAs() + q + gainSQLAlias() + q : ""); } @Override - public AbstractSQLConfig setTable(String table) { //Table已经在Parser中校验,所以这里不用防SQL注入 + public AbstractSQLConfig setTable(String table) { //Table已经在Parser中校验,所以这里不用防SQL注入 this.table = table; return this; } - public String getAs() { + public String gainAs() { return isOracle() || isManticore() ? " " : " AS "; } @@ -1538,12 +1528,12 @@ public String getAlias() { return alias; } @Override - public AbstractSQLConfig setAlias(String alias) { + public AbstractSQLConfig setAlias(String alias) { this.alias = alias; return this; } - public String getSQLAliasWithQuote() { - String a = getSQLAlias(); + public String gainSQLAliasWithQuote() { + String a = gainSQLAlias(); String q = getQuote(); // getTable 不能小写,因为Verifier用大小写敏感的名称判断权限 // 如果要强制小写,则可在子类重写这个方法再 toLowerCase @@ -1555,36 +1545,36 @@ public String getSQLAliasWithQuote() { public String getGroup() { return group; } - public AbstractSQLConfig setGroup(String... keys) { + public AbstractSQLConfig setGroup(String... keys) { return setGroup(StringUtil.get(keys)); } @Override - public AbstractSQLConfig setGroup(String group) { + public AbstractSQLConfig setGroup(String group) { this.group = group; return this; } - @JSONField(serialize = false) - public String getGroupString(boolean hasPrefix) { + + public String gainGroupString(boolean hasPrefix) { //加上子表的 group String joinGroup = ""; if (joinList != null) { boolean first = true; - for (Join j : joinList) { - if (j.isAppJoin()) { + for (Join join : joinList) { + if (join.isAppJoin()) { continue; } - SQLConfig ocfg = j.getOuterConfig(); - SQLConfig cfg = (ocfg != null && ocfg.getGroup() != null) || j.isLeftOrRightJoin() ? ocfg : j.getJoinConfig(); + SQLConfig ocfg = join.getOuterConfig(); + SQLConfig cfg = (ocfg != null && ocfg.getGroup() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { cfg.setMain(false).setKeyPrefix(true); //if (StringUtil.isEmpty(cfg.getAlias(), true)) { // cfg.setAlias(cfg.getTable()); //} - String c = ((AbstractSQLConfig) cfg).getGroupString(false); + String c = ((AbstractSQLConfig) cfg).gainGroupString(false); - if (StringUtil.isEmpty(c, true) == false) { + if (StringUtil.isNotEmpty(c, true)) { joinGroup += (first ? "" : ", ") + c; first = false; } @@ -1601,13 +1591,13 @@ public String getGroupString(boolean hasPrefix) { for (int i = 0; i < keys.length; i++) { if (isPrepared()) { - // 不能通过 ? 来代替,因为SQLExecutor statement.setString后 GROUP BY 'userId' 有单引号,只能返回一条数据,必须去掉单引号才行! + // 不能通过 ? 来代替,因为SQLExecutor statement.setString后 GROUP BY 'userId' 有单引号,只能返回一条数据,必须去掉单引号才行! if (StringUtil.isName(keys[i]) == false) { throw new IllegalArgumentException("@group:value 中 value里面用 , 分割的每一项都必须是1个单词!并且不要有空格!"); } } - keys[i] = getKey(keys[i]); + keys[i] = gainKey(keys[i]); } return (hasPrefix ? " GROUP BY " : "") + StringUtil.concat(StringUtil.get(keys), joinGroup, ", "); @@ -1618,7 +1608,7 @@ public String getHavingCombine() { return havingCombine; } @Override - public AbstractSQLConfig setHavingCombine(String havingCombine) { + public AbstractSQLConfig setHavingCombine(String havingCombine) { this.havingCombine = havingCombine; return this; } @@ -1628,11 +1618,11 @@ public Map getHaving() { return having; } @Override - public AbstractSQLConfig setHaving(Map having) { + public AbstractSQLConfig setHaving(Map having) { this.having = having; return this; } - public AbstractSQLConfig setHaving(String... conditions) { + public AbstractSQLConfig setHaving(String... conditions) { return setHaving(StringUtil.get(conditions)); } @@ -1640,28 +1630,27 @@ public AbstractSQLConfig setHaving(String... conditions) { * @return HAVING conditoin0 AND condition1 OR condition2 ... * @throws Exception */ - @JSONField(serialize = false) - public String getHavingString(boolean hasPrefix) throws Exception { + public String gainHavingString(boolean hasPrefix) throws Exception { //加上子表的 having String joinHaving = ""; if (joinList != null) { boolean first = true; - for (Join j : joinList) { - if (j.isAppJoin()) { + for (Join join : joinList) { + if (join.isAppJoin()) { continue; } - SQLConfig ocfg = j.getOuterConfig(); - SQLConfig cfg = (ocfg != null && ocfg.getHaving() != null) || j.isLeftOrRightJoin() ? ocfg : j.getJoinConfig(); + SQLConfig ocfg = join.getOuterConfig(); + SQLConfig cfg = (ocfg != null && ocfg.getHaving() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { cfg.setMain(false).setKeyPrefix(true); //if (StringUtil.isEmpty(cfg.getAlias(), true)) { // cfg.setAlias(cfg.getTable()); //} - String c = ((AbstractSQLConfig) cfg).getHavingString(false); + String c = ((AbstractSQLConfig) cfg).gainHavingString(false); - if (StringUtil.isEmpty(c, true) == false) { + if (StringUtil.isNotEmpty(c, true)) { joinHaving += (first ? "" : ", ") + c; first = false; } @@ -1692,11 +1681,11 @@ public String getHavingString(boolean hasPrefix) throws Exception { return (hasPrefix ? " HAVING " : "") + StringUtil.concat(havingString, joinHaving, AND); } - protected String getHavingItem(String quote, String table, String alias + protected String gainHavingItem(String quote, String table, String alias , String key, String expression, boolean containRaw) throws Exception { //fun(arg0,arg1,...) if (containRaw) { - String rawSQL = getRawSQL(KEY_HAVING, expression); + String rawSQL = gainRawSQL(KEY_HAVING, expression); if (rawSQL != null) { return rawSQL; } @@ -1746,36 +1735,35 @@ else if (SQL_FUNCTION_MAP.containsKey(method) == false) { public String getSample() { return sample; } - public AbstractSQLConfig setSample(String... conditions) { + public AbstractSQLConfig setSample(String... conditions) { return setSample(StringUtil.get(conditions)); } @Override - public AbstractSQLConfig setSample(String sample) { + public AbstractSQLConfig setSample(String sample) { this.sample = sample; return this; } - @JSONField(serialize = false) - public String getSampleString(boolean hasPrefix) { + public String gainSampleString(boolean hasPrefix) { //加上子表的 sample String joinSample = ""; if (joinList != null) { boolean first = true; - for (Join j : joinList) { - if (j.isAppJoin()) { + for (Join join : joinList) { + if (join.isAppJoin()) { continue; } - SQLConfig ocfg = j.getOuterConfig(); - SQLConfig cfg = (ocfg != null && ocfg.getSample() != null) || j.isLeftOrRightJoin() ? ocfg : j.getJoinConfig(); + SQLConfig ocfg = join.getOuterConfig(); + SQLConfig cfg = (ocfg != null && ocfg.getSample() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { cfg.setMain(false).setKeyPrefix(true); // if (StringUtil.isEmpty(cfg.getAlias(), true)) { // cfg.setAlias(cfg.getTable()); // } - String c = ((AbstractSQLConfig) cfg).getSampleString(false); + String c = ((AbstractSQLConfig) cfg).gainSampleString(false); - if (StringUtil.isEmpty(c, true) == false) { + if (StringUtil.isNotEmpty(c, true)) { joinSample += (first ? "" : ", ") + c; first = false; } @@ -1807,7 +1795,7 @@ else if (StringUtil.isCombineOfNumOrAlpha(origin)) { } } - keys[i] = getKey(origin); + keys[i] = gainKey(origin); } return (hasPrefix ? " SAMPLE BY " : "") + StringUtil.concat(StringUtil.get(keys), joinSample, ", "); @@ -1817,36 +1805,35 @@ else if (StringUtil.isCombineOfNumOrAlpha(origin)) { public String getLatest() { return latest; } - public AbstractSQLConfig setLatest(String... conditions) { + public AbstractSQLConfig setLatest(String... conditions) { return setLatest(StringUtil.get(conditions)); } @Override - public AbstractSQLConfig setLatest(String latest) { + public AbstractSQLConfig setLatest(String latest) { this.latest = latest; return this; } - @JSONField(serialize = false) - public String getLatestString(boolean hasPrefix) { + public String gainLatestString(boolean hasPrefix) { //加上子表的 latest String joinLatest = ""; if (joinList != null) { boolean first = true; - for (Join j : joinList) { - if (j.isAppJoin()) { + for (Join join : joinList) { + if (join.isAppJoin()) { continue; } - SQLConfig ocfg = j.getOuterConfig(); - SQLConfig cfg = (ocfg != null && ocfg.getLatest() != null) || j.isLeftOrRightJoin() ? ocfg : j.getJoinConfig(); + SQLConfig ocfg = join.getOuterConfig(); + SQLConfig cfg = (ocfg != null && ocfg.getLatest() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { cfg.setMain(false).setKeyPrefix(true); // if (StringUtil.isEmpty(cfg.getAlias(), true)) { // cfg.setAlias(cfg.getTable()); // } - String c = ((AbstractSQLConfig) cfg).getLatestString(false); + String c = ((AbstractSQLConfig) cfg).gainLatestString(false); - if (StringUtil.isEmpty(c, true) == false) { + if (StringUtil.isNotEmpty(c, true)) { joinLatest += (first ? "" : ", ") + c; first = false; } @@ -1873,7 +1860,7 @@ public String getLatestString(boolean hasPrefix) { } } - keys[i] = getKey(origin); + keys[i] = gainKey(origin); } return (hasPrefix ? " LATEST ON " : "") + StringUtil.concat(StringUtil.get(keys), joinLatest, ", "); @@ -1883,36 +1870,35 @@ public String getLatestString(boolean hasPrefix) { public String getPartition() { return partition; } - public AbstractSQLConfig setPartition(String... conditions) { + public AbstractSQLConfig setPartition(String... conditions) { return setPartition(StringUtil.get(conditions)); } @Override - public AbstractSQLConfig setPartition(String partition) { + public AbstractSQLConfig setPartition(String partition) { this.partition = partition; return this; } - @JSONField(serialize = false) - public String getPartitionString(boolean hasPrefix) { + public String gainPartitionString(boolean hasPrefix) { //加上子表的 partition String joinPartition = ""; if (joinList != null) { boolean first = true; - for (Join j : joinList) { - if (j.isAppJoin()) { + for (Join join : joinList) { + if (join.isAppJoin()) { continue; } - SQLConfig ocfg = j.getOuterConfig(); - SQLConfig cfg = (ocfg != null && ocfg.getPartition() != null) || j.isLeftOrRightJoin() ? ocfg : j.getJoinConfig(); + SQLConfig ocfg = join.getOuterConfig(); + SQLConfig cfg = (ocfg != null && ocfg.getPartition() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { cfg.setMain(false).setKeyPrefix(true); // if (StringUtil.isEmpty(cfg.getAlias(), true)) { // cfg.setAlias(cfg.getTable()); // } - String c = ((AbstractSQLConfig) cfg).getPartitionString(false); + String c = ((AbstractSQLConfig) cfg).gainPartitionString(false); - if (StringUtil.isEmpty(c, true) == false) { + if (StringUtil.isNotEmpty(c, true)) { joinPartition += (first ? "" : ", ") + c; first = false; } @@ -1939,7 +1925,7 @@ public String getPartitionString(boolean hasPrefix) { } } - keys[i] = getKey(origin); + keys[i] = gainKey(origin); } return (hasPrefix ? " PARTITION BY " : "") + StringUtil.concat(StringUtil.get(keys), joinPartition, ", "); @@ -1949,36 +1935,35 @@ public String getPartitionString(boolean hasPrefix) { public String getFill() { return fill; } - public AbstractSQLConfig setFill(String... conditions) { + public AbstractSQLConfig setFill(String... conditions) { return setFill(StringUtil.get(conditions)); } @Override - public AbstractSQLConfig setFill(String fill) { + public AbstractSQLConfig setFill(String fill) { this.fill = fill; return this; } - @JSONField(serialize = false) - public String getFillString(boolean hasPrefix) { + public String gainFillString(boolean hasPrefix) { //加上子表的 fill String joinFill = ""; if (joinList != null) { boolean first = true; - for (Join j : joinList) { - if (j.isAppJoin()) { + for (Join join : joinList) { + if (join.isAppJoin()) { continue; } - SQLConfig ocfg = j.getOuterConfig(); - SQLConfig cfg = (ocfg != null && ocfg.getFill() != null) || j.isLeftOrRightJoin() ? ocfg : j.getJoinConfig(); + SQLConfig ocfg = join.getOuterConfig(); + SQLConfig cfg = (ocfg != null && ocfg.getFill() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { cfg.setMain(false).setKeyPrefix(true); // if (StringUtil.isEmpty(cfg.getAlias(), true)) { // cfg.setAlias(cfg.getTable()); // } - String c = ((AbstractSQLConfig) cfg).getFillString(false); + String c = ((AbstractSQLConfig) cfg).gainFillString(false); - if (StringUtil.isEmpty(c, true) == false) { + if (StringUtil.isNotEmpty(c, true)) { joinFill += (first ? "" : ", ") + c; first = false; } @@ -2013,7 +1998,7 @@ else if (StringUtil.isCombineOfNumOrAlpha(origin)) { } } - keys[i] = getKey(origin); + keys[i] = gainKey(origin); } return (hasPrefix ? " FILL(" : "") + StringUtil.concat(StringUtil.get(keys), joinFill, ", ") + ")"; @@ -2023,36 +2008,35 @@ else if (StringUtil.isCombineOfNumOrAlpha(origin)) { public String getOrder() { return order; } - public AbstractSQLConfig setOrder(String... conditions) { + public AbstractSQLConfig setOrder(String... conditions) { return setOrder(StringUtil.get(conditions)); } @Override - public AbstractSQLConfig setOrder(String order) { + public AbstractSQLConfig setOrder(String order) { this.order = order; return this; } - @JSONField(serialize = false) - public String getOrderString(boolean hasPrefix) { + public String gainOrderString(boolean hasPrefix) { //加上子表的 order String joinOrder = ""; if (joinList != null) { boolean first = true; - for (Join j : joinList) { - if (j.isAppJoin()) { + for (Join join : joinList) { + if (join.isAppJoin()) { continue; } - SQLConfig ocfg = j.getOuterConfig(); - SQLConfig cfg = (ocfg != null && ocfg.getOrder() != null) || j.isLeftOrRightJoin() ? ocfg : j.getJoinConfig(); + SQLConfig ocfg = join.getOuterConfig(); + SQLConfig cfg = (ocfg != null && ocfg.getOrder() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig(); if (cfg != null) { cfg.setMain(false).setKeyPrefix(true); //if (StringUtil.isEmpty(cfg.getAlias(), true)) { // cfg.setAlias(cfg.getTable()); //} - String c = ((AbstractSQLConfig) cfg).getOrderString(false); + String c = ((AbstractSQLConfig) cfg).gainOrderString(false); - if (StringUtil.isEmpty(c, true) == false) { + if (StringUtil.isNotEmpty(c, true)) { joinOrder += (first ? "" : ", ") + c; first = false; } @@ -2131,7 +2115,7 @@ public String getOrderString(boolean hasPrefix) { } } - keys[i] = getKey(origin) + sort; + keys[i] = gainKey(origin) + sort; } return (hasPrefix ? " ORDER BY " : "") + StringUtil.concat(StringUtil.get(keys), joinOrder, ", "); @@ -2142,7 +2126,7 @@ public Map getKeyMap() { return keyMap; } @Override - public AbstractSQLConfig setKeyMap(Map keyMap) { + public AbstractSQLConfig setKeyMap(Map keyMap) { this.keyMap = keyMap; return this; } @@ -2152,7 +2136,7 @@ public List getRaw() { return raw; } @Override - public AbstractSQLConfig setRaw(List raw) { + public AbstractSQLConfig setRaw(List raw) { this.raw = raw; return this; } @@ -2164,8 +2148,8 @@ public AbstractSQLConfig setRaw(List raw) { * @throws Exception */ @Override - public String getRawSQL(String key, Object value) throws Exception { - return getRawSQL(key, value, ! ALLOW_MISSING_KEY_4_COMBINE); + public String gainRawSQL(String key, Object value) throws Exception { + return gainRawSQL(key, value, ! ALLOW_MISSING_KEY_4_COMBINE); } /**获取原始 SQL 片段 * @param key @@ -2175,7 +2159,7 @@ public String getRawSQL(String key, Object value) throws Exception { * @throws Exception */ @Override - public String getRawSQL(String key, Object value, boolean throwWhenMissing) throws Exception { + public String gainRawSQL(String key, Object value, boolean throwWhenMissing) throws Exception { if (value == null) { return null; } @@ -2195,7 +2179,7 @@ public String getRawSQL(String key, Object value, boolean throwWhenMissing) thro + "对应的 " + key + ":value 中 value 值 " + value + " 未在后端 RAW_MAP 中配置 !"); } - putWarnIfNeed(JSONRequest.KEY_RAW, "@raw:value 的 value 中 " + putWarnIfNeed(apijson.JSONObject.KEY_RAW, "@raw:value 的 value 中 " + key + " 不合法!对应的 " + key + ":value 中 value 值 " + value + " 未在后端 RAW_MAP 中配置 !"); } else if (rawSQL.isEmpty()) { @@ -2212,18 +2196,18 @@ public List getJson() { return json; } @Override - public AbstractSQLConfig setJson(List json) { + public AbstractSQLConfig setJson(List json) { this.json = json; return this; } @Override - public Subquery getFrom() { + public Subquery getFrom() { return from; } @Override - public AbstractSQLConfig setFrom(Subquery from) { + public AbstractSQLConfig setFrom(Subquery from) { this.from = from; return this; } @@ -2233,18 +2217,16 @@ public List getColumn() { return column; } @Override - public AbstractSQLConfig setColumn(List column) { + public AbstractSQLConfig setColumn(List column) { this.column = column; return this; } - @JSONField(serialize = false) - public String getColumnString() throws Exception { - return getColumnString(false); + public String gainColumnString() throws Exception { + return gainColumnString(false); } - @JSONField(serialize = false) - public String getColumnString(boolean inSQLJoin) throws Exception { + public String gainColumnString(boolean inSQLJoin) throws Exception { List column = getColumn(); - String as = getAs(); + String as = gainAs(); String q = getQuote(); switch (getMethod()) { @@ -2257,7 +2239,7 @@ public String getColumnString(boolean inSQLJoin) throws Exception { for (String c : column) { if (containRaw) { // 由于 HashMap 对 key 做了 hash 处理,所以 get 比 containsValue 更快 - if ("".equals(RAW_MAP.get(c)) || RAW_MAP.containsValue(c)) { // newSQLConfig 提前处理好的 + if ("".equals(RAW_MAP.get(c)) || RAW_MAP.containsValue(c)) { // newSQLConfig 提前处理好的 //排除@raw中的值,以避免使用date_format(date,'%Y-%m-%d %H:%i:%s') 时,冒号的解析出错 //column.remove(c); continue; @@ -2323,7 +2305,7 @@ public String getColumnString(boolean inSQLJoin) throws Exception { } } - return "count(" + (onlyOne ? getKey(c0) : "*") + ")" + as + q + JSONResponse.KEY_COUNT + q; + return "count(" + (onlyOne ? gainKey(c0) : "*") + ")" + as + q + JSONResponse.KEY_COUNT + q; // return SQL.count(onlyOne && StringUtil.isName(column.get(0)) ? getKey(column.get(0)) : "*"); case POST: if (column == null || column.isEmpty()) { @@ -2337,7 +2319,7 @@ public String getColumnString(boolean inSQLJoin) throws Exception { // 不能通过 ? 来代替,SELECT 'id','name' 返回的就是 id:"id", name:"name",而不是数据库里的值! throw new IllegalArgumentException("POST请求: 每一个 key:value 中的key都必须是1个单词!"); } - s += ((pfirst ? "" : ",") + getKey(c)); + s += ((pfirst ? "" : ",") + gainKey(c)); pfirst = false; } @@ -2348,12 +2330,12 @@ public String getColumnString(boolean inSQLJoin) throws Exception { String joinColumn = ""; if (joinList != null) { boolean first = true; - for (Join join : joinList) { + for (Join join : joinList) { if (join.isAppJoin()) { continue; } - SQLConfig ocfg = join.getOuterConfig(); + SQLConfig ocfg = join.getOuterConfig(); boolean isEmpty = ocfg == null || ocfg.getColumn() == null; boolean isLeftOrRightJoin = join.isLeftOrRightJoin(); @@ -2361,18 +2343,18 @@ public String getColumnString(boolean inSQLJoin) throws Exception { // 改为 SELECT ViceTable.* 解决 SELECT sum(ViceTable.id) // LEFT/RIGHT JOIN (SELECT sum(id) FROM ViceTable...) AS ViceTable // 不仅导致 SQL 函数重复计算,还有时导致 SQL 报错或对应字段未返回 - joinColumn += (first ? "" : ", ") + q + SQLConfig.getSQLAlias(join.getTable(), join.getAlias()) + q + ".*"; + joinColumn += (first ? "" : ", ") + q + SQLConfig.gainSQLAlias(join.getTable(), join.getAlias()) + q + ".*"; first = false; } else { - SQLConfig cfg = isLeftOrRightJoin == false && isEmpty ? join.getJoinConfig() : ocfg; + SQLConfig cfg = isLeftOrRightJoin == false && isEmpty ? join.getJoinConfig() : ocfg; if (cfg != null) { cfg.setMain(false).setKeyPrefix(true); //if (StringUtil.isEmpty(cfg.getAlias(), true)) { // cfg.setAlias(cfg.getTable()); //} - String c = ((AbstractSQLConfig) cfg).getColumnString(true); - if (StringUtil.isEmpty(c, true) == false) { + String c = ((AbstractSQLConfig) cfg).gainColumnString(true); + if (StringUtil.isNotEmpty(c, true)) { joinColumn += (first ? "" : ", ") + c; first = false; } @@ -2383,14 +2365,14 @@ public String getColumnString(boolean inSQLJoin) throws Exception { } } - String tableAlias = q + getSQLAlias() + q; + String tableAlias = q + gainSQLAlias() + q; // String c = StringUtil.getString(column); //id,name;json_length(contactIdList):contactCount;... String[] keys = column == null ? null : column.toArray(new String[]{}); //StringUtil.split(c, ";"); if (keys == null || keys.length <= 0) { boolean noColumn = column != null && inSQLJoin; - String mc = isKeyPrefix() == false ? (noColumn ? "" : "*") : (noColumn ? "" : tableAlias + ".*"); + String mc = isKeyPrefix() ? (noColumn ? "" : tableAlias + ".*") : (noColumn ? "" : "*"); return StringUtil.concat(mc, joinColumn, ", ", true); } @@ -2403,7 +2385,7 @@ public String getColumnString(boolean inSQLJoin) throws Exception { String expression = keys[i]; //fun(arg0,arg1,...) if (containRaw) { // 由于 HashMap 对 key 做了 hash 处理,所以 get 比 containsValue 更快 - if ("".equals(RAW_MAP.get(expression)) || RAW_MAP.containsValue(expression)) { // newSQLConfig 提前处理好的 + if ("".equals(RAW_MAP.get(expression)) || RAW_MAP.containsValue(expression)) { // newSQLConfig 提前处理好的 continue; } @@ -2412,8 +2394,8 @@ public String getColumnString(boolean inSQLJoin) throws Exception { String alias = expression.substring(index+1); boolean hasAlias = StringUtil.isName(alias); String pre = index > 0 && hasAlias ? expression.substring(0, index) : expression; - if (RAW_MAP.containsValue(pre) || "".equals(RAW_MAP.get(pre))) { // newSQLConfig 提前处理好的 - keys[i] = pre + (hasAlias ? getAs() + q + alias + q : ""); + if (RAW_MAP.containsValue(pre) || "".equals(RAW_MAP.get(pre))) { // newSQLConfig 提前处理好的 + keys[i] = pre + (hasAlias ? gainAs() + q + alias + q : ""); continue; } } @@ -2527,7 +2509,7 @@ public String parseSQLExpression(String key, String expression, boolean containR // 解析函数内的参数 String ckeys[] = parseArgsSplitWithComma(s, false, containRaw, allowAlias); - String suffix = expression.substring(end + 1, expression.length()); //:contactCount + String suffix = expression.substring(end + 1); //:contactCount String alias = null; if (allowAlias) { int index = suffix.lastIndexOf(":"); @@ -2540,15 +2522,15 @@ public String parseSQLExpression(String key, String expression, boolean containR } } - if (suffix.isEmpty() == false && (((String) suffix).contains("--") || ((String) suffix).contains("/*") - || PATTERN_RANGE.matcher((String) suffix).matches() == false)) { + if (suffix.isEmpty() == false && (suffix.contains("--") || suffix.contains("/*") + || PATTERN_RANGE.matcher(suffix).matches() == false)) { throw new UnsupportedOperationException("字符串 " + suffix + " 不合法!预编译模式下 " + key + ":\"column?value;function(arg0,arg1,...)?value...\"" + " 中 ?value 必须符合正则表达式 " + PATTERN_RANGE + " 且不包含连续减号 -- 或注释符 /* !不允许多余的空格!"); } String origin = fun + "(" + (distinct ? PREFIX_DISTINCT : "") + StringUtil.get(ckeys) + ")" + suffix; - expression = origin + (StringUtil.isEmpty(alias, true) ? "" : getAs() + quote + alias + quote); + expression = origin + (StringUtil.isEmpty(alias, true) ? "" : gainAs() + quote + alias + quote); } else { //是窗口函数 fun(arg0,agr1) OVER (agr0 agr1 ...) @@ -2586,7 +2568,7 @@ else if (SQL_FUNCTION_MAP.containsKey(fun) == false) { int index2 = s2.indexOf("("); // 后半部分 “(”的起始位置 String argString2 = s2.substring(index2 + 1, end); // 后半部分的参数 // 别名 - int aliasIndex = allowAlias == false ? -1 : s2.lastIndexOf(":"); + int aliasIndex = allowAlias ? s2.lastIndexOf(":") : -1; String alias = aliasIndex < 0 ? "" : s2.substring(aliasIndex + 1); if (alias.isEmpty() == false && StringUtil.isName(alias) == false) { throw new IllegalArgumentException("字符串 " + alias + " 不合法!预编译模式下 " @@ -2595,18 +2577,18 @@ else if (SQL_FUNCTION_MAP.containsKey(fun) == false) { } String suffix = s2.substring(end + 1, aliasIndex < 0 ? s2.length() : aliasIndex); - if (suffix.isEmpty() == false && (((String) suffix).contains("--") || ((String) suffix).contains("/*") - || PATTERN_RANGE.matcher((String) suffix).matches() == false)) { + if (suffix.isEmpty() == false && (suffix.contains("--") || suffix.contains("/*") + || PATTERN_RANGE.matcher(suffix).matches() == false)) { throw new UnsupportedOperationException("字符串 " + suffix + " 不合法!预编译模式下 " + key + ":\"column?value;function(arg0,arg1,...)?value...\"" + " 中 ?value 必须符合正则表达式 " + PATTERN_RANGE + " 且不包含连续减号 -- 或注释符 /* !不允许多余的空格!"); } // 获取后半部分的参数解析 (agr0 agr1 ...) - String argsString2[] = parseArgsSplitWithComma(argString2, false, containRaw, allowAlias); + String[] argsString2 = parseArgsSplitWithComma(argString2, false, containRaw, allowAlias); expression = fun + "(" + StringUtil.get(agrsString1) + (containOver ? ") OVER (" : ") AGAINST (") + StringUtil.get(argsString2) + ")" + suffix // 传参不传空格,拼接带空格 - + (StringUtil.isEmpty(alias, true) ? "" : getAs() + quote + alias + quote); + + (StringUtil.isEmpty(alias, true) ? "" : gainAs() + quote + alias + quote); } } @@ -2625,8 +2607,8 @@ private String[] parseArgsSplitWithComma(String param, boolean isColumn, boolean // 以"," 分割参数 String quote = getQuote(); boolean isKeyPrefix = isKeyPrefix(); - String tableAlias = quote + getSQLAlias() + quote; - String ckeys[] = StringUtil.split(param); // 以","分割参数 + String tableAlias = quote + gainSQLAlias() + quote; + String[] ckeys = StringUtil.split(param); // 以","分割参数 if (ckeys != null && ckeys.length > 0) { for (int i = 0; i < ckeys.length; i++) { @@ -2645,7 +2627,7 @@ private String[] parseArgsSplitWithComma(String param, boolean isColumn, boolean + " 中所有字符串 column 都必须必须为1个单词 !"); } - origin = getKey(origin).toString(); + origin = gainKey(origin); } else if (ck.startsWith("'") && ck.endsWith("'")) { origin = ck.substring(1, ck.length() - 1); @@ -2656,7 +2638,7 @@ else if (ck.startsWith("'") && ck.endsWith("'")) { } // 1.字符串不是字段也没有别名,所以不解析别名 2. 是字符串,进行预编译,使用getValue() ,对字符串进行截取 - origin = getValue(origin).toString(); + origin = gainValue(origin).toString(); } else { // 参数不包含",",即不是字符串 @@ -2703,7 +2685,7 @@ else if ("!=null".equals(ck)) { origin = parseArgsSplitWithSpace(mkes); } else { String mk = RAW_MAP.get(origin); - if (mk != null) { // newSQLConfig 提前处理好的 + if (mk != null) { // newSQLConfig 提前处理好的 if (mk.length() > 0) { origin = mk; } @@ -2731,12 +2713,12 @@ else if ("!=null".equals(ck)) { if (StringUtil.isNotEmpty(s, true)) { origin = (len == 1 && isKeyPrefix ? tableAlias + "." : "") + s; } else { - origin = getValue(origin).toString(); + origin = gainValue(origin).toString(); } } - if (isColumn && StringUtil.isEmpty(alias, true) == false) { - origin += getAs() + quote + alias + quote; + if (isColumn && StringUtil.isNotEmpty(alias, true)) { + origin += gainAs() + quote + alias + quote; } } } @@ -2756,10 +2738,10 @@ else if ("!=null".equals(ck)) { * @param mkes * @return */ - private String parseArgsSplitWithSpace(String mkes[]) { + private String parseArgsSplitWithSpace(String[] mkes) { String quote = getQuote(); boolean isKeyPrefix = isKeyPrefix(); - String tableAlias = quote + getSQLAlias() + quote; + String tableAlias = quote + gainSQLAlias() + quote; // 包含空格的参数 肯定不包含别名 不用处理别名 if (mkes != null && mkes.length > 0) { @@ -2768,7 +2750,7 @@ private String parseArgsSplitWithSpace(String mkes[]) { String origin = mkes[j]; String mk = RAW_MAP.get(origin); - if (mk != null) { // newSQLConfig 提前处理好的 + if (mk != null) { // newSQLConfig 提前处理好的 if (mk.length() > 0) { mkes[j] = mk; } @@ -2786,7 +2768,7 @@ private String parseArgsSplitWithSpace(String mkes[]) { + " 中所有字符串 column 都必须必须为1个单词 !"); } - mkes[j] = getKey(origin); + mkes[j] = gainKey(origin); continue; } else if (ck.startsWith("'") && ck.endsWith("'")) { @@ -2798,7 +2780,7 @@ else if (ck.startsWith("'") && ck.endsWith("'")) { } // 1.字符串不是字段也没有别名,所以不解析别名 2. 是字符串,进行预编译,使用getValue() ,对字符串进行截取 - mkes[j] = getValue(origin).toString(); + mkes[j] = gainValue(origin).toString(); continue; } else if (ck.contains("`") || ck.contains("'") || origin.startsWith("_") || origin.contains("--")) { @@ -2833,7 +2815,7 @@ else if (ck.contains("`") || ck.contains("'") || origin.startsWith("_") || origi if (StringUtil.isNotEmpty(s, true)) { origin = (len == 1 && isKeyPrefix ? tableAlias + "." : "") + s; } else { - origin = getValue(origin).toString(); + origin = gainValue(origin).toString(); } } @@ -2849,7 +2831,6 @@ else if (ck.contains("`") || ck.contains("'") || origin.startsWith("_") || origi public List> getValues() { return values; } - @JSONField(serialize = false) public String getValuesString() { String s = ""; if (values != null && values.size() > 0) { @@ -2863,7 +2844,7 @@ public String getValuesString() { items[i] = "("; for (int j = 0; j < vs.size(); j++) { - items[i] += ((j <= 0 ? "" : ",") + getValue(vs.get(j))); + items[i] += ((j <= 0 ? "" : ",") + gainValue(vs.get(j))); } items[i] += ")"; } @@ -2872,7 +2853,7 @@ public String getValuesString() { return s; } @Override - public AbstractSQLConfig setValues(List> valuess) { + public AbstractSQLConfig setValues(List> valuess) { this.values = valuess; return this; } @@ -2882,7 +2863,7 @@ public Map getContent() { return content; } @Override - public AbstractSQLConfig setContent(Map content) { + public AbstractSQLConfig setContent(Map content) { this.content = content; return this; } @@ -2892,7 +2873,7 @@ public int getCount() { return count; } @Override - public AbstractSQLConfig setCount(int count) { + public AbstractSQLConfig setCount(int count) { this.count = count; return this; } @@ -2901,7 +2882,7 @@ public int getPage() { return page; } @Override - public AbstractSQLConfig setPage(int page) { + public AbstractSQLConfig setPage(int page) { this.page = page; return this; } @@ -2910,7 +2891,7 @@ public int getPosition() { return position; } @Override - public AbstractSQLConfig setPosition(int position) { + public AbstractSQLConfig setPosition(int position) { this.position = position; return this; } @@ -2920,7 +2901,7 @@ public int getQuery() { return query; } @Override - public AbstractSQLConfig setQuery(int query) { + public AbstractSQLConfig setQuery(int query) { this.query = query; return this; } @@ -2929,7 +2910,7 @@ public Boolean getCompat() { return compat; } @Override - public AbstractSQLConfig setCompat(Boolean compat) { + public AbstractSQLConfig setCompat(Boolean compat) { this.compat = compat; return this; } @@ -2939,7 +2920,7 @@ public int getType() { return type; } @Override - public AbstractSQLConfig setType(int type) { + public AbstractSQLConfig setType(int type) { this.type = type; return this; } @@ -2949,39 +2930,39 @@ public int getCache() { return cache; } @Override - public AbstractSQLConfig setCache(int cache) { + public AbstractSQLConfig setCache(int cache) { this.cache = cache; return this; } - public AbstractSQLConfig setCache(String cache) { + public AbstractSQLConfig setCache(String cache) { return setCache(getCache(cache)); } public static int getCache(String cache) { int cache2; if (cache == null) { - cache2 = JSONRequest.CACHE_ALL; + cache2 = apijson.JSONObject.CACHE_ALL; } else { // if (isSubquery) { - // throw new IllegalArgumentException("子查询内不支持传 " + JSONRequest.KEY_CACHE + "!"); + // throw new IllegalArgumentException("子查询内不支持传 " + apijson.JSONObject.KEY_CACHE + "!"); // } switch (cache) { case "0": - case JSONRequest.CACHE_ALL_STRING: - cache2 = JSONRequest.CACHE_ALL; + case apijson.JSONObject.CACHE_ALL_STRING: + cache2 = apijson.JSONObject.CACHE_ALL; break; case "1": - case JSONRequest.CACHE_ROM_STRING: - cache2 = JSONRequest.CACHE_ROM; + case apijson.JSONObject.CACHE_ROM_STRING: + cache2 = apijson.JSONObject.CACHE_ROM; break; case "2": - case JSONRequest.CACHE_RAM_STRING: - cache2 = JSONRequest.CACHE_RAM; + case apijson.JSONObject.CACHE_RAM_STRING: + cache2 = apijson.JSONObject.CACHE_RAM; break; default: - throw new IllegalArgumentException(JSONRequest.KEY_CACHE + throw new IllegalArgumentException(apijson.JSONObject.KEY_CACHE + ":value 中 value 的值不合法!必须在 [0,1,2] 或 [ALL, ROM, RAM] 内 !"); } } @@ -2993,17 +2974,17 @@ public boolean isExplain() { return explain; } @Override - public AbstractSQLConfig setExplain(boolean explain) { + public AbstractSQLConfig setExplain(boolean explain) { this.explain = explain; return this; } @Override - public List getJoinList() { + public List> getJoinList() { return joinList; } @Override - public AbstractSQLConfig setJoinList(List joinList) { + public AbstractSQLConfig setJoinList(List> joinList) { this.joinList = joinList; return this; } @@ -3018,7 +2999,7 @@ public boolean isTest() { return test; } @Override - public AbstractSQLConfig setTest(boolean test) { + public AbstractSQLConfig setTest(boolean test) { this.test = test; return this; } @@ -3026,7 +3007,6 @@ public AbstractSQLConfig setTest(boolean test) { /**获取初始位置offset * @return */ - @JSONField(serialize = false) public int getOffset() { return getOffset(getPage(), getCount()); } @@ -3041,8 +3021,7 @@ public static int getOffset(int page, int count) { /**获取限制数量 * @return */ - @JSONField(serialize = false) - public String getLimitString() { + public String gainLimitString() { int count = getCount(); int page = getPage(); @@ -3055,7 +3034,7 @@ public String getLimitString() { boolean isQuestDB = isQuestDB(); if (isSurrealDB || isQuestDB || isMilvus) { if (count == 0) { - Parser parser = getParser(); + Parser parser = gainParser(); count = parser == null ? AbstractParser.MAX_QUERY_COUNT : parser.getMaxQueryCount(); } @@ -3072,7 +3051,7 @@ else if (isSurrealDB()) { } boolean isOracle = isOracle(); - return getLimitString(page, count, isTSQL(), isOracle || isDameng() || isKingBase(), isPresto() || isTrino()); + return gainLimitString(page, count, isTSQL(), isOracle || isDameng() || isKingBase(), isPresto() || isTrino()); } /**获取限制数量及偏移量 * @param page @@ -3081,8 +3060,8 @@ else if (isSurrealDB()) { * @param isOracle * @return */ - public static String getLimitString(int page, int count, boolean isTSQL, boolean isOracle) { - return getLimitString(page, count, isTSQL, isOracle, false); + public static String gainLimitString(int page, int count, boolean isTSQL, boolean isOracle) { + return gainLimitString(page, count, isTSQL, isOracle, false); } /**获取限制数量及偏移量 * @param page @@ -3092,7 +3071,7 @@ public static String getLimitString(int page, int count, boolean isTSQL, boolean * @param isPresto * @return */ - public static String getLimitString(int page, int count, boolean isTSQL, boolean isOracle, boolean isPresto) { + public static String gainLimitString(int page, int count, boolean isTSQL, boolean isOracle, boolean isPresto) { int offset = getOffset(page, count); if (isOracle) { // TODO 判断版本,高版本可以用 OFFSET FETCH @@ -3115,7 +3094,7 @@ public List getNull() { return nulls; } @Override - public AbstractSQLConfig setNull(List nulls) { + public AbstractSQLConfig setNull(List nulls) { this.nulls = nulls; return this; } @@ -3125,7 +3104,7 @@ public Map getCast() { return cast; } @Override - public AbstractSQLConfig setCast(Map cast) { + public AbstractSQLConfig setCast(Map cast) { this.cast = cast; return this; } @@ -3157,7 +3136,7 @@ public String getCombine() { return combine; } @Override - public AbstractSQLConfig setCombine(String combine) { + public AbstractSQLConfig setCombine(String combine) { this.combine = combine; return this; } @@ -3176,7 +3155,7 @@ public Map> getCombineMap() { return combineMap; } @Override - public AbstractSQLConfig setCombineMap(Map> combineMap) { + public AbstractSQLConfig setCombineMap(Map> combineMap) { this.combineMap = combineMap; return this; } @@ -3186,7 +3165,7 @@ public Map getWhere() { return where; } @Override - public AbstractSQLConfig setWhere(Map where) { + public AbstractSQLConfig setWhere(Map where) { this.where = where; return this; } @@ -3196,7 +3175,6 @@ public AbstractSQLConfig setWhere(Map where) { * @param key * @return */ - @JSONField(serialize = false) @Override public Object getWhere(String key) { return getWhere(key, false); @@ -3208,7 +3186,6 @@ public Object getWhere(String key) { * @return *

use entrySet+getValue() to replace keySet+get() to enhance efficiency

*/ - @JSONField(serialize = false) @Override public Object getWhere(String key, boolean exactMatch) { if (exactMatch) { @@ -3231,10 +3208,10 @@ public Object getWhere(String key, boolean exactMatch) { return null; } @Override - public AbstractSQLConfig putWhere(String key, Object value, boolean prior) { + public AbstractSQLConfig putWhere(String key, Object value, boolean prior) { if (key != null) { if (where == null) { - where = new LinkedHashMap(); + where = new LinkedHashMap<>(); } if (value == null) { where.remove(key); @@ -3320,9 +3297,8 @@ else if (key.equals(userIdInKey)) { * @return * @throws Exception */ - @JSONField(serialize = false) @Override - public String getWhereString(boolean hasPrefix) throws Exception { + public String gainWhereString(boolean hasPrefix) throws Exception { String combineExpr = getCombine(); if (StringUtil.isEmpty(combineExpr, false)) { return getWhereString(hasPrefix, getMethod(), getWhere(), getCombineMap(), getJoinList(), ! isTest()); @@ -3335,9 +3311,8 @@ public String getWhereString(boolean hasPrefix) throws Exception { * @return * @throws Exception */ - @JSONField(serialize = false) public String getWhereString(boolean hasPrefix, RequestMethod method, Map where - , String combine, List joinList, boolean verifyName) throws Exception { + , String combine, List> joinList, boolean verifyName) throws Exception { String whereString = parseCombineExpression(method, getQuote(), getTable(), getAlias() , where, combine, verifyName, false, false); whereString = concatJoinWhereString(whereString); @@ -3455,8 +3430,8 @@ protected String parseCombineExpression(RequestMethod method, String quote, Stri + key + "' 对应的条件键值对 " + column + ":value 不存在!"); } } else { - wi = isHaving ? getHavingItem(quote, table, alias, column, (String) value, containRaw) - : getWhereItem(column, value, method, verifyName); + wi = isHaving ? gainHavingItem(quote, table, alias, column, (String) value, containRaw) + : gainWhereItem(column, value, method, verifyName); } if (1.0f*allCount/size > maxCombineRatio && maxCombineRatio > 0) { @@ -3479,7 +3454,7 @@ protected String parseCombineExpression(RequestMethod method, String quote, Stri } usedKeyCountMap.put(column, count); - result += "( " + getCondition(isNot, wi) + " )"; + result += "( " + gainCondition(isNot, wi) + " )"; isNot = false; first = false; } @@ -3618,8 +3593,8 @@ else if (c == ')') { continue; } - String wi = isHaving ? getHavingItem(quote, table, alias, key, (String) entry.getValue(), containRaw) - : getWhereItem(key, entry.getValue(), method, verifyName); + String wi = isHaving ? gainHavingItem(quote, table, alias, key, (String) entry.getValue(), containRaw) + : gainWhereItem(key, entry.getValue(), method, verifyName); if (StringUtil.isEmpty(wi, true)) {//避免SQL条件连接错误 continue; } @@ -3637,7 +3612,7 @@ else if (c == ')') { } else if (StringUtil.isNotEmpty(andCond, true)) { // andCond 必须放后面,否则 prepared 值顺序错误 if (isHaving) { - // HAVING 前 WHERE 已经有条件 ? 占位,不能反过来,想优化 AND 连接在最前,需要多遍历一次内部的 key,也可以 newSQLConfig 时存到 andList + // HAVING 前 WHERE 已经有条件 ? 占位,不能反过来,想优化 AND 连接在最前,需要多遍历一次内部的 key,也可以 newSQLConfig 时存到 andList result = "( " + result + " )" + AND + andCond; } else { @@ -3666,7 +3641,7 @@ else if (StringUtil.isNotEmpty(andCond, true)) { // andCond 必须放后面, * @throws Exception */ public String getWhereString(boolean hasPrefix, RequestMethod method, Map where - , Map> combine, List joinList, boolean verifyName) throws Exception { + , Map> combine, List> joinList, boolean verifyName) throws Exception { Set>> combineSet = combine == null ? null : combine.entrySet(); if (combineSet == null || combineSet.isEmpty()) { Log.w(TAG, "getWhereString combineSet == null || combineSet.isEmpty() >> return \"\";"); @@ -3703,7 +3678,7 @@ else if ("!".equals(ce.getKey())) { isItemFirst = true; cs = ""; for (String key : keyList) { - c = getWhereItem(key, where.get(key), method, verifyName); + c = gainWhereItem(key, where.get(key), method, verifyName); if (StringUtil.isEmpty(c, true)) {//避免SQL条件连接错误 continue; @@ -3734,7 +3709,7 @@ else if ("!".equals(ce.getKey())) { protected String concatJoinWhereString(String whereString) throws Exception { - List joinList = getJoinList(); + List> joinList = getJoinList(); if (joinList != null) { String newWs = ""; @@ -3743,12 +3718,12 @@ protected String concatJoinWhereString(String whereString) throws Exception { List newPvl = new ArrayList<>(); List pvl = new ArrayList<>(getPreparedValueList()); - SQLConfig jc; + SQLConfig jc; String js; boolean changed = false; // 各种 JOIN 没办法统一用 & | !连接,只能按优先级,和 @combine 一样? - for (Join j : joinList) { + for (Join j : joinList) { String jt = j.getJoinType(); switch (jt) { @@ -3769,7 +3744,7 @@ protected String concatJoinWhereString(String whereString) throws Exception { jc = j.getJoinConfig(); boolean isMain = jc.isMain(); jc.setMain(false).setPrepared(isPrepared()).setPreparedValueList(new ArrayList()); - js = jc.getWhereString(false); + js = jc.gainWhereString(false); jc.setMain(isMain); boolean isOuterJoin = "!".equals(jt); @@ -3802,7 +3777,7 @@ protected String concatJoinWhereString(String whereString) throws Exception { } else { if (isSideJoin || isForeignJoin) { - newWs += " ( " + getCondition(true, ws) + " ) "; + newWs += " ( " + gainCondition(true, ws) + " ) "; newPvl.addAll(pvl); newPvl.addAll(jc.getPreparedValueList()); @@ -3813,7 +3788,7 @@ protected String concatJoinWhereString(String whereString) throws Exception { continue; } - if (StringUtil.isEmpty(newWs, true) == false) { + if (StringUtil.isNotEmpty(newWs, true)) { newWs += AND; } @@ -3825,7 +3800,7 @@ else if (isForeignJoin) { // ) FOREIGN JOIN: (! A) & B // preparedValueList.add } else if (isSideJoin) { // ^ SIDE JOIN: ! (A & B) //MySQL 因为 NULL 值处理问题,(A & ! B) | (B & ! A) 与 ! (A & B) 返回结果不一样,后者往往更多 - newWs += " ( " + getCondition( + newWs += " ( " + gainCondition( true, ( isWsEmpty ? "" : ws + AND ) + " ( " + js + " ) " ) + " ) "; @@ -3833,7 +3808,7 @@ else if (isSideJoin) { // ^ SIDE JOIN: ! (A & B) else { // & INNER JOIN: A & B; | FULL JOIN: A | B; OUTER JOIN: ! (A | B) int logic = Logic.getType(jt); newWs += " ( " - + getCondition( + + gainCondition( Logic.isNot(logic), ws + ( isWsEmpty ? "" : (Logic.isAnd(logic) ? AND : OR) ) @@ -3874,7 +3849,7 @@ else if (isSideJoin) { // ^ SIDE JOIN: ! (A & B) * @return * @throws Exception */ - protected String getWhereItem(String key, Object value, RequestMethod method, boolean verifyName) throws Exception { + protected String gainWhereItem(String key, Object value, RequestMethod method, boolean verifyName) throws Exception { Log.d(TAG, "getWhereItem key = " + key); // 避免筛选到全部 value = key == null ? null : where.get(key); if (key == null || key.endsWith("()") || key.startsWith("@")) { //关键字||方法, +或-直接报错 @@ -3924,42 +3899,41 @@ else if (key.endsWith("<")) { keyType = 0; } - String column = getRealKey(method, key, false, true, verifyName); + String column = gainRealKey(method, key, false, true, verifyName); // 原始 SQL 片段 - String rawSQL = getRawSQL(key, value); + String rawSQL = gainRawSQL(key, value); switch (keyType) { case 1: - return getSearchString(key, column, value, rawSQL); + return gainSearchString(key, column, value, rawSQL); case -2: case 2: - return getRegExpString(key, column, value, keyType < 0, rawSQL); + return gainRegExpString(key, column, value, keyType < 0, rawSQL); case 3: - return getBetweenString(key, column, value, rawSQL); + return gainBetweenString(key, column, value, rawSQL); case 4: - return getRangeString(key, column, value, rawSQL); + return gainRangeString(key, column, value, rawSQL); case 5: - return getExistsString(key, column, value, rawSQL); + return gainExistsString(key, column, value, rawSQL); case 6: - return getContainString(key, column, value, rawSQL); + return gainContainString(key, column, value, rawSQL); case 7: - return getCompareString(key, column, value, ">=", rawSQL); + return gainCompareString(key, column, value, ">=", rawSQL); case 8: - return getCompareString(key, column, value, "<=", rawSQL); + return gainCompareString(key, column, value, "<=", rawSQL); case 9: - return getCompareString(key, column, value, ">", rawSQL); + return gainCompareString(key, column, value, ">", rawSQL); case 10: - return getCompareString(key, column, value, "<", rawSQL); + return gainCompareString(key, column, value, "<", rawSQL); default: // TODO MySQL JSON类型的字段对比 key='[]' 会无结果! key LIKE '[1, 2, 3]' //TODO MySQL , 后面有空格! - return getEqualString(key, column, value, rawSQL); + return gainEqualString(key, column, value, rawSQL); } } - @JSONField(serialize = false) - public String getEqualString(String key, String column, Object value, String rawSQL) throws Exception { - if (value != null && JSON.isBooleanOrNumberOrString(value) == false && value instanceof Subquery == false) { + public String gainEqualString(String key, String column, Object value, String rawSQL) throws Exception { + if (value != null && JSON.isBoolOrNumOrStr(value) == false && value instanceof Subquery == false) { throw new IllegalArgumentException(key + ":value 中value不合法!非PUT请求只支持 [Boolean, Number, String] 内的类型 !"); } @@ -3974,13 +3948,12 @@ public String getEqualString(String key, String column, Object value, String raw } String logic = value == null && rawSQL == null ? (not ? SQL.IS_NOT : SQL.IS) : (not ? " != " : " = "); - return getKey(column) + logic + (value instanceof Subquery ? getSubqueryString((Subquery) value) - : (rawSQL != null ? rawSQL : getValue(key, column, value))); + return gainKey(column) + logic + (value instanceof Subquery ? gainSubqueryString((Subquery) value) + : (rawSQL != null ? rawSQL : gainValue(key, column, value))); } - @JSONField(serialize = false) - public String getCompareString(String key, String column, Object value, String type, String rawSQL) throws Exception { - if (value != null && JSON.isBooleanOrNumberOrString(value) == false && value instanceof Subquery == false) { + public String gainCompareString(String key, String column, Object value, String type, String rawSQL) throws Exception { + if (value != null && JSON.isBoolOrNumOrStr(value) == false && value instanceof Subquery == false) { throw new IllegalArgumentException(key + ":value 中 value 不合法!比较运算 [>, <, >=, <=] 只支持 [Boolean, Number, String] 内的类型 !"); } @@ -3989,11 +3962,11 @@ public String getCompareString(String key, String column, Object value, String t throw new IllegalArgumentException(key + ":value 中 key 不合法!比较运算 [>, <, >=, <=] 不支持 [&, !, |] 中任何逻辑运算符 !"); } - return getKey(column) + " " + type + " " + (value instanceof Subquery ? getSubqueryString((Subquery) value) - : (rawSQL != null ? rawSQL : getValue(key, column, value))); + return gainKey(column) + " " + type + " " + (value instanceof Subquery ? gainSubqueryString((Subquery) value) + : (rawSQL != null ? rawSQL : gainValue(key, column, value))); } - public String getKey(String key) { + public String gainKey(@NotNull String key) { String lenFun = ""; if (key.endsWith("[")) { lenFun = isSQLServer() ? "datalength" : "length"; @@ -4007,7 +3980,7 @@ else if (isTest()) { if (key.contains("'")) { // || key.contains("#") || key.contains("--")) { throw new IllegalArgumentException("参数 " + key + " 不合法!key 中不允许有单引号 ' !"); } - return getSQLValue(key).toString(); + return gainSQLValue(key).toString(); } Map keyMap = getKeyMap(); @@ -4030,18 +4003,18 @@ else if (isTest()) { } public String getSQLKey(String key) { String q = getQuote(); - return (isKeyPrefix() ? q + getSQLAlias() + q + "." : "") + q + key + q; + return (isKeyPrefix() ? q + gainSQLAlias() + q + "." : "") + q + key + q; } /** * 使用prepareStatement预编译,值为 ? ,后续动态set进去 */ - protected Object getValue(@NotNull Object value) { - return getValue(null, null, value); + protected Object gainValue(@NotNull Object value) { + return gainValue(null, null, value); } protected List preparedValueList = new ArrayList<>(); - protected Object getValue(String key, String column, Object value) { + protected Object gainValue(String key, String column, Object value) { if (isPrepared()) { if (value == null) { return null; @@ -4071,16 +4044,16 @@ protected Object getValue(String key, String column, Object value) { return StringUtil.isEmpty(type, true) ? "?" : "cast(?" + SQL.AS + type + ")"; } - return key == null ? getSQLValue(value) : getSQLValue(key, column, value); + return key == null ? gainSQLValue(value) : gainSQLValue(key, column, value); } - public Object getSQLValue(String key, String column, @NotNull Object value) { + public Object gainSQLValue(String key, String column, @NotNull Object value) { Map castMap = getCast(); String type = key == null || castMap == null ? null : castMap.get(key); - Object val = getSQLValue(value); + Object val = gainSQLValue(value); return StringUtil.isEmpty(type, true) ? val : "cast(" + val + SQL.AS + type + ")"; } - public Object getSQLValue(@NotNull Object value) { + public Object gainSQLValue(@NotNull Object value) { if (value == null) { return SQL.NULL; } @@ -4095,7 +4068,7 @@ public List getPreparedValueList() { return preparedValueList; } @Override - public AbstractSQLConfig setPreparedValueList(List preparedValueList) { + public AbstractSQLConfig setPreparedValueList(List preparedValueList) { this.preparedValueList = preparedValueList; return this; } @@ -4106,11 +4079,10 @@ public AbstractSQLConfig setPreparedValueList(List preparedValueList) * @param column * @param value * @param rawSQL - * @return {@link #getSearchString(String, String, Object[], int)} + * @return {@link #gainSearchString(String, String, Object[], int)} * @throws IllegalArgumentException */ - @JSONField(serialize = false) - public String getSearchString(String key, String column, Object value, String rawSQL) throws IllegalArgumentException { + public String gainSearchString(String key, String column, Object value, String rawSQL) throws IllegalArgumentException { if (rawSQL != null) { throw new UnsupportedOperationException("@raw:value 中 " + key + " 不合法!@raw 不支持 key$ 这种功能符 !只支持 key, key!, key<, key{} 等比较运算 和 @column, @having !"); @@ -4123,11 +4095,11 @@ public String getSearchString(String key, String column, Object value, String ra column = logic.getKey(); Log.i(TAG, "getSearchString column = " + column); - JSONArray arr = newJSONArray(value); + List arr = newJSONArray(value); if (arr.isEmpty()) { return ""; } - return getSearchString(key, column, arr.toArray(), logic.getType()); + return gainSearchString(key, column, arr.toArray(), logic.getType()); } /**search key match values * @param key @@ -4137,8 +4109,7 @@ public String getSearchString(String key, String column, Object value, String ra * @return LOGIC [ key LIKE 'values[i]' ] * @throws IllegalArgumentException */ - @JSONField(serialize = false) - public String getSearchString(String key, String column, Object[] values, int type) throws IllegalArgumentException { + public String gainSearchString(String key, String column, Object[] values, int type) throws IllegalArgumentException { if (values == null || values.length <= 0) { return ""; } @@ -4156,10 +4127,10 @@ public String getSearchString(String key, String column, Object[] values, int ty // throw new IllegalArgumentException(key + "$:value 中 value 值 " + v + " 中包含 %% !不允许有连续的 % !"); // } - condition += (i <= 0 ? "" : (Logic.isAnd(type) ? AND : OR)) + getLikeString(key, column, (String) v); + condition += (i <= 0 ? "" : (Logic.isAnd(type) ? AND : OR)) + gainLikeString(key, column, (String) v); } - return getCondition(Logic.isNot(type), condition); + return gainCondition(Logic.isNot(type), condition); } /**WHERE key LIKE 'value' @@ -4168,8 +4139,7 @@ public String getSearchString(String key, String column, Object[] values, int ty * @param value * @return key LIKE 'value' */ - @JSONField(serialize = false) - public String getLikeString(@NotNull String key, @NotNull String column, String value) { + public String gainLikeString(@NotNull String key, @NotNull String column, String value) { String k = key.substring(0, key.length() - 1); char r = k.charAt(k.length() - 1); @@ -4218,7 +4188,7 @@ else if (l > 0 && StringUtil.isName(String.valueOf(l))) { } } - return getKey(column) + " LIKE " + getValue(key, column, value); + return gainKey(column) + " LIKE " + gainValue(key, column, value); } //$ search >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -4231,11 +4201,10 @@ else if (l > 0 && StringUtil.isName(String.valueOf(l))) { * @param column * @param value * @param ignoreCase - * @return {@link #getRegExpString(String, String, Object[], int, boolean)} + * @return {@link #gainRegExpString(String, String, Object[], int, boolean)} * @throws IllegalArgumentException */ - @JSONField(serialize = false) - public String getRegExpString(String key, String column, Object value, boolean ignoreCase, String rawSQL) + public String gainRegExpString(String key, String column, Object value, boolean ignoreCase, String rawSQL) throws IllegalArgumentException { if (rawSQL != null) { throw new UnsupportedOperationException("@raw:value 中 " + key + " 不合法!@raw 不支持 key~ 这种功能符 !" + @@ -4249,11 +4218,11 @@ public String getRegExpString(String key, String column, Object value, boolean i column = logic.getKey(); Log.i(TAG, "getRegExpString column = " + column); - JSONArray arr = newJSONArray(value); + L arr = newJSONArray(value); if (arr.isEmpty()) { return ""; } - return getRegExpString(key, column, arr.toArray(), logic.getType(), ignoreCase); + return gainRegExpString(key, column, arr.toArray(), logic.getType(), ignoreCase); } /**search key match RegExp values * @param key @@ -4263,8 +4232,7 @@ public String getRegExpString(String key, String column, Object value, boolean i * @return LOGIC [ key REGEXP 'values[i]' ] * @throws IllegalArgumentException */ - @JSONField(serialize = false) - public String getRegExpString(String key, String column, Object[] values, int type, boolean ignoreCase) + public String gainRegExpString(String key, String column, Object[] values, int type, boolean ignoreCase) throws IllegalArgumentException { if (values == null || values.length <= 0) { return ""; @@ -4276,10 +4244,10 @@ public String getRegExpString(String key, String column, Object[] values, int ty throw new IllegalArgumentException(key + ":value 中value的类型只能为String或String[]!"); } condition += (i <= 0 ? "" : (Logic.isAnd(type) ? AND : OR)) - + getRegExpString(key, column, (String) values[i], ignoreCase); + + gainRegExpString(key, column, (String) values[i], ignoreCase); } - return getCondition(Logic.isNot(type), condition); + return gainCondition(Logic.isNot(type), condition); } /**WHERE key REGEXP 'value' @@ -4288,30 +4256,29 @@ public String getRegExpString(String key, String column, Object[] values, int ty * @param ignoreCase * @return key REGEXP 'value' */ - @JSONField(serialize = false) - public String getRegExpString(String key, String column, String value, boolean ignoreCase) { + public String gainRegExpString(String key, String column, String value, boolean ignoreCase) { if (isPSQL()) { - return getKey(column) + " ~" + (ignoreCase ? "* " : " ") + getValue(key, column, value); + return gainKey(column) + " ~" + (ignoreCase ? "* " : " ") + gainValue(key, column, value); } - if (isOracle() || isDameng() || isKingBase() || (isMySQL() && getDBVersionNums()[0] >= 8)) { - return "regexp_like(" + getKey(column) + ", " + getValue(key, column, value) + (ignoreCase ? ", 'i'" : ", 'c'") + ")"; + if (isOracle() || isDameng() || isKingBase() || (isMySQL() && gainDBVersionNums()[0] >= 8)) { + return "regexp_like(" + gainKey(column) + ", " + gainValue(key, column, value) + (ignoreCase ? ", 'i'" : ", 'c'") + ")"; } if (isPresto() || isTrino()) { - return "regexp_like(" + (ignoreCase ? "lower(" : "") + getKey(column) + (ignoreCase ? ")" : "") - + ", " + (ignoreCase ? "lower(" : "") + getValue(key, column, value) + (ignoreCase ? ")" : "") + ")"; + return "regexp_like(" + (ignoreCase ? "lower(" : "") + gainKey(column) + (ignoreCase ? ")" : "") + + ", " + (ignoreCase ? "lower(" : "") + gainValue(key, column, value) + (ignoreCase ? ")" : "") + ")"; } if (isClickHouse()) { - return "match(" + (ignoreCase ? "lower(" : "") + getKey(column) + (ignoreCase ? ")" : "") - + ", " + (ignoreCase ? "lower(" : "") + getValue(key, column, value) + (ignoreCase ? ")" : "") + ")"; + return "match(" + (ignoreCase ? "lower(" : "") + gainKey(column) + (ignoreCase ? ")" : "") + + ", " + (ignoreCase ? "lower(" : "") + gainValue(key, column, value) + (ignoreCase ? ")" : "") + ")"; } if (isElasticsearch()) { - return getKey(column) + " RLIKE " + getValue(key, column, value); + return gainKey(column) + " RLIKE " + gainValue(key, column, value); } if (isHive()) { - return (ignoreCase ? "lower(" : "") + getKey(column) + (ignoreCase ? ")" : "") - + " REGEXP " + (ignoreCase ? "lower(" : "") + getValue(key, column, value) + (ignoreCase ? ")" : ""); + return (ignoreCase ? "lower(" : "") + gainKey(column) + (ignoreCase ? ")" : "") + + " REGEXP " + (ignoreCase ? "lower(" : "") + gainValue(key, column, value) + (ignoreCase ? ")" : ""); } - return getKey(column) + " REGEXP " + (ignoreCase ? "" : "BINARY ") + getValue(key, column, value); + return gainKey(column) + " REGEXP " + (ignoreCase ? "" : "BINARY ") + gainValue(key, column, value); } @@ -4327,8 +4294,7 @@ public String getRegExpString(String key, String column, String value, boolean i * @return LOGIC [ key BETWEEN 'start' AND 'end' ] * @throws IllegalArgumentException */ - @JSONField(serialize = false) - public String getBetweenString(String key, String column, Object value, String rawSQL) throws IllegalArgumentException { + public String gainBetweenString(String key, String column, Object value, String rawSQL) throws IllegalArgumentException { if (rawSQL != null) { throw new UnsupportedOperationException("@raw:value 中 " + key + " 不合法!@raw 不支持 key% 这种功能符 !" + "只支持 key, key!, key<, key{} 等比较运算 和 @column, @having !"); @@ -4341,11 +4307,11 @@ public String getBetweenString(String key, String column, Object value, String r column = logic.getKey(); Log.i(TAG, "getBetweenString column = " + column); - JSONArray arr = newJSONArray(value); + L arr = newJSONArray(value); if (arr.isEmpty()) { return ""; } - return getBetweenString(key, column, arr.toArray(), logic.getType()); + return gainBetweenString(key, column, arr.toArray(), logic.getType()); } /**WHERE key BETWEEN 'start' AND 'end' @@ -4356,8 +4322,7 @@ public String getBetweenString(String key, String column, Object value, String r * @return LOGIC [ key BETWEEN 'start' AND 'end' ] * @throws IllegalArgumentException */ - @JSONField(serialize = false) - public String getBetweenString(String key, String column, Object[] values, int type) throws IllegalArgumentException { + public String gainBetweenString(String key, String column, Object[] values, int type) throws IllegalArgumentException { if (values == null || values.length <= 0) { return ""; } @@ -4376,10 +4341,10 @@ public String getBetweenString(String key, String column, Object[] values, int t } condition += (i <= 0 ? "" : (Logic.isAnd(type) ? AND : OR)) - + "(" + getBetweenString(key, column, vs[0], (Object) vs[1]) + ")"; + + "(" + gainBetweenString(key, column, vs[0], (Object) vs[1]) + ")"; } - return getCondition(Logic.isNot(type), condition); + return gainCondition(Logic.isNot(type), condition); } /**WHERE key BETWEEN 'start' AND 'end' @@ -4390,13 +4355,12 @@ public String getBetweenString(String key, String column, Object[] values, int t * @return LOGIC [ key BETWEEN 'start' AND 'end' ] * @throws IllegalArgumentException */ - @JSONField(serialize = false) - public String getBetweenString(String key, String column, Object start, Object end) throws IllegalArgumentException { - if (JSON.isBooleanOrNumberOrString(start) == false || JSON.isBooleanOrNumberOrString(end) == false) { + public String gainBetweenString(String key, String column, Object start, Object end) throws IllegalArgumentException { + if (JSON.isBoolOrNumOrStr(start) == false || JSON.isBoolOrNumOrStr(end) == false) { throw new IllegalArgumentException(key + ":value 中 value 不合法!类型为 String 时必须包括1个逗号 , " + "且左右两侧都有值!类型为 String[] 里面每个元素要符合前面类型为 String 的规则 !"); } - return getKey(column) + " BETWEEN " + getValue(key, column, start) + AND + getValue(key, column, end); + return gainKey(column) + " BETWEEN " + gainValue(key, column, start) + AND + gainValue(key, column, end); } @@ -4413,8 +4377,7 @@ public String getBetweenString(String key, String column, Object start, Object e * @return key condition0 AND key condition1 AND ... * @throws Exception */ - @JSONField(serialize = false) - public String getRangeString(String key, String column, Object range, String rawSQL) throws Exception { + public String gainRangeString(String key, String column, Object range, String rawSQL) throws Exception { Log.i(TAG, "getRangeString column = " + column); if (range == null) {//依赖的对象都没有给出有效值,这个存在无意义。如果是客户端传的,那就能在客户端确定了。 throw new NotExistException(TAG + "getRangeString(" + column + ", " + range + ") range == null"); @@ -4435,7 +4398,7 @@ public String getRangeString(String key, String column, Object range, String raw if (logic.isNot() && l.isEmpty()) { return ""; // key!{}: [] 这个条件无效,加到 SQL 语句中 key IN() 会报错,getInString 里不好处理 } - return getKey(k) + getInString(k, column, l.toArray(), logic.isNot()); + return gainKey(k) + gainInString(k, column, l.toArray(), logic.isNot()); } throw new IllegalArgumentException(key + ":[] 中 {} 前面的逻辑运算符错误!只能用'|','!'中的一种 !"); } @@ -4445,7 +4408,7 @@ else if (range instanceof String) {//非Number类型需要客户端拼接成 < ' if (rawSQL != null) { int index = rawSQL.indexOf("("); - condition = (index >= 0 && index < rawSQL.lastIndexOf(")") ? "" : getKey(k) + " ") + rawSQL; + condition = (index >= 0 && index < rawSQL.lastIndexOf(")") ? "" : gainKey(k) + " ") + rawSQL; } if (cs != null) { @@ -4467,7 +4430,7 @@ else if (range instanceof String) {//非Number类型需要客户端拼接成 < ' , key + ":\"!=null;+3*2<=10;function0(arg0,arg1,...)>1;function1(...)%5<=3...\""); } else { - String fk = getKey(k) + " "; + String fk = gainKey(k) + " "; String[] ccs = StringUtil.split(expr, false); expr = ""; @@ -4497,11 +4460,11 @@ else if (isPrepared() && (c.contains("--") || PATTERN_RANGE.matcher(c).matches() return ""; } - return getCondition(logic.isNot(), condition); + return gainCondition(logic.isNot(), condition); } else if (range instanceof Subquery) { - // 如果在 Parser 解析成 SQL 字符串再引用,没法保证安全性,毕竟可以再通过远程函数等方式来拼接再替代,最后引用的字符串就能注入 - return getKey(k) + (logic.isNot() ? NOT : "") + " IN " + getSubqueryString((Subquery) range); + // 如果在 Parser 解析成 SQL 字符串再引用,没法保证安全性,毕竟可以再通过远程函数等方式来拼接再替代,最后引用的字符串就能注入 + return gainKey(k) + (logic.isNot() ? NOT : "") + " IN " + gainSubqueryString((Subquery) range); } throw new IllegalArgumentException(key + ":range 类型为" + range.getClass().getSimpleName() @@ -4512,12 +4475,11 @@ else if (range instanceof Subquery) { * @return IN ('key0', 'key1', ... ) * @throws NotExistException */ - @JSONField(serialize = false) - public String getInString(String key, String column, Object[] in, boolean not) throws NotExistException { + public String gainInString(String key, String column, Object[] in, boolean not) throws NotExistException { String condition = ""; if (in != null) {//返回 "" 会导致 id:[] 空值时效果和没有筛选id一样! for (int i = 0; i < in.length; i++) { - condition += ((i > 0 ? "," : "") + getValue(key, column, in[i])); + condition += ((i > 0 ? "," : "") + gainValue(key, column, in[i])); } } if (condition.isEmpty()) {//条件如果存在必须执行,不能忽略。条件为空会导致出错,又很难保证条件不为空(@:条件),所以还是这样好 @@ -4537,8 +4499,7 @@ public String getInString(String key, String column, Object[] in, boolean not) t * @return EXISTS ALL(SELECT ...) * @throws NotExistException */ - @JSONField(serialize = false) - public String getExistsString(String key, String column, Object value, String rawSQL) throws Exception { + public String gainExistsString(String key, String column, Object value, String rawSQL) throws Exception { if (rawSQL != null) { throw new UnsupportedOperationException("@raw:value 中 " + key + " 不合法!" + "@raw 不支持 key}{ 这种功能符 !只支持 key, key!, key<, key{} 等比较运算 和 @column, @having !"); @@ -4555,7 +4516,7 @@ public String getExistsString(String key, String column, Object value, String ra column = logic.getKey(); Log.i(TAG, "getExistsString column = " + column); - return (logic.isNot() ? NOT : "") + " EXISTS " + getSubqueryString((Subquery) value); + return (logic.isNot() ? NOT : "") + " EXISTS " + gainSubqueryString((Subquery) value); } //}{ exists >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -4563,11 +4524,10 @@ public String getExistsString(String key, String column, Object value, String ra /**WHERE key contains value * @param key * @param value - * @return {@link #getContainString(String, String, Object[], int)} + * @return {@link #gainContainString(String, String, Object[], int)} * @throws NotExistException */ - @JSONField(serialize = false) - public String getContainString(String key, String column, Object value, String rawSQL) throws IllegalArgumentException { + public String gainContainString(String key, String column, Object value, String rawSQL) throws IllegalArgumentException { if (rawSQL != null) { throw new UnsupportedOperationException("@raw:value 中 " + key + " 不合法!@raw 不支持 key<> 这种功能符 !" + "只支持 key, key!, key<, key{} 等比较运算 和 @column, @having !"); @@ -4577,7 +4537,7 @@ public String getContainString(String key, String column, Object value, String r column = logic.getKey(); Log.i(TAG, "getContainString column = " + column); - return getContainString(key, column, newJSONArray(value).toArray(), logic.getType()); + return gainContainString(key, column, newJSONArray(value).toArray(), logic.getType()); } /**WHERE key contains childs TODO 支持 key<>: { "path":"$[0].name", "value": 82001 } * 或者 key<$[0].name>:82001 或者 key$[0].name<>:82001 ? 还是前者好,key 一旦复杂了, @@ -4589,8 +4549,7 @@ public String getContainString(String key, String column, Object value, String r * OR key LIKE '%, " + childs[i] + ", %' OR key LIKE '%, " + childs[i] + "]' ) ] * @throws IllegalArgumentException */ - @JSONField(serialize = false) - public String getContainString(String key, String column, Object[] childs, int type) throws IllegalArgumentException { + public String gainContainString(String key, String column, Object[] childs, int type) throws IllegalArgumentException { boolean not = Logic.isNot(type); String condition = ""; if (childs != null) { @@ -4617,44 +4576,44 @@ public String getContainString(String key, String column, Object[] childs, int t condition += (i <= 0 ? "" : (Logic.isAnd(type) ? AND : OR)); if (isPSQL()) { - condition += (getKey(column) + " @> " + getValue(key, column, newJSONArray(c))); + condition += (gainKey(column) + " @> " + gainValue(key, column, newJSONArray(c))); // operator does not exist: jsonb @> character varying "[" + c + "]"); } else if (isOracle() || isDameng() || isKingBase()) { - condition += ("json_textcontains(" + getKey(column) + ", " + (StringUtil.isEmpty(path, true) - ? "'$'" : getValue(key, column, path)) + ", " + getValue(key, column, c == null ? null : c.toString()) + ")"); + condition += ("json_textcontains(" + gainKey(column) + ", " + (StringUtil.isEmpty(path, true) + ? "'$'" : gainValue(key, column, path)) + ", " + gainValue(key, column, c == null ? null : c.toString()) + ")"); } else if (isPresto() || isTrino()) { - condition += ("json_array_contains(cast(" + getKey(column) + " AS VARCHAR), " - + getValue(key, column, c) + (StringUtil.isEmpty(path, true) - ? "" : ", " + getValue(key, column, path)) + ")"); + condition += ("json_array_contains(cast(" + gainKey(column) + " AS VARCHAR), " + + gainValue(key, column, c) + (StringUtil.isEmpty(path, true) + ? "" : ", " + gainValue(key, column, path)) + ")"); } else { String v = c == null ? "null" : (c instanceof Boolean || c instanceof Number ? c.toString() : "\"" + c + "\""); if (isClickHouse()) { - condition += (condition + "has(JSONExtractArrayRaw(assumeNotNull(" + getKey(column) + "))" - + ", " + getValue(key, column, v) + (StringUtil.isEmpty(path, true) - ? "" : ", " + getValue(key, column, path)) + ")"); + condition += (condition + "has(JSONExtractArrayRaw(assumeNotNull(" + gainKey(column) + "))" + + ", " + gainValue(key, column, v) + (StringUtil.isEmpty(path, true) + ? "" : ", " + gainValue(key, column, path)) + ")"); } else { - condition += ("json_contains(" + getKey(column) + ", " + getValue(key, column, v) - + (StringUtil.isEmpty(path, true) ? "" : ", " + getValue(key, column, path)) + ")"); + condition += ("json_contains(" + gainKey(column) + ", " + gainValue(key, column, v) + + (StringUtil.isEmpty(path, true) ? "" : ", " + gainValue(key, column, path)) + ")"); } } } if (condition.isEmpty()) { - condition = getKey(column) + SQL.isNull(true) + OR + getLikeString(key, column, "[]"); // key = '[]' 无结果! + condition = gainKey(column) + SQL.isNull(true) + OR + gainLikeString(key, column, "[]"); // key = '[]' 无结果! } else { - condition = getKey(column) + SQL.isNull(false) + AND + "(" + condition + ")"; + condition = gainKey(column) + SQL.isNull(false) + AND + "(" + condition + ")"; } } if (condition.isEmpty()) { return ""; } - return getCondition(not, condition); + return gainCondition(not, condition); } //<> contain >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -4662,6 +4621,27 @@ else if (isPresto() || isTrino()) { //key@:{} Subquery <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + public List getWithAsExprSQLList() { + return withAsExprSQLList; + } + private void clearWithAsExprListIfNeed() { + // mysql8版本以上,子查询支持with as表达式 + if(this.isMySQL() && this.gainDBVersionNums()[0] >= 8) { + this.withAsExprSQLList = new ArrayList<>(); + } + } + + @Override + public List getWithAsExprPreparedValueList() { + return this.withAsExprPreparedValueList; + } + + @Override + public AbstractSQLConfig setWithAsExprPreparedValueList(List list) { + this.withAsExprPreparedValueList = list; + return this; + } + /** * 只要 method != RequestMethod.POST 就都支持 with-as表达式 * @param cfg @@ -4669,20 +4649,20 @@ else if (isPresto() || isTrino()) { * @return * @throws Exception */ - private String withAsExpreSubqueryString(SQLConfig cfg, Subquery subquery) throws Exception { + private String withAsExprSubqueryString(SQLConfig cfg, Subquery subquery) throws Exception { boolean isWithAsEnable = isWithAsEnable(); - List list = isWithAsEnable ? getWithAsExprSqlList() : null; + List list = isWithAsEnable ? getWithAsExprSQLList() : null; if (cfg.getMethod() != RequestMethod.POST && list == null) { clearWithAsExprListIfNeed(); } String quote = getQuote(); - String as = getAs(); + String as = gainAs(); String withAsExpreSql; if (list != null) { - String withQuoteName = quote + subquery.getKey() + quote; - list.add(" " + withQuoteName + as + "(" + cfg.getSQL(isPrepared()) + ") "); + String withQuoteName = quote + subquery.gainKey() + quote; + list.add(" " + withQuoteName + as + "(" + cfg.gainSQL(isPrepared()) + ") "); withAsExpreSql = " SELECT * FROM " + withQuoteName; // 预编译参数 FIXME 这里重复添加了,导致子查询都报错参数超过 ? 数量 Parameter index out of range (5 > number of parameters, which is 4) @@ -4698,10 +4678,10 @@ private String withAsExpreSubqueryString(SQLConfig cfg, Subquery subquery) throw cfg.setPreparedValueList(new ArrayList<>()); } } else { - withAsExpreSql = cfg.getSQL(isPrepared()); + withAsExpreSql = cfg.gainSQL(isPrepared()); // mysql 才存在这个问题, 主表和子表是一张表 - if (isWithAsEnable && isMySQL() && StringUtil.equals(getTable(), subquery.getFrom())) { - withAsExpreSql = " SELECT * FROM (" + withAsExpreSql + ")" + as + quote + subquery.getKey() + quote; + if (isWithAsEnable && isMySQL() && StringUtil.equals(getTable(), subquery.gainFrom())) { + withAsExpreSql = " SELECT * FROM (" + withAsExpreSql + ")" + as + quote + subquery.gainKey() + quote; } } @@ -4709,20 +4689,20 @@ private String withAsExpreSubqueryString(SQLConfig cfg, Subquery subquery) throw } @Override - public String getSubqueryString(Subquery subquery) throws Exception { + public String gainSubqueryString(Subquery subquery) throws Exception { if (subquery == null) { return ""; } - String range = subquery.getRange(); - SQLConfig cfg = subquery.getConfig(); + String range = subquery.gainRange(); + SQLConfig cfg = subquery.gainConfig(); // 子查询 = 主语句 datasource - if(StringUtil.equals(this.getTable(), subquery.getFrom() ) == false && cfg.hasJoin() == false) { + if (StringUtil.equals(this.getTable(), subquery.gainFrom()) == false && cfg.hasJoin() == false) { cfg.setDatasource(this.getDatasource()); } cfg.setPreparedValueList(new ArrayList<>()); - String withAsExprSql = withAsExpreSubqueryString(cfg, subquery); + String withAsExprSql = withAsExprSubqueryString(cfg, subquery); String sql = (range == null || range.isEmpty() ? "" : range) + "(" + withAsExprSql + ") "; //// SELECT .. FROM(SELECT ..) .. WHERE .. 格式需要把子查询中的预编译值提前 @@ -4763,8 +4743,8 @@ public String getSubqueryString(Subquery subquery) throws Exception { * @param condition * @return */ - public static String getCondition(boolean not, String condition) { - return getCondition(not, condition, false); + public static String gainCondition(boolean not, String condition) { + return gainCondition(not, condition, false); } /**拼接条件 * @param not @@ -4772,7 +4752,7 @@ public static String getCondition(boolean not, String condition) { * @param addOuterBracket * @return */ - public static String getCondition(boolean not, String condition, boolean addOuterBracket) { + public static String gainCondition(boolean not, String condition, boolean addOuterBracket) { String s = not ? NOT + "(" + condition + ")" : condition; return addOuterBracket ? "( " + s + " )" : s; } @@ -4783,8 +4763,20 @@ public static String getCondition(boolean not, String condition, boolean addOute * @return */ @NotNull - public static JSONArray newJSONArray(Object obj) { - JSONArray array = new JSONArray(); + public L newJSONArray(Object obj) { + L array = JSON.createJSONArray(); + if (obj != null) { + if (obj instanceof Collection) { + array.addAll((Collection) obj); + } else { + array.add(obj); + } + } + return array; + } + @NotNull + public static , L extends List> L newJSONArray(Object obj, @NotNull JSONCreator creator) { + L array = creator.createJSONArray(); if (obj != null) { if (obj instanceof Collection) { array.addAll((Collection) obj); @@ -4803,9 +4795,8 @@ public static JSONArray newJSONArray(Object obj) { * @return * @throws Exception */ - @JSONField(serialize = false) - public String getSetString() throws Exception { - return getSetString(getMethod(), getContent(), ! isTest()); + public String gainSetString() throws Exception { + return gainSetString(getMethod(), getContent(), ! isTest()); } //CS304 Issue link: https://github.com/Tencent/APIJSON/issues/48 /**获取SET @@ -4815,8 +4806,7 @@ public String getSetString() throws Exception { * @throws Exception *

use entrySet+getValue() to replace keySet+get() to enhance efficiency

*/ - @JSONField(serialize = false) - public String getSetString(RequestMethod method, Map content, boolean verifyName) throws Exception { + public String gainSetString(RequestMethod method, Map content, boolean verifyName) throws Exception { Set set = content == null ? null : content.keySet(); String setString = ""; @@ -4841,11 +4831,11 @@ public String getSetString(RequestMethod method, Map content, bo keyType = 0; //注意重置类型,不然不该加减的字段会跟着加减 } value = entry.getValue(); - String column = getRealKey(method, key, false, true, verifyName); + String column = gainRealKey(method, key, false, true, verifyName); - setString += (isFirst ? "" : ", ") + (getKey(column) + " = " - + (keyType == 1 ? getAddString(key, column, value) : (keyType == 2 - ? getRemoveString(key, column, value) : getValue(key, column, value)) ) + setString += (isFirst ? "" : ", ") + (gainKey(column) + " = " + + (keyType == 1 ? gainAddString(key, column, value) : (keyType == 2 + ? gainRemoveString(key, column, value) : gainValue(key, column, value)) ) ); isFirst = false; @@ -4864,13 +4854,12 @@ public String getSetString(RequestMethod method, Map content, bo * @return concat(key, 'value') * @throws IllegalArgumentException */ - @JSONField(serialize = false) - public String getAddString(String key, String column, Object value) throws IllegalArgumentException { + public String gainAddString(String key, String column, Object value) throws IllegalArgumentException { if (value instanceof Number) { - return getKey(column) + " + " + value; + return gainKey(column) + " + " + value; } if (value instanceof String) { - return SQL.concat(getKey(column), (String) getValue(key, column, value)); + return SQL.concat(gainKey(column), (String) gainValue(key, column, value)); } throw new IllegalArgumentException(key + ":value 中 value 类型错误,必须是 Number,String,Array 中的任何一种!"); } @@ -4880,13 +4869,12 @@ public String getAddString(String key, String column, Object value) throws Illeg * @return REPLACE (key, 'value', '') * @throws IllegalArgumentException */ - @JSONField(serialize = false) - public String getRemoveString(String key, String column, Object value) throws IllegalArgumentException { + public String gainRemoveString(String key, String column, Object value) throws IllegalArgumentException { if (value instanceof Number) { - return getKey(column) + " - " + value; + return gainKey(column) + " - " + value; } if (value instanceof String) { - return SQL.replace(getKey(column), (String) getValue(key, column, value), "''"); + return SQL.replace(gainKey(column), (String) gainValue(key, column, value), "''"); // " replace(" + column + ", '" + value + "', '') "; } throw new IllegalArgumentException(key + ":value 中 value 类型错误,必须是 Number,String,Array 中的任何一种!"); @@ -4907,15 +4895,14 @@ public Map onFakeDelete(Map map) { * @return * @throws Exception */ - @JSONField(serialize = false) @Override - public String getSQL(boolean prepared) throws Exception { + public String gainSQL(boolean prepared) throws Exception { boolean isPrepared = isPrepared(); if (isPrepared == prepared) { - return getSQL(this); + return gainSQL(this); } - String sql = getSQL(this.setPrepared(prepared)); + String sql = gainSQL(this.setPrepared(prepared)); setPrepared(isPrepared); return sql; } @@ -4924,7 +4911,7 @@ public String getSQL(boolean prepared) throws Exception { * @return * @throws Exception */ - public static String getSQL(AbstractSQLConfig config) throws Exception { + public static , L extends List> String gainSQL(AbstractSQLConfig config) throws Exception { if (config == null) { Log.i(TAG, "getSQL config == null >> return null;"); return null; @@ -4932,7 +4919,7 @@ public static String getSQL(AbstractSQLConfig config) throws Exception { // TODO procedure 改为 List procedureList; behind : true; function: callFunction(); String key; ... // for (...) { Call procedure1();\n SQL \n; Call procedure2(); ... } - // 貌似不需要,因为 ObjectParser 里就已经处理的顺序等,只是这里要解决下 Schema 问题。 + // 貌似不需要,因为 ObjectParser 里就已经处理的顺序等,只是这里要解决下 Schema 问题。 String procedure = config.getProcedure(); if (StringUtil.isNotEmpty(procedure, true)) { @@ -4940,38 +4927,43 @@ public static String getSQL(AbstractSQLConfig config) throws Exception { boolean hasPrefix = ind >= 0 && ind < procedure.indexOf("("); String sch = hasPrefix ? AbstractFunctionParser.extractSchema( procedure.substring(0, ind), config.getTable() - ) : config.getSQLSchema(); + ) : config.gainSQLSchema(); String q = config.getQuote(); return "CALL " + q + sch + q + "." + (hasPrefix ? procedure.substring(ind + 1) : procedure); } - String tablePath = config.getTablePath(); - if (StringUtil.isNotEmpty(tablePath, true) == false) { - Log.i(TAG, "getSQL StringUtil.isNotEmpty(tablePath, true) == false >> return null;"); + String tablePath = config.gainTablePath(); + if (StringUtil.isEmpty(tablePath, true)) { + Log.i(TAG, "getSQL StringUtil.isEmpty(tablePath, true) >> return null;"); return null; } // 解决重复添加导致报错:Parameter index out of range (6 > number of parameters, which is 5) config.setPreparedValueList(new ArrayList<>()); + RequestMethod method = config.getMethod(); + if (method == null) { + method = GET; + } + String cSql = null; - switch (config.getMethod()) { + switch (method) { case POST: - return "INSERT INTO " + tablePath + config.getColumnString() + " VALUES" + config.getValuesString(); + return "INSERT INTO " + tablePath + config.gainColumnString() + " VALUES" + config.getValuesString(); case PUT: if(config.isClickHouse()){ - return "ALTER TABLE " + tablePath + " UPDATE" + config.getSetString() + config.getWhereString(true); + return "ALTER TABLE " + tablePath + " UPDATE" + config.gainSetString() + config.gainWhereString(true); } - cSql = "UPDATE " + tablePath + config.getSetString() + config.getWhereString(true) - + (config.isMySQL() ? config.getLimitString() : ""); + cSql = "UPDATE " + tablePath + config.gainSetString() + config.gainWhereString(true) + + (config.isMySQL() ? config.gainLimitString() : ""); cSql = buildWithAsExprSql(config, cSql); return cSql; case DELETE: if(config.isClickHouse()){ - return "ALTER TABLE " + tablePath + " DELETE" + config.getWhereString(true); + return "ALTER TABLE " + tablePath + " DELETE" + config.gainWhereString(true); } - cSql = "DELETE FROM " + tablePath + config.getWhereString(true) - + (config.isMySQL() ? config.getLimitString() : ""); // PostgreSQL 不允许 LIMIT + cSql = "DELETE FROM " + tablePath + config.gainWhereString(true) + + (config.isMySQL() ? config.gainLimitString() : ""); // PostgreSQL 不允许 LIMIT cSql = buildWithAsExprSql(config, cSql); return cSql; default: @@ -4979,27 +4971,27 @@ public static String getSQL(AbstractSQLConfig config) throws Exception { : (config.isOracle() || config.isDameng() || config.isKingBase() ? "EXPLAIN PLAN FOR " : "EXPLAIN ")) : ""; if (config.isTest() && RequestMethod.isGetMethod(config.getMethod(), true)) { // FIXME 为啥是 code 而不是 count ? String q = config.getQuote(); // 生成 SELECT ( (24 >=0 AND 24 <3) ) AS `code` LIMIT 1 OFFSET 0 - return explain + "SELECT " + config.getWhereString(false) - + config.getAs() + q + JSONResponse.KEY_COUNT + q + config.getLimitString(); + return explain + "SELECT " + config.gainWhereString(false) + + config.gainAs() + q + JSONResponse.KEY_COUNT + q + config.gainLimitString(); } config.setPreparedValueList(new ArrayList()); - String column = config.getColumnString(); + String column = config.gainColumnString(); if (config.isOracle() || config.isDameng() || config.isKingBase()) { //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() == JSONRequest.CACHE_RAM - ? "SQL_NO_CACHE " : "") + column + " FROM " + getConditionString(tablePath, config) + ") " + config.getLimitString(); + return explain + "SELECT count(*) FROM (SELECT " + (config.getCache() == apijson.JSONObject.CACHE_RAM + ? "SQL_NO_CACHE " : "") + column + " FROM " + gainConditionString(tablePath, config) + ") " + config.gainLimitString(); } - String sql = "SELECT " + (config.getCache() == JSONRequest.CACHE_RAM - ? "SQL_NO_CACHE " : "") + column + " FROM " + getConditionString(tablePath, config); - return explain + config.getOraclePageSql(sql); + String sql = "SELECT " + (config.getCache() == apijson.JSONObject.CACHE_RAM + ? "SQL_NO_CACHE " : "") + column + " FROM " + gainConditionString(tablePath, config); + return explain + config.gainOraclePageSQL(sql); } - cSql = "SELECT " + (config.getCache() == JSONRequest.CACHE_RAM ? "SQL_NO_CACHE " : "") - + column + " FROM " + getConditionString(tablePath, config) + config.getLimitString(); + cSql = "SELECT " + (config.getCache() == apijson.JSONObject.CACHE_RAM ? "SQL_NO_CACHE " : "") + + column + " FROM " + gainConditionString(tablePath, config) + config.gainLimitString(); cSql = buildWithAsExprSql(config, cSql); if(config.isElasticsearch()) { // elasticSearch 不支持 explain return cSql; @@ -5008,12 +5000,12 @@ public static String getSQL(AbstractSQLConfig config) throws Exception { } } - private static String buildWithAsExprSql(@NotNull AbstractSQLConfig config, String cSql) throws Exception { + private static , L extends List> String buildWithAsExprSql(@NotNull AbstractSQLConfig config, String cSql) throws Exception { if (config.isWithAsEnable() == false) { return cSql; } - List list = config.getWithAsExprSqlList(); + List list = config.getWithAsExprSQLList(); int size = list == null ? 0 : list.size(); if (size > 0) { String withAsExpreSql = "WITH "; @@ -5028,21 +5020,21 @@ private static String buildWithAsExprSql(@NotNull AbstractSQLConfig config, Stri @Override public boolean isWithAsEnable() { - return ENABLE_WITH_AS && (isMySQL() == false || getDBVersionNums()[0] >= 8); + return ENABLE_WITH_AS && (isMySQL() == false || gainDBVersionNums()[0] >= 8); } /**Oracle的分页获取 * @param sql * @return */ - protected String getOraclePageSql(String sql) { + protected String gainOraclePageSQL(String sql) { int count = getCount(); if (count <= 0 || RequestMethod.isHeadMethod(getMethod(), true)) { // TODO HEAD 真的不需要 LIMIT ? return sql; } int offset = getOffset(getPage(), count); String quote = getQuote(); - String alias = quote + getSQLAlias() + quote; + String alias = quote + gainSQLAlias() + quote; return "SELECT * FROM (SELECT " + alias + ".*, ROWNUM "+ quote + "RN" + quote +" FROM (" + sql + ") " + alias + " WHERE ROWNUM <= " + (offset + count) + ") WHERE "+ quote + "RN" + quote +" > " + offset; } @@ -5053,32 +5045,33 @@ protected String getOraclePageSql(String sql) { * @return * @throws Exception */ - private static String getConditionString(String table, AbstractSQLConfig config) throws Exception { - Subquery from = config.getFrom(); + private static , L extends List> String gainConditionString( + String table, AbstractSQLConfig config) throws Exception { + Subquery from = config.getFrom(); if (from != null) { - table = config.getSubqueryString(from) + config.getAs() + config.getSQLAliasWithQuote() + " "; + table = config.gainSubqueryString(from) + config.gainAs() + config.gainSQLAliasWithQuote() + " "; } - String join = config.getJoinString(); + String join = config.gainJoinString(); - String where = config.getWhereString(true); + String where = config.gainWhereString(true); //根据方法不同,聚合语句不同。GROUP BY 和 HAVING 可以加在 HEAD 上, HAVING 可以加在 PUT, DELETE 上,GET 全加,POST 全都不加 String aggregation; if (RequestMethod.isGetMethod(config.getMethod(), true)) { - aggregation = config.getGroupString(true) + config.getHavingString(true) - + config.getSampleString(true) + config.getLatestString(true) - + config.getPartitionString(true) + config.getFillString(true) - + config.getOrderString(true); + aggregation = config.gainGroupString(true) + config.gainHavingString(true) + + config.gainSampleString(true) + config.gainLatestString(true) + + config.gainPartitionString(true) + config.gainFillString(true) + + config.gainOrderString(true); } else if (RequestMethod.isHeadMethod(config.getMethod(), true)) { // TODO 加参数 isPagenation 判断是 GET 内分页 query:2 查总数,不用加这些条件 - aggregation = config.getGroupString(true) + config.getHavingString(true) - + config.getSampleString(true) + config.getLatestString(true) - + config.getPartitionString(true) + config.getFillString(true); + aggregation = config.gainGroupString(true) + config.gainHavingString(true) + + config.gainSampleString(true) + config.gainLatestString(true) + + config.gainPartitionString(true) + config.gainFillString(true); } else if (config.getMethod() == PUT || config.getMethod() == DELETE) { - aggregation = config.getHavingString(true) ; + aggregation = config.gainHavingString(true) ; } else { aggregation = ""; @@ -5129,13 +5122,13 @@ public boolean isKeyPrefix() { return keyPrefix; } @Override - public AbstractSQLConfig setKeyPrefix(boolean keyPrefix) { + public AbstractSQLConfig setKeyPrefix(boolean keyPrefix) { this.keyPrefix = keyPrefix; return this; } - public String getJoinString() throws Exception { + public String gainJoinString() throws Exception { String joinOns = ""; if (joinList != null) { @@ -5145,7 +5138,7 @@ public String getJoinString() throws Exception { // 主表不用别名 String ta; for (Join j : joinList) { - onGetJoinString(j); + onGainJoinString(j); if (j.isAppJoin()) { // APP JOIN,只是作为一个标记,执行完主表的查询后自动执行副表的查询 User.id IN($commentIdList) continue; @@ -5154,11 +5147,11 @@ public String getJoinString() throws Exception { //LEFT JOIN sys.apijson_user AS User ON User.id = Moment.userId, 都是用 = ,通过relateType处理缓存 // <"INNER JOIN User ON User.id = Moment.userId", UserConfig> TODO AS 放 getSQLTable 内 - SQLConfig jc = j.getJoinConfig(); + SQLConfig jc = j.getJoinConfig(); jc.setPrepared(isPrepared()); // 将关联表所属数据源配置为主表数据源 jc.setDatasource(this.getDatasource()); - String jt = jc.getSQLAlias(); + String jt = jc.gainSQLAlias(); List onList = j.getOnList(); //如果要强制小写,则可在子类重写这个方法再 toLowerCase @@ -5174,12 +5167,12 @@ public String getJoinString() throws Exception { // continue; case "*": // CROSS JOIN - onGetCrossJoinString(j); + onGainCrossJoinString(j); case "<": // LEFT JOIN case ">": // RIGHT JOIN jc.setMain(true).setKeyPrefix(false); sql = ( "<".equals(type) ? " LEFT" : (">".equals(type) ? " RIGHT" : " CROSS") ) - + " JOIN ( " + jc.getSQL(isPrepared()) + " ) " + getAs() + quote + jt + quote; + + " JOIN ( " + jc.gainSQL(isPrepared()) + " ) " + gainAs() + quote + jt + quote; sql = concatJoinOn(sql, quote, j, jt, onList); jc.setMain(false).setKeyPrefix(true); @@ -5195,15 +5188,15 @@ public String getJoinString() throws Exception { case "^": // SIDE JOIN: ! (A & B) case "(": // ANTI JOIN: A & ! B case ")": // FOREIGN JOIN: B & ! A - sql = " INNER JOIN " + jc.getTablePath(); + sql = " INNER JOIN " + jc.gainTablePath(); sql = concatJoinOn(sql, quote, j, jt, onList); break; case "~": // ASOF JOIN: B ~= A - sql = " ASOF JOIN " + jc.getTablePath(); + sql = " ASOF JOIN " + jc.gainTablePath(); sql = concatJoinOn(sql, quote, j, jt, onList); break; default: - String k = jc.getTableKey(); + String k = jc.gainTableKey(); throw new UnsupportedOperationException( "join:value 中 value 里的 " + k + "/" + j.getPath() + "错误!不支持 " + k + " 等 [ @ APP, < LEFT, > RIGHT, * CROSS" @@ -5211,13 +5204,13 @@ public String getJoinString() throws Exception { ); } - SQLConfig oc = j.getOuterConfig(); + SQLConfig oc = j.getOuterConfig(); String ow = null; if (oc != null) { oc.setPrepared(isPrepared()); oc.setPreparedValueList(new ArrayList<>()); oc.setMain(false).setKeyPrefix(true); - ow = oc.getWhereString(false); + ow = oc.gainWhereString(false); pvl.addAll(oc.getPreparedValueList()); //changed = true; @@ -5240,10 +5233,9 @@ public String getJoinString() throws Exception { return StringUtil.isEmpty(joinOns, true) ? "" : joinOns + " \n"; } - - protected String concatJoinOn(@NotNull String sql, @NotNull String quote, @NotNull Join join, @NotNull String jt, List onList) { + protected String concatJoinOn(@NotNull String sql, @NotNull String quote, @NotNull Join join, @NotNull String jt, List onList) { if (onList != null) { - SQLConfig jc = join.getJoinConfig(); + SQLConfig jc = join.getJoinConfig(); Map castMap = jc == null ? null : jc.getCast(); boolean first = true; @@ -5262,7 +5254,7 @@ protected String concatJoinOn(@NotNull String sql, @NotNull String quote, @NotNu String rt = on.getRelateType(); - String rk = quote + SQLConfig.getSQLAlias(on.getTargetTable(), on.getTargetAlias()) + quote + "." + quote + on.getTargetKey() + quote; + String rk = quote + SQLConfig.gainSQLAlias(on.getTargetTable(), on.getTargetAlias()) + quote + "." + quote + on.getTargetKey() + quote; if (StringUtil.isEmpty(rt, false)) { sql += (first ? ON : AND) + lk + (isNot ? " != " : " = ") + rk; @@ -5365,7 +5357,7 @@ else if ("{}".equals(rt) || "<>".equals(rt)) { } else { boolean find = false; - for (Join jn : joinList) { + for (Join jn : joinList) { if (tt.equals(jn.getTable()) && Objects.equals(ta, jn.getAlias())) { cast = getCast(); find = true; @@ -5386,26 +5378,26 @@ else if ("{}".equals(rt) || "<>".equals(rt)) { String itemKeyPath = isIn ? lk : rk; if (isPSQL()) { //operator does not exist: jsonb @> character varying "[" + c + "]"); - sql += (first ? ON : AND) + (isNot ? "( " : "") + getCondition(isNot, arrKeyPath + sql += (first ? ON : AND) + (isNot ? "( " : "") + gainCondition(isNot, arrKeyPath + " IS NOT NULL AND " + arrKeyPath + " @> " + itemKeyPath) + (isNot ? ") " : ""); } else if (isOracle() || isDameng() || isKingBase()) { - sql += (first ? ON : AND) + (isNot ? "( " : "") + getCondition(isNot, arrKeyPath + sql += (first ? ON : AND) + (isNot ? "( " : "") + gainCondition(isNot, arrKeyPath + " IS NOT NULL AND json_textcontains(" + arrKeyPath + ", '$', " + itemKeyPath + ")") + (isNot ? ") " : ""); } else if (isPresto() || isTrino()) { - sql += (first ? ON : AND) + (isNot ? "( " : "") + getCondition(isNot, arrKeyPath + sql += (first ? ON : AND) + (isNot ? "( " : "") + gainCondition(isNot, arrKeyPath + " IS NOT NULL AND json_array_contains(cast(" + arrKeyPath + " AS VARCHAR), " + itemKeyPath + ")") + (isNot ? ") " : ""); } else if (isClickHouse()) { - sql += (first ? ON : AND) + (isNot ? "( " : "") + getCondition(isNot, arrKeyPath + sql += (first ? ON : AND) + (isNot ? "( " : "") + gainCondition(isNot, arrKeyPath + " IS NOT NULL AND has(JSONExtractArrayRaw(assumeNotNull(" + arrKeyPath + "))" + ", " + itemKeyPath + ")") + (isNot ? ") " : ""); } else { - sql += (first ? ON : AND) + (isNot ? "( " : "") + getCondition(isNot, arrKeyPath + sql += (first ? ON : AND) + (isNot ? "( " : "") + gainCondition(isNot, arrKeyPath + " IS NOT NULL AND json_contains(" + arrKeyPath + (isBoolOrNum ? ", cast(" + itemKeyPath + " AS CHAR), '$')" : ", concat('\"', " + itemKeyPath + ", '\"'), '$')" @@ -5426,17 +5418,17 @@ else if (isClickHouse()) { return sql; } - protected void onJoinNotRelation(String sql, String quote, Join join, String table, List onList, On on) { + protected void onJoinNotRelation(String sql, String quote, Join join, String table, List onList, On on) { throw new UnsupportedOperationException("JOIN 已禁用 '!' 非逻辑连接符 !性能很差、需求极少,如要取消禁用可在后端重写相关方法!"); } - protected void onJoinComplexRelation(String sql, String quote, Join join, String table, List onList, On on) { + protected void onJoinComplexRelation(String sql, String quote, Join join, String table, List onList, On on) { throw new UnsupportedOperationException("JOIN 已禁用 $, ~, {}, <>, >, <, >=, <= 等复杂关联 !" + "性能很差、需求极少,默认只允许 = 等价关联,如要取消禁用可在后端重写相关方法!"); } - protected void onGetJoinString(Join join) throws UnsupportedOperationException { + protected void onGainJoinString(Join join) throws UnsupportedOperationException { } - protected void onGetCrossJoinString(Join join) throws UnsupportedOperationException { + protected void onGainCrossJoinString(Join join) throws UnsupportedOperationException { throw new UnsupportedOperationException("已禁用 * CROSS JOIN !性能很差、需求极少,如要取消禁用可在后端重写相关方法!"); } @@ -5449,29 +5441,30 @@ protected void onGetCrossJoinString(Join join) throws UnsupportedOperationExcept * @return * @throws Exception */ - public static SQLConfig newSQLConfig(RequestMethod method, String table, String alias - , JSONObject request, List joinList, boolean isProcedure, Callback callback) throws Exception { + public static , L extends List> SQLConfig newSQLConfig( + RequestMethod method, String table, String alias + , M request, List> joinList, boolean isProcedure, Callback callback) throws Exception { if (request == null) { // User:{} 这种空内容在查询时也有效 - throw new NullPointerException(TAG + ": newSQLConfig request == null!"); + throw new NullPointerException(TAG + ": newSQLConfig request == null!"); } - Boolean explain = request.getBoolean(KEY_EXPLAIN); + Boolean explain = getBoolean(request, KEY_EXPLAIN); if (explain != null && explain && Log.DEBUG == false) { // 不在 config.setExplain 抛异常,一方面处理更早性能更好,另一方面为了内部调用可以绕过这个限制 throw new UnsupportedOperationException("非DEBUG模式, 不允许传 " + KEY_EXPLAIN + " !"); } - String database = request.getString(KEY_DATABASE); - if (StringUtil.isEmpty(database, false) == false && DATABASE_LIST.contains(database) == false) { + String database = getString(request, KEY_DATABASE); + if (StringUtil.isNotEmpty(database, false) && DATABASE_LIST.contains(database) == false) { throw new UnsupportedDataTypeException("@database:value 中 value 错误,只能是 [" + StringUtil.get(DATABASE_LIST.toArray()) + "] 中的一种!"); } - String datasource = request.getString(KEY_DATASOURCE); - String namespace = request.getString(KEY_NAMESPACE); - String catalog = request.getString(KEY_CATALOG); - String schema = request.getString(KEY_SCHEMA); + String datasource = getString(request, KEY_DATASOURCE); + String namespace = getString(request, KEY_NAMESPACE); + String catalog = getString(request, KEY_CATALOG); + String schema = getString(request, KEY_SCHEMA); - SQLConfig config = callback.getSQLConfig(method, database, schema, datasource, table); + SQLConfig config = (SQLConfig) callback.getSQLConfig(method, database, schema, datasource, table); config.setAlias(alias); config.setDatabase(database); // 不删,后面表对象还要用的,必须放在 parseJoin 前 @@ -5509,7 +5502,7 @@ public static SQLConfig newSQLConfig(RequestMethod method, } } if (newIdIn.isEmpty()) { - throw new NotExistException(TAG + ": newSQLConfig idIn instanceof List >> 去掉无效 id 后 newIdIn.isEmpty()"); + throw new NotExistException(TAG + ": newSQLConfig idIn instanceof List >> 去掉无效 id 后 newIdIn.isEmpty()"); } idIn = newIdIn; @@ -5526,12 +5519,12 @@ public static SQLConfig newSQLConfig(RequestMethod method, if (id != null) { // null 无效 if (id instanceof Number) { if (((Number) id).longValue() <= 0) { // 一定没有值 - throw new NotExistException(TAG + ": newSQLConfig " + table + ".id <= 0"); + throw new NotExistException(TAG + ": newSQLConfig " + table + ".id <= 0"); } } else if (id instanceof String) { if (StringUtil.isEmpty(id, true)) { // 一定没有值 - throw new NotExistException(TAG + ": newSQLConfig StringUtil.isEmpty(" + table + ".id, true)"); + throw new NotExistException(TAG + ": newSQLConfig StringUtil.isEmpty(" + table + ".id, true)"); } } else if (id instanceof Subquery) {} @@ -5549,7 +5542,7 @@ else if (id instanceof Subquery) {} } } if (contains == false) { // empty有效 BaseModel.isEmpty(idIn) == false) { - throw new NotExistException(TAG + ": newSQLConfig idIn != null && (((List) idIn).contains(id) == false"); + throw new NotExistException(TAG + ": newSQLConfig idIn != null && (((List) idIn).contains(id) == false"); } } @@ -5571,7 +5564,7 @@ else if (id instanceof Subquery) {} } } if (newUserIdIn.isEmpty()) { - throw new NotExistException(TAG + ": newSQLConfig userIdIn instanceof List >> 去掉无效 userId 后 newIdIn.isEmpty()"); + throw new NotExistException(TAG + ": newSQLConfig userIdIn instanceof List >> 去掉无效 userId 后 newIdIn.isEmpty()"); } userIdIn = newUserIdIn; } @@ -5580,12 +5573,12 @@ else if (id instanceof Subquery) {} if (userId != null) { // null 无效 if (userId instanceof Number) { if (((Number) userId).longValue() <= 0) { // 一定没有值 - throw new NotExistException(TAG + ": newSQLConfig " + table + ".userId <= 0"); + throw new NotExistException(TAG + ": newSQLConfig " + table + ".userId <= 0"); } } else if (userId instanceof String) { if (StringUtil.isEmpty(userId, true)) { // 一定没有值 - throw new NotExistException(TAG + ": newSQLConfig StringUtil.isEmpty(" + table + ".userId, true)"); + throw new NotExistException(TAG + ": newSQLConfig StringUtil.isEmpty(" + table + ".userId, true)"); } } else if (userId instanceof Subquery) {} @@ -5603,32 +5596,32 @@ else if (userId instanceof Subquery) {} } } if (contains == false) { // empty有效 BaseModel.isEmpty(userIdIn) == false) { - throw new NotExistException(TAG + ": newSQLConfig userIdIn != null && (((List) userIdIn).contains(userId) == false"); + throw new NotExistException(TAG + ": newSQLConfig userIdIn != null && (((List) userIdIn).contains(userId) == false"); } } } // 对 id, id{}, userId, userId{} 处理,这些只要不为 null 就一定会作为 AND 条件 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - String role = request.getString(KEY_ROLE); - String cache = request.getString(KEY_CACHE); - Subquery from = (Subquery) request.get(KEY_FROM); - String column = request.getString(KEY_COLUMN); - String nulls = request.getString(KEY_NULL); - String cast = request.getString(KEY_CAST); - String combine = request.getString(KEY_COMBINE); - String group = request.getString(KEY_GROUP); + String role = getString(request, KEY_ROLE); + String cache = getString(request, KEY_CACHE); + Subquery from = (Subquery) request.get(KEY_FROM); + String column = getString(request, KEY_COLUMN); + String nulls = getString(request, KEY_NULL); + String cast = getString(request, KEY_CAST); + String combine = getString(request, KEY_COMBINE); + String group = getString(request, KEY_GROUP); Object having = request.get(KEY_HAVING); - String havingAnd = request.getString(KEY_HAVING_AND); - String sample = request.getString(KEY_SAMPLE); - String latest = request.getString(KEY_LATEST); - String partition = request.getString(KEY_PARTITION); - String fill = request.getString(KEY_FILL); - String order = request.getString(KEY_ORDER); + String havingAnd = getString(request, KEY_HAVING_AND); + String sample = getString(request, KEY_SAMPLE); + String latest = getString(request, KEY_LATEST); + String partition = getString(request, KEY_PARTITION); + String fill = getString(request, KEY_FILL); + String order = getString(request, KEY_ORDER); Object keyMap = request.get(KEY_KEY); - String raw = request.getString(KEY_RAW); - String json = request.getString(KEY_JSON); - String mthd = request.getString(KEY_METHOD); + String raw = getString(request, KEY_RAW); + String json = getString(request, KEY_JSON); + String mthd = getString(request, KEY_METHOD); try { // 强制作为条件且放在最前面优化性能 @@ -5744,7 +5737,7 @@ else if (userId instanceof Subquery) {} if (values == null || values.length != columns.length) { throw new Exception("服务器内部错误:\n" + TAG - + " newSQLConfig values == null || values.length != columns.length !"); + + " newSQLConfig values == null || values.length != columns.length !"); } column = (id == null ? "" : idKey + ",") + (userId == null ? "" : userIdKey + ",") @@ -5813,21 +5806,21 @@ else if (userId instanceof Subquery) {} Object deletedKey = accessFakeDeleteMap == null ? null : accessFakeDeleteMap.get(KEY_DELETED_KEY); boolean hasKey = deletedKey instanceof String && StringUtil.isNotEmpty(deletedKey, true); Object deletedValue = hasKey ? accessFakeDeleteMap.get(KEY_DELETED_VALUE) : null; - boolean containNotDeletedValue = hasKey ? accessFakeDeleteMap.containsKey(KEY_NOT_DELETED_VALUE) : false; + boolean containNotDeletedValue = hasKey && accessFakeDeleteMap.containsKey(KEY_NOT_DELETED_VALUE); Object notDeletedValue = containNotDeletedValue ? accessFakeDeleteMap.get(KEY_NOT_DELETED_VALUE) : null; if (deletedValue != null || containNotDeletedValue) { boolean isFakeDelete = true; if (from != null) { // 兼容 JOIN 外层 SELECT 重复生成 deletedKey - SQLConfig cfg = from.getConfig(); + SQLConfig cfg = from.gainConfig(); if (cfg != null && StringUtil.equals(table, cfg.getTable())) { isFakeDelete = false; } - List jl = isFakeDelete && cfg != null ? cfg.getJoinList() : null; + List> jl = isFakeDelete && cfg != null ? cfg.getJoinList() : null; if (jl != null) { - for (Join join : jl) { + for (Join join : jl) { if (join != null && StringUtil.equals(table, join.getTable())) { isFakeDelete = false; break; @@ -5906,11 +5899,11 @@ else if (w.startsWith("!")) { // 可重写回调方法自定义处理 // 动态设置的场景似乎很少,而且去掉后不方便用户排错! // 去掉判断,有时候不在没关系,如果是对增删改等非开放请求强制要求传对应的条件,可以用 Operation.NECESSARY - if (request.containsKey(w) == false) { // 和 request.get(w) == null 没区别,前面 Parser 已经过滤了 null + if (request.containsKey(w) == false) { // 和 request.get(w) == null 没区别,前面 Parser 已经过滤了 null // throw new IllegalArgumentException(table + ":{} 里的 @combine:value 中的value里 " + ws[i] + " 对应的 " + w + " 不在它里面!"); callback.onMissingKey4Combine(table, request, combine, ws[i], w); if (config instanceof AbstractSQLConfig) { - ((AbstractSQLConfig) config).putWarnIfNeed(KEY_COMBINE, table + ":{} 里的 @combine:value 中的 value 里 " + ((AbstractSQLConfig) config).putWarnIfNeed(KEY_COMBINE, table + ":{} 里的 @combine:value 中的 value 里 " + ws[i] + " 对应的条件 " + w + ":value 中 value 必须存在且不能为 null!"); } } @@ -5943,7 +5936,7 @@ else if (w.startsWith("!")) { } else if (whereList.contains(key)) { tableWhere.put(key, value); } else { - tableContent.put(key, value); // 一样 instanceof JSONArray ? JSON.toJSONString(value) : value); + tableContent.put(key, value); // 一样 instanceof List ? JSON.toJSONString(value) : value); } } @@ -5995,7 +5988,7 @@ else if (w.startsWith("!")) { boolean containColumnRaw = rawList != null && rawList.contains(KEY_COLUMN); String rawColumnSQL = null; if (containColumnRaw) { - rawColumnSQL = config.getRawSQL(KEY_COLUMN, column); + rawColumnSQL = config.gainRawSQL(KEY_COLUMN, column); if (rawColumnSQL != null) { cs.add(rawColumnSQL); } @@ -6008,7 +6001,7 @@ else if (w.startsWith("!")) { if (fks != null) { for (String fk : fks) { if (containColumnRaw) { - String rawSQL = config.getRawSQL(KEY_COLUMN, fk); + String rawSQL = config.gainRawSQL(KEY_COLUMN, fk); if (rawSQL != null) { cs.add(rawSQL); continue; @@ -6081,13 +6074,13 @@ else if (w.startsWith("!")) { } } } - else if (newHaving instanceof JSONObject) { + else if (newHaving instanceof Map) { if (isHavingAnd) { throw new IllegalArgumentException(table + ":{ " + havingKey + ":value } 里的 value 类型不合法!" + "@having&:value 中 value 只能是 String,@having:value 中 value 只能是 String 或 JSONObject !"); } - JSONObject havingObj = (JSONObject) newHaving; + JSONObject havingObj = new JSONObject(newHaving); Set> havingSet = havingObj.entrySet(); for (Entry entry : havingSet) { String k = entry == null ? null : entry.getKey(); @@ -6271,12 +6264,12 @@ else if (keyMap != null) { * @return * @throws Exception */ - public static SQLConfig parseJoin(RequestMethod method, SQLConfig config - , List joinList, Callback callback) throws Exception { + public static , L extends List> SQLConfig parseJoin( + RequestMethod method, SQLConfig config, List> joinList, Callback callback) throws Exception { boolean isQuery = RequestMethod.isQueryMethod(method); config.setKeyPrefix(isQuery && config.isMain() == false); - //TODO 解析出 SQLConfig 再合并 column, order, group 等 + //TODO 解析出 SQLConfig 再合并 column, order, group 等 if (joinList == null || joinList.isEmpty() || RequestMethod.isQueryMethod(method) == false) { return config; } @@ -6284,15 +6277,15 @@ public static SQLConfig parseJoin(RequestMethod method, SQ String table; String alias; - for (Join j : joinList) { - table = j.getTable(); - alias = j.getAlias(); + for (Join join : joinList) { + table = join.getTable(); + alias = join.getAlias(); //JOIN子查询不能设置LIMIT,因为ON关系是在子查询后处理的,会导致结果会错误 - SQLConfig joinConfig = newSQLConfig(method, table, alias, j.getRequest(), null, false, callback); - SQLConfig cacheConfig = j.canCacheViceTable() == false ? null : newSQLConfig(method, table, alias - , j.getRequest(), null, false, callback).setCount(j.getCount()); + SQLConfig joinConfig = newSQLConfig(method, table, alias, join.getRequest(), null, false, callback); + SQLConfig cacheConfig = join.canCacheViceTable() == false ? null : newSQLConfig(method, table, alias + , join.getRequest(), null, false, callback).setCount(join.getCount()); - if (j.isAppJoin() == false) { //除了 @ APP JOIN,其它都是 SQL JOIN,则副表要这样配置 + if (join.isAppJoin() == false) { //除了 @ APP JOIN,其它都是 SQL JOIN,则副表要这样配置 if (joinConfig.getDatabase() == null) { joinConfig.setDatabase(config.getDatabase()); //解决主表 JOIN 副表,引号不一致 } @@ -6308,21 +6301,20 @@ else if (joinConfig.getDatabase().equals(config.getDatabase()) == false) { cacheConfig.setDatabase(joinConfig.getDatabase()).setSchema(joinConfig.getSchema()); //解决主表 JOIN 副表,引号不一致 } - if (isQuery) { config.setKeyPrefix(true); } joinConfig.setMain(false).setKeyPrefix(true); - if (j.getOuter() != null) { - SQLConfig outerConfig = newSQLConfig(method, table, alias, j.getOuter(), null, false, callback); + if (join.getOuter() != null) { + SQLConfig outerConfig = newSQLConfig(method, table, alias, join.getOuter(), null, false, callback); outerConfig.setMain(false) .setKeyPrefix(true) .setDatabase(joinConfig.getDatabase()) .setSchema(joinConfig.getSchema()); //解决主表 JOIN 副表,引号不一致 - j.setOuterConfig(outerConfig); + join.setOuterConfig(outerConfig); } } @@ -6330,7 +6322,7 @@ else if (joinConfig.getDatabase().equals(config.getDatabase()) == false) { /* SELECT count(*) AS count FROM sys.Moment AS Moment LEFT JOIN ( SELECT count(*) AS count FROM sys.Comment ) AS Comment ON Comment.momentId = Moment.id LIMIT 1 OFFSET 0 */ if (RequestMethod.isHeadMethod(method, true)) { - List onList = j.getOnList(); + List onList = join.getOnList(); List column = onList == null ? null : new ArrayList<>(onList.size()); if (column != null) { for (On on : onList) { @@ -6347,8 +6339,8 @@ LEFT JOIN ( SELECT count(*) AS count FROM sys.Comment ) AS Comment ON Comment.m } } - j.setJoinConfig(joinConfig); - j.setCacheConfig(cacheConfig); + join.setJoinConfig(joinConfig); + join.setCacheConfig(cacheConfig); } config.setJoinList(joinList); @@ -6366,9 +6358,9 @@ LEFT JOIN ( SELECT count(*) AS count FROM sys.Comment ) AS Comment ON Comment.m * @param saveLogic 保留逻辑运算符 & | ! * @return */ - public static String getRealKey(RequestMethod method, String originKey + public static String gainRealKey(RequestMethod method, String originKey , boolean isTableKey, boolean saveLogic) throws Exception { - return getRealKey(method, originKey, isTableKey, saveLogic, true); + return gainRealKey(method, originKey, isTableKey, saveLogic, true); } /**获取客户端实际需要的key * @param method @@ -6378,7 +6370,7 @@ public static String getRealKey(RequestMethod method, String originKey * @param verifyName 验证key名是否符合代码变量/常量名 * @return */ - public static String getRealKey(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)) { @@ -6498,7 +6490,7 @@ else if (key.endsWith("-")) {//缩减,PUT查询时处理 } - public static interface IdCallback { + public static interface IdCallback { /**为 post 请求新建 id, 只能是 Long 或 String * @param method * @param database @@ -6526,22 +6518,22 @@ public static interface IdCallback { String getUserIdKey(String database, String schema, String datasource, String table); } - public static interface Callback extends IdCallback { - /**获取 SQLConfig 的实例 + public static interface Callback, L extends List> extends IdCallback { + /**获取 SQLConfig 的实例 * @param method * @param database * @param schema * @param table * @return */ - SQLConfig getSQLConfig(RequestMethod method, String database, String schema, String datasource, String table); + SQLConfig getSQLConfig(RequestMethod method, String database, String schema, String datasource, String table); /**combine 里的 key 在 request 中 value 为 null 或不存在,即 request 中缺少用来作为 combine 条件的 key: value * @param combine * @param key * @param request */ - void onMissingKey4Combine(String name, JSONObject request, String combine, String item, String key) throws Exception; + void onMissingKey4Combine(String name, M request, String combine, String item, String key) throws Exception; } public static Long LAST_ID; @@ -6549,7 +6541,7 @@ public static interface Callback extends IdCallback { LAST_ID = System.currentTimeMillis(); } - public static abstract class SimpleCallback implements Callback { + public static abstract class SimpleCallback, L extends List> implements Callback { @SuppressWarnings("unchecked") @Override @@ -6574,7 +6566,7 @@ public String getUserIdKey(String database, String schema, String datasource, St } @Override - public void onMissingKey4Combine(String name, JSONObject request, String combine, String item, String key) throws Exception { + public void onMissingKey4Combine(String name, M request, String combine, String item, String key) throws Exception { if (ALLOW_MISSING_KEY_4_COMBINE) { return; } @@ -6607,24 +6599,4 @@ private static boolean isKeyInCombineExpr(String combineExpr, String key) { } - public List getWithAsExprSqlList() { - return withAsExprSqlList; - } - private void clearWithAsExprListIfNeed() { - // mysql8版本以上,子查询支持with as表达式 - if(this.isMySQL() && this.getDBVersionNums()[0] >= 8) { - this.withAsExprSqlList = new ArrayList<>(); - } - } - - @Override - public List getWithAsExprPreparedValueList() { - return this.withAsExprPreparedValueList; - } - - @Override - public AbstractSQLConfig setWithAsExprPreparedValueList(List list) { - this.withAsExprPreparedValueList = list; - return this; - } } diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java index 2165c3b05..ce64cb3aa 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java @@ -8,8 +8,6 @@ import apijson.*; import apijson.orm.Join.On; import apijson.orm.exception.NotExistException; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; import java.io.BufferedReader; import java.math.BigDecimal; @@ -27,20 +25,21 @@ /**executor for query(read) or update(write) MySQL database * @author Lemon */ -public abstract class AbstractSQLExecutor implements SQLExecutor { +public abstract class AbstractSQLExecutor, L extends List> + implements SQLExecutor { private static final String TAG = "AbstractSQLExecutor"; //是否返回 值为null的字段 public static boolean ENABLE_OUTPUT_NULL_COLUMN = false; public static String KEY_RAW_LIST = "@RAW@LIST"; // 避免和字段命名冲突,不用 $RAW@LIST$ 是因为 $ 会在 fastjson 内部转义,浪费性能 public static String KEY_VICE_ITEM = "@VICE@ITEM"; // 避免和字段命名冲突,不用 $VICE@LIST$ 是因为 $ 会在 fastjson 内部转义,浪费性能 - private Parser parser; + private Parser parser; @Override - public Parser getParser() { + public Parser getParser() { return parser; } @Override - public AbstractSQLExecutor setParser(Parser parser) { + public AbstractSQLExecutor setParser(Parser parser) { this.parser = parser; return this; } @@ -78,15 +77,15 @@ public long getSqlResultDuration() { /** * 缓存 Map */ - protected Map> cacheMap = new HashMap<>(); + protected Map> cacheMap = new HashMap<>(); /**保存缓存 * @param sql key * @param list value - * @param config 一般主表 SQLConfig 不为 null,JOIN 副表的为 null + * @param config 一般主表 SQLConfig 不为 null,JOIN 副表的为 null */ @Override - public void putCache(String sql, List list, SQLConfig config) { + public void putCache(String sql, List list, SQLConfig config) { if (sql == null || list == null) { // 空 list 有效,说明查询过 sql 了 || list.isEmpty()) { Log.i(TAG, "saveList sql == null || list == null >> return;"); return; @@ -97,33 +96,33 @@ public void putCache(String sql, List list, SQLConfig config) { /**获取缓存 * @param sql key - * @param config 一般主表 SQLConfig 不为 null,JOIN 副表的为 null + * @param config 一般主表 SQLConfig 不为 null,JOIN 副表的为 null */ @Override - public List getCache(String sql, SQLConfig config) { + public List getCache(String sql, SQLConfig config) { return cacheMap.get(sql); } /**获取缓存 * @param sql key * @param position - * @param config 一般主表 SQLConfig 不为 null,JOIN 副表的为 null + * @param config 一般主表 SQLConfig 不为 null,JOIN 副表的为 null * @return */ @Override - public JSONObject getCacheItem(String sql, int position, SQLConfig config) { - List list = getCache(sql, config); + public M getCacheItem(String sql, int position, SQLConfig config) { + List list = getCache(sql, config); return getCacheItem(list, position, config); } - public JSONObject getCacheItem(List list, int position, SQLConfig config) { + public M getCacheItem(List list, int position, SQLConfig config) { // 只要 list 不为 null,则如果 list.get(position) == null,则返回 {} ,避免再次 SQL 查询 if (list == null) { return null; } - JSONObject result = position >= list.size() ? null : list.get(position); - return result != null ? result : new JSONObject(); + M result = position >= list.size() ? null : list.get(position); + return result != null ? result : JSON.createJSONObject(); } @@ -135,7 +134,7 @@ public JSONObject getCacheItem(List list, int position, SQLConfig * @param config */ @Override - public void removeCache(String sql, SQLConfig config) { + public void removeCache(String sql, SQLConfig config) { if (sql == null) { Log.i(TAG, "removeList sql == null >> return;"); return; @@ -167,9 +166,9 @@ public ResultSet execute(@NotNull Statement statement, String sql) throws Except * @throws Exception */ @Override - public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) throws Exception { + public M execute(@NotNull SQLConfig config, boolean unknownType) throws Exception { long executedSQLStartTime = System.currentTimeMillis(); - final String sql = config.getSQL(false); + final String sql = config.gainSQL(false); if (StringUtil.isEmpty(sql, true)) { Log.e(TAG, "execute StringUtil.isEmpty(sql, true) >> return null;"); @@ -180,7 +179,7 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) thr boolean isHead = RequestMethod.isHeadMethod(config.getMethod(), true); final int position = config.getPosition(); - JSONObject result; + M result; if (isExplain == false) { generatedSQLCount ++; @@ -196,8 +195,8 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) thr + "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); ResultSet rs = null; - List resultList = null; - Map childMap = null; + List resultList = null; + Map childMap = null; Map keyMap = null; try { @@ -213,7 +212,7 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) thr executedSQLDuration += System.currentTimeMillis() - executedSQLStartTime; } - result = new JSONObject(true); + result = JSON.createJSONObject(); result.put(JSONResponse.KEY_COUNT, updateCount); result.put("update", updateCount >= 0); //导致后面 rs.getMetaData() 报错 Operation not allowed after ResultSet closed result.put("moreResults", statement.getMoreResults()); @@ -238,7 +237,7 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) thr } // updateCount>0时收集结果。例如更新操作成功时,返回count(affected rows)、id字段 - result = AbstractParser.newSuccessResult(); // TODO 对 APIAuto 及其它现有的前端/客户端影响比较大,暂时还是返回 code 和 msg,5.0 再移除 new JSONObject(true); + result = getParser().newSuccessResult(); // TODO 对 APIAuto 及其它现有的前端/客户端影响比较大,暂时还是返回 code 和 msg,5.0 再移除 JSON.createJSONObject(); //id,id{}至少一个会有,一定会返回,不用抛异常来阻止关联写操作时前面错误导致后面无条件执行! result.put(JSONResponse.KEY_COUNT, updateCount);//返回修改的记录数 @@ -253,7 +252,7 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) thr if (method == RequestMethod.PUT || method == RequestMethod.DELETE) { config.setMethod(RequestMethod.GET); - removeCache(config.getSQL(false), config); + removeCache(config.gainSQL(false), config); config.setMethod(method); } @@ -263,7 +262,7 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) thr case GETS: case HEAD: case HEADS: - List cache = getCache(sql, config); + List cache = getCache(sql, config); result = getCacheItem(cache, position, config); Log.i(TAG, ">>> execute result = getCache('" + sql + "', " + position + ") = " + result); if (result != null) { @@ -297,10 +296,10 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) thr if (isExplain == false && isHead) { if (rs.next() == false) { - return AbstractParser.newErrorResult(new SQLException("数据库错误, rs.next() 失败!")); + return getParser().newErrorResult(new SQLException("数据库错误, rs.next() 失败!")); } - result = AbstractParser.newSuccessResult(); + result = getParser().newSuccessResult(); // 兼容nosql,比如 elasticSearch-sql if(config.isElasticsearch()) { result.put(JSONResponse.KEY_COUNT, rs.getObject(1)); @@ -389,7 +388,7 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) thr // WHERE id = ? AND ... 或 WHERE ... AND id = ? 强制排序 remove 再 put,还是重新 getSQL吧 - List joinList = config.getJoinList(); + List> joinList = config.getJoinList(); boolean hasJoin = config.hasJoin() && joinList != null && ! joinList.isEmpty(); // 直接用数组存取更快 Map columnIndexAndJoinMap = isExplain || ! hasJoin ? null : new HashMap<>(length); @@ -409,9 +408,9 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) thr index ++; Log.d(TAG, "\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n execute while (rs.next()){ index = " + index + "\n\n"); - JSONObject item = new JSONObject(true); - JSONObject viceItem = null; - JSONObject curItem = item; + M item = JSON.createJSONObject(); + M viceItem = null; + M curItem = item; boolean isMain = true; boolean reseted = false; @@ -427,9 +426,9 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) thr // 为什么 isExplain == false 不用判断?因为所有字段都在一张 Query Plan 表 if (index <= 0 && columnIndexAndJoinMap != null) { // && viceColumnStart > length) { - SQLConfig curConfig = curJoin == null || ! curJoin.isSQLJoin() ? null : curJoin.getCacheConfig(); + SQLConfig curConfig = curJoin == null || ! curJoin.isSQLJoin() ? null : curJoin.getCacheConfig(); List curColumn = curConfig == null ? null : curConfig.getColumn(); - String sqlTable = curConfig == null ? null : curConfig.getSQLTable(); + String sqlTable = curConfig == null ? null : curConfig.gainSQLTable(); String sqlAlias = curConfig == null ? null : curConfig.getAlias(); List column = config.getColumn(); @@ -461,7 +460,7 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) thr ) { // Presto 等引擎 JDBC 返回 rsmd.getTableName(i) 为空,主表如果一个字段都没有会导致 APISJON 主副表所有字段都不返回 sqlTable = null; if (reseted) { - SQLConfig lastCfg = lastJoin == null ? null : lastJoin.getCacheConfig(); + SQLConfig lastCfg = lastJoin == null ? null : lastJoin.getCacheConfig(); List lastColumn = lastCfg == null ? null : lastCfg.getColumn(); lastViceTableStart ++; @@ -469,12 +468,12 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) thr } else if (isMain) { for (int j = 0; j < joinList.size(); j++) { - Join join = joinList.get(j); - SQLConfig cfg = join == null || ! join.isSQLJoin() ? null : join.getJoinConfig(); + Join join = joinList.get(j); + SQLConfig cfg = join == null || ! join.isSQLJoin() ? null : join.getJoinConfig(); List c = cfg == null ? null : cfg.getColumn(); if (cfg != null) { - sqlTable = cfg.getSQLTable(); + sqlTable = cfg.gainSQLTable(); sqlAlias = cfg.getAlias(); lastViceTableStart = j; // 避免后面的空 @column 表内字段被放到之前的空 @column 表 lastViceColumnStart = i + 1; @@ -501,8 +500,8 @@ else if (isMain) { int nextViceColumnStart = lastViceColumnStart; // 主表没有 @column 时会偏小 lastViceColumnStart int joinCount = joinList.size(); for (int j = lastViceTableStart; j < joinCount; j++) { // 查找副表 @column,定位字段所在表 - Join join = joinList.get(j); - SQLConfig cfg = join == null || ! join.isSQLJoin() ? null : join.getJoinConfig(); + Join join = joinList.get(j); + SQLConfig cfg = join == null || ! join.isSQLJoin() ? null : join.getJoinConfig(); List c = cfg == null ? null : cfg.getColumn(); nextViceColumnStart += (c != null && ! c.isEmpty() ? @@ -512,7 +511,7 @@ else if (isMain) { ) ); if (i < nextViceColumnStart) { // 导致只 JOIN 一张副表时主表数据放到副表 || j >= joinCount - 1) { - sqlTable = cfg.getSQLTable(); + sqlTable = cfg.gainSQLTable(); sqlAlias = cfg.getAlias(); lastViceTableStart = j; // 避免后面的空 @column 表内字段被放到之前的空 @column 表 @@ -546,9 +545,9 @@ else if (isMain) { if (toFindJoin) { // 找到对应的副表 JOIN 配置 for (int j = lastViceTableStart; j < joinList.size(); j++) { // 查找副表 @column,定位字段所在表 Join join = joinList.get(j); - SQLConfig cfg = join == null || ! join.isSQLJoin() ? null : join.getJoinConfig(); + SQLConfig cfg = join == null || ! join.isSQLJoin() ? null : join.getJoinConfig(); - if (cfg != null && StringUtil.equalsIgnoreCase(sqlTable, cfg.getSQLTable()) + if (cfg != null && StringUtil.equalsIgnoreCase(sqlTable, cfg.gainSQLTable()) ) { // FIXME 导致副表字段错放到主表 && StringUtil.equals(sqlAlias, cfg.getAlias())) { lastViceTableStart = j; // 避免后面的空 @column 表内字段被放到之前的空 @column 表 @@ -591,14 +590,14 @@ else if (isMain) { // 如果是主表则直接用主表对应的 item,否则缓存副表数据到 childMap Join prevJoin = columnIndexAndJoinMap == null || i < 2 ? null : columnIndexAndJoinMap[i - 2]; if (curJoin != prevJoin) { // 前后字段不在同一个表对象,即便后面出现 null,也不该是主表数据,而是逻辑 bug 导致 - SQLConfig viceConfig = curJoin != null && curJoin.isSQLJoin() ? curJoin.getCacheConfig() : null; + SQLConfig viceConfig = curJoin != null && curJoin.isSQLJoin() ? curJoin.getCacheConfig() : null; boolean hasPK = false; if (viceConfig != null) { //FIXME 只有和主表关联才能用 item,否则应该从 childMap 查其它副表数据 List onList = curJoin.getOnList(); int size = onList == null ? 0 : onList.size(); if (size > 0) { String idKey = viceConfig.getIdKey(); - String tblKey = config.getTableKey(); + String tblKey = config.gainTableKey(); for (int j = size - 1; j >= 0; j--) { On on = onList.get(j); String ok = on == null ? null : on.getOriginKey(); @@ -609,7 +608,7 @@ else if (isMain) { String k = ok.substring(0, ok.length() - 1); String ttk = on.getTargetTableKey(); - JSONObject target = StringUtil.equals(ttk, tblKey) ? item : (viceItem == null ? null : viceItem.getJSONObject(ttk)); + M target = StringUtil.equals(ttk, tblKey) ? item : (viceItem == null ? null : JSON.get(viceItem, ttk)); Object v = target == null ? null : target.get(on.getTargetKey()); hasPK = hasPK || (k.equals(idKey) && v != null); @@ -625,21 +624,21 @@ else if (isMain) { else if (curJoin.isOuterJoin() || curJoin.isAntiJoin()) { Log.i(TAG, "execute curJoin.isOuterJoin() || curJoin.isAntiJoin() >> item = null; >> "); curItem = null; // 肯定没有数据,缓存也无意义 - // 副表是按常规条件查询,缓存会导致其它同表同条件对象查询结果集为空 childMap.put(viceSql, new JSONObject()); // 缓存固定空数据,避免后续多余查询 + // 副表是按常规条件查询,缓存会导致其它同表同条件对象查询结果集为空 childMap.put(viceSql, JSON.createJSONObject()); // 缓存固定空数据,避免后续多余查询 } else { - String viceName = viceConfig.getTableKey(); + String viceName = viceConfig.gainTableKey(); if (viceItem == null) { - viceItem = new JSONObject(true); + viceItem = JSON.createJSONObject(); } - curItem = viceItem.getJSONObject(viceName); + curItem = JSON.get(viceItem, viceName); - String viceSql = hasPK ? viceConfig.getSQL(false) : null; // TODO 在 SQLConfig 缓存 SQL,减少大量的重复生成 - JSONObject curCache = hasPK ? childMap.get(viceSql) : null; + String viceSql = hasPK ? viceConfig.gainSQL(false) : null; // TODO 在 SQLConfig 缓存 SQL,减少大量的重复生成 + M curCache = hasPK ? childMap.get(viceSql) : null; if (curItem == null || curItem.isEmpty()) { - // 导致前面判断重复 key 出错 curItem = curCache != null ? curCache : new JSONObject(true); - curItem = new JSONObject(true); + // 导致前面判断重复 key 出错 curItem = curCache != null ? curCache : JSON.createJSONObject(); + curItem = JSON.createJSONObject(); viceItem.put(viceName, curItem); if (hasPK && curCache == null) { childMap.put(viceSql, curItem); @@ -658,7 +657,7 @@ else if (hasPK) { } } - curItem = onPutColumn(config, rs, rsmd, index, curItem, i, curJoin, childMap, keyMap); // isExplain == false && hasJoin && i >= viceColumnStart ? childMap : null); + curItem = (M) onPutColumn(config, rs, rsmd, index, curItem, i, curJoin, childMap, keyMap); // isExplain == false && hasJoin && i >= viceColumnStart ? childMap : null); } if (viceItem != null) { @@ -689,10 +688,10 @@ else if (hasPK) { if (unknownType || isExplain) { if (isExplain) { if (result == null) { - result = new JSONObject(true); + result = JSON.createJSONObject(); } config.setExplain(false); - result.put("sql", config.getSQL(false)); + result.put("sql", config.gainSQL(false)); config.setExplain(isExplain); } result.put("list", resultList); @@ -706,31 +705,31 @@ else if (hasPK) { if (isHead == false) { // @ APP JOIN 查询副表并缓存到 childMap <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - Map> appJoinChildMap = new HashMap<>(); + Map> appJoinChildMap = new HashMap<>(); childMap.forEach((viceSql, item) -> appJoinChildMap.put(viceSql, Arrays.asList(item))); executeAppJoin(config, resultList, appJoinChildMap, keyMap); // @ APP JOIN 查询副表并缓存到 childMap >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //子查询 SELECT Moment.*, Comment.id 中的 Comment 内字段 - Set>> set = appJoinChildMap.entrySet(); + Set>> set = appJoinChildMap.entrySet(); // - for (Entry> entry : set) { + for (Entry> entry : set) { putCache(entry.getKey(), entry.getValue(), null); } Log.i(TAG, ">>> execute putCache('" + sql + "', resultList); resultList.size() = " + resultList.size()); - // 数组主表对象额外一次返回全部,方便 Parser 缓存来提高性能 + // 数组主表对象额外一次返回全部,方便 Parser 缓存来提高性能 - result = position >= resultList.size() ? new JSONObject() : resultList.get(position); + result = position >= resultList.size() ? JSON.createJSONObject() : resultList.get(position); if (position == 0 && resultList.size() > 1 && result != null && result.isEmpty() == false) { // 不是 main 不会直接执行,count=1 返回的不会超过 1 && config.isMain() && config.getCount() != 1 Log.i(TAG, ">>> execute position == 0 && resultList.size() > 1 && result != null && result.isEmpty() == false" - + " >> result = new JSONObject(result); result.put(KEY_RAW_LIST, resultList);"); + + " >> result = JSON.createJSONObject(result); result.put(KEY_RAW_LIST, resultList);"); - result = new JSONObject(result); + result = (M) JSON.createJSONObject(result); result.put(KEY_RAW_LIST, resultList); } } @@ -750,17 +749,17 @@ else if (hasPK) { * @param childMap * @throws Exception */ - protected void executeAppJoin(SQLConfig config, List resultList, Map> childMap, Map keyMap) throws Exception { - List joinList = config.getJoinList(); + protected void executeAppJoin(SQLConfig config, List resultList, Map> childMap, Map keyMap) throws Exception { + List> joinList = config.getJoinList(); if (joinList != null) { - for (Join join : joinList) { + for (Join join : joinList) { if (join.isAppJoin() == false) { Log.i(TAG, "executeAppJoin for (Join j : joinList) >> j.isAppJoin() == false >> continue;"); continue; } - SQLConfig cc = join.getCacheConfig(); //这里用config改了getSQL后再还原很麻烦,所以提前给一个config2更好 + SQLConfig cc = join.getCacheConfig(); //这里用config改了getSQL后再还原很麻烦,所以提前给一个config2更好 if (cc == null) { if (Log.DEBUG) { throw new NullPointerException("服务器内部错误, executeAppJoin cc == null ! 导致不能缓存 @ APP JOIN 的副表数据!"); @@ -768,7 +767,7 @@ protected void executeAppJoin(SQLConfig config, List resultList, continue; } - SQLConfig jc = join.getJoinConfig(); + SQLConfig jc = join.getJoinConfig(); List onList = join.getOnList(); On on = onList == null || onList.isEmpty() ? null : onList.get(0); // APP JOIN 应该有且只有一个 ON 条件 @@ -785,7 +784,7 @@ protected void executeAppJoin(SQLConfig config, List resultList, List targetValueList = new ArrayList<>(); for (int i = 0; i < resultList.size(); i++) { - JSONObject mainTable = resultList.get(i); + M mainTable = resultList.get(i); Object targetValue = mainTable == null ? null : mainTable.get(on.getTargetKey()); if (targetValue != null && targetValueList.contains(targetValue) == false) { @@ -825,14 +824,14 @@ protected void executeAppJoin(SQLConfig config, List resultList, // } boolean prepared = jc.isPrepared(); - String sql = jc.getSQL(false); + String sql = jc.gainSQL(false); if (StringUtil.isEmpty(sql, true)) { throw new NullPointerException(TAG + ".executeAppJoin StringUtil.isEmpty(sql, true) >> return null;"); } String sql2 = null; - if (childCount > 0 && isOne2Many && (jc.isMySQL() == false || jc.getDBVersionNums()[0] >= 8)) { + if (childCount > 0 && isOne2Many && (jc.isMySQL() == false || jc.gainDBVersionNums()[0] >= 8)) { // 加 row_number 字段并不会导致 count 等聚合函数统计出错,结果偏大,SQL JOIN 才会,之前没发现是因为缓存失效 bug // boolean noAggrFun = true; // List column = jc.getColumn(); @@ -852,10 +851,10 @@ protected void executeAppJoin(SQLConfig config, List resultList, // // if (noAggrFun) { // 加 row_number 字段会导致 count 等聚合函数统计出错,结果偏大? String q = jc.getQuote(); - sql2 = prepared && jc.isTDengine() == false ? jc.getSQL(true) : sql; + sql2 = prepared && jc.isTDengine() == false ? jc.gainSQL(true) : sql; String prefix = "SELECT * FROM("; - String rnStr = ", row_number() OVER (PARTITION BY " + q + key + q + ((AbstractSQLConfig) jc).getOrderString(true) + ") _row_num_ FROM "; + String rnStr = ", row_number() OVER (PARTITION BY " + q + key + q + ((AbstractSQLConfig) jc).gainOrderString(true) + ") _row_num_ FROM "; String suffix = ") _t WHERE ( (_row_num_ <= " + childCount + ") )" + (allChildCount > 0 ? " LIMIT " + allChildCount : ""); sql2 = prefix @@ -910,7 +909,7 @@ protected void executeAppJoin(SQLConfig config, List resultList, index ++; Log.d(TAG, "\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n executeAppJoin while (rs.next()){ index = " + index + "\n\n"); - JSONObject result = new JSONObject(true); + M result = JSON.createJSONObject(); for (int i = 1; i <= length; i++) { result = onPutColumn(jc, rs, rsmd, index, result, i, null, null, keyMap); @@ -923,8 +922,8 @@ protected void executeAppJoin(SQLConfig config, List resultList, //TODO 兼容复杂关联 cc.putWhere(key, result.get(key), true); // APP JOIN 应该有且只有一个 ON 条件 - String cacheSql = cc.getSQL(false); - List results = childMap.get(cacheSql); + String cacheSql = cc.gainSQL(false); + List results = childMap.get(cacheSql); if (results == null || skipMap.get(cacheSql) == null) { // 避免添加重复数据 results = new ArrayList<>(childCount); @@ -968,15 +967,15 @@ protected void executeAppJoin(SQLConfig config, List resultList, * @param config * @param rs * @param rsmd - * @param tablePosition 从0开始 + * @param row 从0开始 * @param table * @param columnIndex 从1开始 * @param childMap * @return result * @throws Exception */ - protected JSONObject onPutColumn(@NotNull SQLConfig config, @NotNull ResultSet rs, @NotNull ResultSetMetaData rsmd - , final int row, @NotNull JSONObject table, final int columnIndex, Join join, Map childMap + protected M onPutColumn(@NotNull SQLConfig config, @NotNull ResultSet rs, @NotNull ResultSetMetaData rsmd + , final int row, @NotNull M table, final int columnIndex, Join join, Map childMap , Map keyMap) throws Exception { if (table == null) { // 对应副表 viceSql 不能生成正常 SQL, 或者是 ! - Outer, ( - ANTI JOIN 的副表这种不需要缓存及返回的数据 Log.i(TAG, "onPutColumn table == null >> return table;"); @@ -1010,8 +1009,8 @@ protected JSONObject onPutColumn(@NotNull SQLConfig config, @NotNull ResultSe * @return * @throws SQLException */ - protected boolean isHideColumn(@NotNull SQLConfig config, @NotNull ResultSet rs, @NotNull ResultSetMetaData rsmd - , final int row, @NotNull JSONObject table, final int columnIndex, Map childMap + protected boolean isHideColumn(@NotNull SQLConfig config, @NotNull ResultSet rs, @NotNull ResultSetMetaData rsmd + , final int row, @NotNull M table, final int columnIndex, Map childMap , Map keyMap) throws SQLException { return rsmd.getColumnName(columnIndex).startsWith("_"); } @@ -1025,15 +1024,15 @@ protected boolean isHideColumn(@NotNull SQLConfig config, @NotNull ResultSet * @param table * @return resultList */ - protected List onPutTable(@NotNull SQLConfig config, @NotNull ResultSet rs, @NotNull ResultSetMetaData rsmd - , @NotNull List resultList, int position, @NotNull JSONObject table) { + protected List onPutTable(@NotNull SQLConfig config, @NotNull ResultSet rs, @NotNull ResultSetMetaData rsmd + , @NotNull List resultList, int position, @NotNull M table) { resultList.add(table); return resultList; } - protected String getKey(@NotNull SQLConfig config, @NotNull ResultSet rs, @NotNull ResultSetMetaData rsmd - , final int row, @NotNull JSONObject table, final int columnIndex, Map childMap + protected String getKey(@NotNull SQLConfig config, @NotNull ResultSet rs, @NotNull ResultSetMetaData rsmd + , final int row, @NotNull M table, final int columnIndex, Map childMap , Map keyMap) throws Exception { long startTime = System.currentTimeMillis(); String key = rsmd.getColumnLabel(columnIndex); // dotIndex < 0 ? label : label.substring(dotIndex + 1); @@ -1060,9 +1059,9 @@ protected String getKey(@NotNull SQLConfig config, @NotNull ResultSet rs, @No return key; } - protected Object getValue(@NotNull SQLConfig config, @NotNull ResultSet rs, @NotNull ResultSetMetaData rsmd - , final int row, @NotNull JSONObject table, final int columnIndex, String label - , Map childMap, Map keyMap) throws Exception { + protected Object getValue(@NotNull SQLConfig config, @NotNull ResultSet rs, @NotNull ResultSetMetaData rsmd + , final int row, @NotNull M table, final int columnIndex, String label + , Map childMap, Map keyMap) throws Exception { long startTime = System.currentTimeMillis(); Object value = rs.getObject(columnIndex); @@ -1136,9 +1135,9 @@ else if (value instanceof Clob) { //SQL Server TEXT 类型 居然走这个 } if (castToJson) { try { - value = JSON.parse((String) value); + value = JSON.parseJSON(value); } catch (Exception e) { - Log.e(TAG, "getValue try { value = JSON.parse((String) value); } catch (Exception e) { \n" + e.getMessage()); + Log.e(TAG, "getValue try { value = parseJSON((String) value); } catch (Exception e) { \n" + e.getMessage()); } } @@ -1179,7 +1178,7 @@ public Object getNumVal(Number value) { * @return */ @Override - public boolean isJSONType(@NotNull SQLConfig config, ResultSetMetaData rsmd, int position, String label) { + public boolean isJSONType(@NotNull SQLConfig config, ResultSetMetaData rsmd, int position, String label) { try { long startTime = System.currentTimeMillis(); String column = rsmd.getColumnTypeName(position); @@ -1204,14 +1203,14 @@ public boolean isJSONType(@NotNull SQLConfig config, ResultSetMetaData rsmd, @Override // 重写是为了返回类型从 Statement 改为 PreparedStatement,避免其它方法出错 - public PreparedStatement getStatement(@NotNull SQLConfig config) throws Exception { + public PreparedStatement getStatement(@NotNull SQLConfig config) throws Exception { return getStatement(config, null); } @Override - public PreparedStatement getStatement(@NotNull SQLConfig config, String sql) throws Exception { + public PreparedStatement getStatement(@NotNull SQLConfig config, String sql) throws Exception { if (StringUtil.isEmpty(sql)) { - sql = config.getSQL(config.isPrepared()); + sql = config.gainSQL(config.isPrepared()); } PreparedStatement statement; //创建Statement对象 @@ -1265,9 +1264,9 @@ else if (RequestMethod.isGetMethod(config.getMethod(), true)) { return statement; } - public PreparedStatement setArgument(@NotNull SQLConfig config, @NotNull PreparedStatement statement, int index, Object value) throws SQLException { + public PreparedStatement setArgument(@NotNull SQLConfig 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 - if (apijson.JSON.isBooleanOrNumberOrString(value)) { + if (apijson.JSON.isBoolOrNumOrStr(value)) { statement.setObject(index + 1, value); //PostgreSQL JDBC 不支持隐式类型转换 tinyint = varchar 报错 } else { @@ -1280,13 +1279,13 @@ public PreparedStatement setArgument(@NotNull SQLConfig config, @NotNull Prep protected Connection connection; @NotNull @Override - public Connection getConnection(@NotNull SQLConfig config) throws Exception { + public Connection getConnection(@NotNull SQLConfig config) throws Exception { String connectionKey = getConnectionKey(config); connection = connectionMap.get(connectionKey); if (connection == null || connection.isClosed()) { Log.i(TAG, "select connection " + (connection == null ? " = null" : ("isClosed = " + connection.isClosed()))) ; // PostgreSQL 不允许 cross-database - connection = DriverManager.getConnection(config.getDBUri(), config.getDBAccount(), config.getDBPassword()); + connection = DriverManager.getConnection(config.gainDBUri(), config.gainDBAccount(), config.gainDBPassword()); connectionMap.put(connectionKey, connection); } @@ -1299,7 +1298,7 @@ public Connection getConnection(@NotNull SQLConfig config) throws Exception { return connection; } - public String getConnectionKey(@NotNull SQLConfig config) { + public String getConnectionKey(@NotNull SQLConfig config) { return getConnectionKey(config.getNamespace(), config.getCatalog(), config.getDatasource(), config.getDatabase()); } public String getConnectionKey(String database, String datasource, String namespace, String catalog) { @@ -1468,7 +1467,7 @@ public void close() { } @Override - public ResultSet executeQuery(@NotNull SQLConfig config, String sql) throws Exception { + public ResultSet executeQuery(@NotNull SQLConfig config, String sql) throws Exception { if (config.isPrepared() == false || config.isTDengine() // TDengine JDBC 不支持 PreparedStatement || (config.isExplain() && (config.isPresto() || config.isTrino()))) { // Presto JDBC 0.277 在 EXPLAIN 模式下预编译值不会替代 ? 占位导致报错 @@ -1478,7 +1477,7 @@ public ResultSet executeQuery(@NotNull SQLConfig config, String sql) throws E // ? conn.createStatement() // fix Presto: ResultSet: Exception: set type is TYPE_FORWARD_ONLY, Result set concurrency must be CONCUR_READ_ONLY // : conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); - return executeQuery(stt, StringUtil.isEmpty(sql) ? config.getSQL(false) : sql); + return executeQuery(stt, StringUtil.isEmpty(sql) ? config.gainSQL(false) : sql); } // Presto JDBC 0.277 在 EXPLAIN 模式下预编译值不会替代 ? 占位导致报错 @@ -1493,7 +1492,7 @@ public ResultSet executeQuery(@NotNull SQLConfig config, String sql) throws E @Override - public int executeUpdate(@NotNull SQLConfig config, String sql) throws Exception { + public int executeUpdate(@NotNull SQLConfig config, String sql) throws Exception { Statement stt; int count; if (config.isTDengine()) { @@ -1503,7 +1502,7 @@ public int executeUpdate(@NotNull SQLConfig config, String sql) throws Except // ? conn.createStatement() // fix Presto: ResultSet: Exception: set type is TYPE_FORWARD_ONLY, Result set concurrency must be CONCUR_READ_ONLY // : conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); - count = stt.executeUpdate(StringUtil.isEmpty(sql) ? config.getSQL(false) : sql); + count = stt.executeUpdate(StringUtil.isEmpty(sql) ? config.gainSQL(false) : sql); } else { stt = getStatement(config); diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java index e4fb2526f..9bf8e64a2 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java @@ -5,6 +5,7 @@ package apijson.orm; +import static apijson.JSON.*; import static apijson.RequestMethod.DELETE; import static apijson.RequestMethod.GET; import static apijson.RequestMethod.GETS; @@ -34,16 +35,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; +import apijson.*; -import apijson.JSON; -import apijson.JSONResponse; -import apijson.Log; -import apijson.MethodAccess; -import apijson.NotNull; -import apijson.RequestMethod; -import apijson.StringUtil; import apijson.orm.AbstractSQLConfig.IdCallback; import apijson.orm.exception.ConflictException; import apijson.orm.exception.NotLoggedInException; @@ -74,7 +67,8 @@ * @author Lemon * @param id 与 userId 的类型,一般为 Long */ -public abstract class AbstractVerifier implements Verifier, IdCallback { +public abstract class AbstractVerifier, L extends List> + implements Verifier, IdCallback { private static final String TAG = "AbstractVerifier"; /**为 PUT, DELETE 强制要求必须有 id/id{}/id{}@ 条件 @@ -111,7 +105,7 @@ public abstract class AbstractVerifier implements Verifier, */ public static final String ADMIN = "ADMIN"; - public static ParserCreator PARSER_CREATOR; +// public static ParserCreator PARSER_CREATOR; public static ScriptEngineManager SCRIPT_ENGINE_MANAGER; public static ScriptEngine SCRIPT_ENGINE; @@ -133,7 +127,7 @@ public abstract class AbstractVerifier implements Verifier, // > // > @NotNull - public static Map> REQUEST_MAP; + public static Map>> REQUEST_MAP; private static String VERIFY_LENGTH_RULE = "(?[>=<]*)(?[0-9]*)"; private static Pattern VERIFY_LENGTH_PATTERN = Pattern.compile(VERIFY_LENGTH_RULE); @@ -224,7 +218,7 @@ public static HashMap getAccessMap(MethodAccess access) @Override - public String getVisitorIdKey(SQLConfig config) { + public String getVisitorIdKey(SQLConfig config) { return config.getUserIdKey(); } @@ -254,7 +248,7 @@ public Visitor getVisitor() { return visitor; } @Override - public AbstractVerifier setVisitor(Visitor visitor) { + public AbstractVerifier setVisitor(Visitor visitor) { this.visitor = visitor; this.visitorId = visitor == null ? null : visitor.getId(); @@ -273,7 +267,7 @@ public AbstractVerifier setVisitor(Visitor visitor) { * @throws Exception */ @Override - public boolean verifyAccess(SQLConfig config) throws Exception { + public boolean verifyAccess(SQLConfig config) throws Exception { if (ENABLE_VERIFY_ROLE == false) { throw new UnsupportedOperationException("AbstractVerifier.ENABLE_VERIFY_ROLE == false " + "时不支持校验角色权限!如需支持则设置 AbstractVerifier.ENABLE_VERIFY_ROLE = true !"); @@ -307,7 +301,7 @@ public boolean verifyAccess(SQLConfig config) throws Exception { } @Override - public void verifyRole(SQLConfig config, String table, RequestMethod method, String role) throws Exception { + public void verifyRole(SQLConfig config, String table, RequestMethod method, String role) throws Exception { verifyAllowRole(config, table, method, role); //验证允许的角色 verifyUseRole(config, table, method, role); //验证使用的角色 } @@ -321,7 +315,7 @@ public void verifyRole(SQLConfig config, String table, RequestMethod method, Str * @throws Exception * @see {@link apijson.JSONObject#KEY_ROLE} */ - public void verifyAllowRole(SQLConfig config, String table, RequestMethod method, String role) throws Exception { + public void verifyAllowRole(SQLConfig config, String table, RequestMethod method, String role) throws Exception { Log.d(TAG, "verifyAllowRole table = " + table + "; method = " + method + "; role = " + role); if (table == null) { table = config == null ? null : config.getTable(); @@ -352,7 +346,7 @@ public void verifyAllowRole(SQLConfig config, String table, RequestMethod method * @throws Exception * @see {@link apijson.JSONObject#KEY_ROLE} */ - public void verifyUseRole(SQLConfig config, String table, RequestMethod method, String role) throws Exception { + public void verifyUseRole(SQLConfig config, String table, RequestMethod method, String role) throws Exception { Log.d(TAG, "verifyUseRole table = " + table + "; method = " + method + "; role = " + role); //验证角色,假定真实强制匹配<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -387,13 +381,13 @@ public void verifyUseRole(SQLConfig config, String table, RequestMethod method, Collection requestIdArray = (Collection) config.getWhere(visitorIdKey + "{}", true); // 不能是 &{}, |{} 不要传,直接 {} if (requestId != null) { if (requestIdArray == null) { - requestIdArray = new JSONArray(); + requestIdArray = JSON.createJSONArray(); } requestIdArray.add(requestId); } if (requestIdArray == null) { // 可能是 @ 得到 || requestIdArray.isEmpty()) { // 请求未声明 key:id 或 key{}:[...] 条件,自动补全 - config.putWhere(visitorIdKey+"{}", JSON.parseArray(list), true); // key{}:[] 有效,SQLConfig 里 throw NotExistException + config.putWhere(visitorIdKey+"{}", JSON.parseArray(list), true); // key{}:[] 有效,SQLConfig 里 throw NotExistException } else { // 请求已声明 key:id 或 key{}:[] 条件,直接验证 for (Object id : requestIdArray) { @@ -536,18 +530,21 @@ public void verifyRepeat(String table, String key, Object value, long exceptId) throw new UnsupportedDataTypeException(key + ":value 中value的类型不能为JSON!"); } - JSONRequest request = new JSONRequest(key, value); + M tblObj = JSON.createJSONObject(); + tblObj.put(key, value); if (exceptId > 0) {//允许修改自己的属性为该属性原来的值 - request.put(JSONRequest.KEY_ID + "!", exceptId); // FIXME 这里 id 写死了,不支持自定义 + tblObj.put(apijson.JSONObject.KEY_ID + "!", exceptId); // FIXME 这里 id 写死了,不支持自定义 } - JSONObject repeat = createParser().setMethod(HEAD).setNeedVerify(true).parseResponse( - new JSONRequest(table, request) - ); - repeat = repeat == null ? null : repeat.getJSONObject(table); + + M req = JSON.createJSONObject(); + req.put(table, tblObj); + Map repeat = createParser().setMethod(HEAD).setNeedVerify(true).parseResponse(req); + + repeat = repeat == null ? null : JSON.get(repeat, table); if (repeat == null) { throw new Exception("服务器内部错误 verifyRepeat repeat == null"); } - if (repeat.getIntValue(JSONResponse.KEY_COUNT) > 0) { + if (getIntValue(repeat, JSONResponse.KEY_COUNT) > 0) { throw new ConflictException(key + ": " + value + " 已经存在,不能重复!"); } } @@ -567,9 +564,8 @@ public void verifyRepeat(String table, String key, Object value, long exceptId) * @throws Exception */ @Override - public JSONObject verifyRequest(@NotNull final RequestMethod method, final String name - , final JSONObject target, final JSONObject request, final int maxUpdateCount - , final String database, final String schema, final SQLCreator creator) throws Exception { + 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 creator) throws Exception { return verifyRequest(method, name, target, request, maxUpdateCount, database, schema, this, creator); } @@ -582,8 +578,9 @@ public JSONObject verifyRequest(@NotNull final RequestMethod method, final Strin * @return * @throws Exception */ - public static JSONObject verifyRequest(@NotNull final RequestMethod method, final String name - , final JSONObject target, final JSONObject request, final SQLCreator creator) throws Exception { + public static , L extends List> M verifyRequest( + @NotNull final RequestMethod method, final String name, final M target, final M request + , final SQLCreator creator) throws Exception { return verifyRequest(method, name, target, request, AbstractParser.MAX_UPDATE_COUNT, creator); } /**从request提取target指定的内容 @@ -596,11 +593,11 @@ public static JSONObject verifyRequest(@NotNull final RequestMethod method, fina * @return * @throws Exception */ - public static JSONObject verifyRequest(@NotNull final RequestMethod method, final String name - , final JSONObject target, final JSONObject request - , final int maxUpdateCount, final SQLCreator creator) throws Exception { - return verifyRequest(method, name, target, request, maxUpdateCount - , null, null, null, creator); + public static , L extends List> M verifyRequest( + @NotNull final RequestMethod method, final String name, final M target, final M request + , final int maxUpdateCount, final SQLCreator creator) throws Exception { + + return verifyRequest(method, name, target, request, maxUpdateCount, null, null, null, creator); } /**从request提取target指定的内容 @@ -617,12 +614,12 @@ public static JSONObject verifyRequest(@NotNull final RequestMethod method, fina * @param * @throws Exception */ - public static JSONObject verifyRequest(@NotNull final RequestMethod method - , final String name, final JSONObject target, final JSONObject request + public static , L extends List> 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 idCallback, final SQLCreator creator) throws Exception { - return verifyRequest(method, name, target, request, maxUpdateCount, database, schema - , null, idCallback, creator); + , final IdCallback idCallback, final SQLCreator creator) throws Exception { + + return verifyRequest(method, name, target, request, maxUpdateCount, database, schema, null, idCallback, creator); } /**从request提取target指定的内容 * @param method @@ -639,10 +636,10 @@ public static JSONObject verifyRequest(@NotNull final Request * @param * @throws Exception */ - public static JSONObject verifyRequest(@NotNull final RequestMethod method - , final String name, final JSONObject target, final JSONObject request + public static , L extends List> 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 idCallback, final SQLCreator creator) throws Exception { + , final IdCallback idCallback, final SQLCreator creator) throws Exception { if (ENABLE_VERIFY_CONTENT == false) { throw new UnsupportedOperationException("AbstractVerifier.ENABLE_VERIFY_CONTENT == false" + " 时不支持校验请求传参内容!如需支持则设置 AbstractVerifier.ENABLE_VERIFY_CONTENT = true !"); @@ -658,17 +655,17 @@ public static JSONObject verifyRequest(@NotNull final Request } //已在 Verifier 中处理 - // if (get(request.getString(JSONRequest.KEY_ROLE)) == ADMIN) { + // if (get(getString(request, apijson.JSONObject.KEY_ROLE)) == ADMIN) { // throw new IllegalArgumentException("角色设置错误!不允许在写操作Request中传 " + name + - // ":{ " + JSONRequest.KEY_ROLE + ":admin } !"); + // ":{ " + apijson.JSONObject.KEY_ROLE + ":admin } !"); // } //解析 - return parse(method, name, target, request, database, schema, idCallback, creator, new OnParseCallback() { + return parse(method, name, target, request, database, schema, idCallback, creator, new OnParseCallback() { @Override - public JSONObject onParseJSONObject(String key, JSONObject tobj, JSONObject robj) throws Exception { + public M onParseJSONObject(String key, M tobj, M robj) throws Exception { // Log.i(TAG, "verifyRequest.parse.onParseJSONObject key = " + key + "; robj = " + robj); if (robj == null) { @@ -676,9 +673,9 @@ public JSONObject onParseJSONObject(String key, JSONObject tobj, JSONObject robj throw new IllegalArgumentException(method + "请求,请在 " + name + " 内传 " + key + ":{} !"); } } else if (apijson.JSONObject.isTableKey(key)) { - String db = request.getString(apijson.JSONObject.KEY_DATABASE); - String sh = request.getString(apijson.JSONObject.KEY_SCHEMA); - String ds = request.getString(apijson.JSONObject.KEY_DATASOURCE); + String db = getString(request, apijson.JSONObject.KEY_DATABASE); + String sh = getString(request, apijson.JSONObject.KEY_SCHEMA); + String ds = getString(request, apijson.JSONObject.KEY_DATASOURCE); if (StringUtil.isEmpty(db, false)) { db = database; } @@ -697,7 +694,7 @@ public JSONObject onParseJSONObject(String key, JSONObject tobj, JSONObject robj throw new IllegalArgumentException(method + "请求," + name + "/" + key + " 不能传 " + finalIdKey + " !"); } } else { - Boolean atLeastOne = tobj == null ? null : tobj.getBoolean(Operation.IS_ID_CONDITION_MUST.name()); + Boolean atLeastOne = tobj == null ? null : getBoolean(tobj, Operation.IS_ID_CONDITION_MUST.name()); if (Boolean.TRUE.equals(atLeastOne) || RequestMethod.isUpdateMethod(method)) { verifyId(method.name(), name, key, robj, finalIdKey, maxUpdateCount, atLeastOne != null ? atLeastOne : IS_UPDATE_MUST_HAVE_ID_CONDITION); @@ -712,8 +709,8 @@ public JSONObject onParseJSONObject(String key, JSONObject tobj, JSONObject robj } @Override - protected JSONArray onParseJSONArray(String key, JSONArray tarray, JSONArray rarray) throws Exception { - if ((method == RequestMethod.POST || method == RequestMethod.PUT) && JSONRequest.isArrayKey(key)) { + protected L onParseJSONArray(String key, L tarray, L rarray) throws Exception { + if ((method == RequestMethod.POST || method == RequestMethod.PUT) && apijson.JSONObject.isArrayKey(key)) { if (rarray == null || rarray.isEmpty()) { throw new IllegalArgumentException(method + "请求,请在 " + name + " 内传 " + key + ":[{ ... }] " + ",批量新增 Table[]:value 中 value 必须是包含表对象的非空数组!其中每个子项 { ... } 都是" @@ -738,8 +735,9 @@ protected JSONArray onParseJSONArray(String key, JSONArray tarray, JSONArray rar * @param idKey * @param atLeastOne 至少有一个不为null */ - private static void verifyId(@NotNull String method, @NotNull String name, @NotNull String key - , @NotNull JSONObject robj, @NotNull String idKey, final int maxUpdateCount, boolean atLeastOne) { + private static , L extends List> void verifyId( + @NotNull String method, @NotNull String name, @NotNull String key + , @NotNull M robj, @NotNull String idKey, final int maxUpdateCount, boolean atLeastOne) throws Exception { //单个修改或删除 Object id = robj.get(idKey); //如果必须传 id ,可在Request表中配置NECESSARY if (id != null && id instanceof Number == false && id instanceof String == false) { @@ -751,10 +749,10 @@ private static void verifyId(@NotNull String method, @NotNull String name, @NotN //批量修改或删除 String idInKey = idKey + "{}"; // id引用, 格式: "id{}@": "sql" - String idRefInKey = robj.getString(idKey + "{}@"); - JSONArray idIn = null; + String idRefInKey = getString(robj, idKey + "{}@"); + L idIn = null; try { - idIn = robj.getJSONArray(idInKey); //如果必须传 id{} ,可在Request表中配置NECESSARY + idIn = JSON.get(robj, idInKey); //如果必须传 id{} ,可在Request表中配置NECESSARY } catch (Exception e) { throw new IllegalArgumentException(method + "请求," + name + "/" + key + " 里面的 " + idInKey + ":value 中value的类型只能是 [Long] !"); @@ -813,9 +811,8 @@ else if (o instanceof String) { * @throws Exception */ @Override - public JSONObject verifyResponse(@NotNull final RequestMethod method, final String name - , final JSONObject target, final JSONObject response, final String database, final String schema - , SQLCreator creator, OnParseCallback callback) throws Exception { + public M verifyResponse(@NotNull final RequestMethod method, final String name, final M target, final M response + , final String database, final String schema, SQLCreator creator, OnParseCallback callback) throws Exception { return verifyResponse(method, name, target, response, database, schema, this, creator, callback); } @@ -829,8 +826,8 @@ public JSONObject verifyResponse(@NotNull final RequestMethod method, final Stri * @return * @throws Exception */ - public static JSONObject verifyResponse(@NotNull final RequestMethod method, final String name - , final JSONObject target, final JSONObject response, SQLCreator creator, OnParseCallback callback) throws Exception { + public static , L extends List> M verifyResponse(@NotNull final RequestMethod method, final String name + , final M target, final M response, SQLCreator creator, OnParseCallback callback) throws Exception { return verifyResponse(method, name, target, response, null, null, null, creator, callback); } /**校验并将response转换为指定的内容和结构 @@ -847,9 +844,9 @@ public static JSONObject verifyResponse(@NotNull final RequestMethod method, fin * @param * @throws Exception */ - public static JSONObject verifyResponse(@NotNull final RequestMethod method, final String name - , final JSONObject target, final JSONObject response, final String database, final String schema - , final IdCallback idKeyCallback, SQLCreator creator, OnParseCallback callback) throws Exception { + public static , L extends List> M verifyResponse(@NotNull final RequestMethod method + , final String name, final M target, final M response, final String database, final String schema + , final IdCallback idKeyCallback, SQLCreator creator, OnParseCallback callback) throws Exception { Log.i(TAG, "verifyResponse method = " + method + "; name = " + name + "; target = \n" + JSON.toJSONString(target) @@ -862,9 +859,9 @@ public static JSONObject verifyResponse(@NotNull final Reques //解析 return parse(method, name, target, response, database, schema - , idKeyCallback, creator, callback != null ? callback : new OnParseCallback() { + , idKeyCallback, creator, callback != null ? callback : new OnParseCallback() { @Override - protected JSONObject onParseJSONObject(String key, JSONObject tobj, JSONObject robj) throws Exception { + protected M onParseJSONObject(String key, M tobj, M robj) throws Exception { return verifyResponse(method, key, tobj, robj, database, schema, idKeyCallback, creator, callback); } }); @@ -881,8 +878,8 @@ protected JSONObject onParseJSONObject(String key, JSONObject tobj, JSONObject r * @return * @throws Exception */ - public static JSONObject parse(@NotNull final RequestMethod method, String name, JSONObject target, JSONObject real - , SQLCreator creator, @NotNull OnParseCallback callback) throws Exception { + public static , L extends List> M parse(@NotNull final RequestMethod method + , String name, M target, M real, SQLCreator creator, @NotNull OnParseCallback callback) throws Exception { return parse(method, name, target, real, null, null, null, creator, callback); } /**对request和response不同的解析用callback返回 @@ -898,9 +895,9 @@ public static JSONObject parse(@NotNull final RequestMethod method, String name, * @return * @throws Exception */ - public static JSONObject parse(@NotNull final RequestMethod method, String name - , JSONObject target, JSONObject real, final String database, final String schema - , final IdCallback idCallback, SQLCreator creator, @NotNull OnParseCallback callback) throws Exception { + public static , L extends List> M parse( + @NotNull final RequestMethod method, String name, M target, M real, final String database, final String schema + , final IdCallback idCallback, SQLCreator creator, @NotNull OnParseCallback callback) throws Exception { return parse(method, name, target, real, database, schema, null, idCallback, creator, callback); } /**对request和response不同的解析用callback返回 @@ -917,39 +914,39 @@ public static JSONObject parse(@NotNull final RequestMethod m * @return * @throws Exception */ - public static JSONObject parse(@NotNull final RequestMethod method, String name - , JSONObject target, JSONObject real, final String database, final String schema, final String datasource - , final IdCallback idCallback, SQLCreator creator, @NotNull OnParseCallback callback) throws Exception { + public static , L extends List> M parse(@NotNull final RequestMethod method + , String name, M target, M real, final String database, final String schema, final String datasource + , final IdCallback idCallback, SQLCreator creator, @NotNull OnParseCallback callback) throws Exception { if (target == null) { return null; } // 获取配置<<<<<<<<<<<<<<<<<<<<<<<<<<<< - JSONObject type = target.getJSONObject(TYPE.name()); - JSONObject verify = target.getJSONObject(VERIFY.name()); - JSONObject insert = target.getJSONObject(INSERT.name()); - JSONObject update = target.getJSONObject(UPDATE.name()); - JSONObject replace = target.getJSONObject(REPLACE.name()); - - String exist = StringUtil.get(target.getString(EXIST.name())); - String unique = StringUtil.get(target.getString(UNIQUE.name())); - String remove = StringUtil.get(target.getString(REMOVE.name())); - String must = StringUtil.get(target.getString(MUST.name())); - String refuse = StringUtil.get(target.getString(REFUSE.name())); + M type = JSON.get(target, TYPE.name()); + M verify = JSON.get(target, VERIFY.name()); + M insert = JSON.get(target, INSERT.name()); + M update = JSON.get(target, UPDATE.name()); + M replace = JSON.get(target, REPLACE.name()); + + String exist = StringUtil.get(getString(target, EXIST.name())); + String unique = StringUtil.get(getString(target, UNIQUE.name())); + String remove = StringUtil.get(getString(target, REMOVE.name())); + String must = StringUtil.get(getString(target, MUST.name())); + String refuse = StringUtil.get(getString(target, REFUSE.name())); Object _if = target.get(IF.name()); boolean ifIsStr = _if instanceof String && StringUtil.isNotEmpty(_if, true); - JSONObject ifObj = ifIsStr == false && _if instanceof JSONObject ? (JSONObject) _if : null; -// : (_if instanceof String ? new apijson.JSONRequest((String) _if, "" /* "throw new Error('')" */ ) : null); + M ifObj = ifIsStr == false && _if instanceof Map ? (M) _if : null; +// : (_if instanceof String ? new apijson.JSONObject((String) _if, "" /* "throw new Error('')" */ ) : null); if (ifObj == null && _if != null && ifIsStr == false) { -// if (_if instanceof JSONArray) { +// if (_if instanceof List) { // } - throw new IllegalArgumentException(name + ": { " + IF.name() + ": value } 中 value 类型错误!只允许 String, JSONObject!"); + throw new IllegalArgumentException(name + ": { " + IF.name() + ": value } 中 value 类型错误!只允许 String, JSONRequest!"); } // Object code = target.get(CODE.name()); - String allowPartialUpdateFail = StringUtil.get(target.getString(ALLOW_PARTIAL_UPDATE_FAIL.name())); + String allowPartialUpdateFail = StringUtil.get(getString(target, ALLOW_PARTIAL_UPDATE_FAIL.name())); // 移除字段<<<<<<<<<<<<<<<<<<< @@ -996,20 +993,20 @@ public static JSONObject parse(@NotNull final RequestMethod m continue; } - if (tvalue instanceof JSONObject) { // JSONObject,往下一级提取 - if (rvalue != null && rvalue instanceof JSONObject == false) { + if (tvalue instanceof Map) { // JSONRequest,往下一级提取 + if (rvalue != null && rvalue instanceof Map == false) { throw new UnsupportedDataTypeException(key + ":value 的 value 不合法!类型必须是 OBJECT ,结构为 {} !"); } - tvalue = callback.onParseJSONObject(key, (JSONObject) tvalue, (JSONObject) rvalue); + tvalue = callback.onParseJSONObject(key, (M) tvalue, (M) rvalue); objKeySet.add(key); - } else if (tvalue instanceof JSONArray) { // JSONArray - if (rvalue != null && rvalue instanceof JSONArray == false) { + } else if (tvalue instanceof List) { // L + if (rvalue != null && rvalue instanceof List == false) { throw new UnsupportedDataTypeException(key + ":value 的 value 不合法!类型必须是 ARRAY ,结构为 [] !"); } - tvalue = callback.onParseJSONArray(key, (JSONArray) tvalue, (JSONArray) rvalue); + tvalue = callback.onParseJSONArray(key, (L) tvalue, (L) rvalue); - if ((method == RequestMethod.POST || method == RequestMethod.PUT) && JSONRequest.isArrayKey(key)) { + if ((method == RequestMethod.POST || method == RequestMethod.PUT) && apijson.JSONObject.isArrayKey(key)) { objKeySet.add(key); } } else { // 其它Object @@ -1112,12 +1109,12 @@ public static JSONObject parse(@NotNull final RequestMethod m // 不在target内的 key:{} if (rk.startsWith("@") == false && rk.endsWith("@") == false && objKeySet.contains(rk) == false) { - if (rv instanceof JSONObject) { + if (rv instanceof Map) { throw new UnsupportedOperationException(method + " 请求," + name + " 里面不允许传 " + rk + ":{} !"); } if ((method == RequestMethod.POST || method == RequestMethod.PUT) - && rv instanceof JSONArray && JSONRequest.isArrayKey(rk)) { + && rv instanceof List && apijson.JSONObject.isArrayKey(rk)) { throw new UnsupportedOperationException(method + " 请求," + name + " 里面不允许 " + rk + ":[] 等未定义的 Table[]:[{}] 批量操作键值对!"); } @@ -1142,9 +1139,9 @@ public static JSONObject parse(@NotNull final RequestMethod m // 校验与修改Request>>>>>>>>>>>>>>>>> - String db = real.getString(apijson.JSONObject.KEY_DATABASE); - String sh = real.getString(apijson.JSONObject.KEY_SCHEMA); - String ds = real.getString(apijson.JSONObject.KEY_DATASOURCE); + String db = getString(real, apijson.JSONObject.KEY_DATABASE); + String sh = getString(real, apijson.JSONObject.KEY_SCHEMA); + String ds = getString(real, apijson.JSONObject.KEY_DATASOURCE); if (StringUtil.isEmpty(db, false)) { db = database; } @@ -1161,7 +1158,7 @@ public static JSONObject parse(@NotNull final RequestMethod m // 校验存在<<<<<<<<<<<<<<<<<<< String[] exists = StringUtil.split(exist); if (exists != null && exists.length > 0) { - long exceptId = real.getLongValue(finalIdKey); + long exceptId = getLongValue(real, finalIdKey); Map map = new HashMap<>(); for (String e : exists) { map.put(e,real.get(e)); @@ -1174,7 +1171,7 @@ public static JSONObject parse(@NotNull final RequestMethod m // 校验重复<<<<<<<<<<<<<<<<<<< String[] uniques = StringUtil.split(unique); if (uniques != null && uniques.length > 0) { - long exceptId = real.getLongValue(finalIdKey); + long exceptId = getLongValue(real, finalIdKey); Map map = new HashMap<>(); for (String u : uniques) { map.put(u, real.get(u)); @@ -1210,17 +1207,17 @@ public static JSONObject parse(@NotNull final RequestMethod m // 校验并配置允许部分批量增删改失败>>>>>>>>>>>>>>>>>>> - String[] nks = ifObj == null ? null : StringUtil.split(real.getString(JSONRequest.KEY_NULL)); + String[] nks = ifObj == null ? null : StringUtil.split(getString(real, apijson.JSONObject.KEY_NULL)); Collection nkl = nks == null || nks.length <= 0 ? new HashSet<>() : Arrays.asList(nks); Set> ifSet = ifObj == null ? null : ifObj.entrySet(); if (ifIsStr || (ifSet != null && ifSet.isEmpty() == false)) { // 没必要限制,都是后端配置的,安全可控,而且可能确实有特殊需求,需要 id, @column 等 -// List condKeys = new ArrayList<>(Arrays.asList(apijson.JSONRequest.KEY_ID, apijson.JSONRequest.KEY_ID_IN -// , apijson.JSONRequest.KEY_USER_ID, apijson.JSONRequest.KEY_USER_ID_IN)); -// condKeys.addAll(JSONRequest.TABLE_KEY_LIST); +// List 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); - String preCode = "var curObj = " + JSON.format(real) + ";"; + String preCode = "var curObj = " + JSON.toJSONString(real) + ";"; // 未传的 key 在后面 eval 时总是报错 undefined,而且可能有冲突,例如对象里有 "curObj": val 键值对,就会覆盖当前对象定义,还不如都是 curObj.sex 这样取值 // Set> rset = real.entrySet(); @@ -1281,13 +1278,13 @@ public static JSONObject parse(@NotNull final RequestMethod m continue; } - if (v instanceof JSONObject == false) { + if (v instanceof Map == false) { throw new IllegalArgumentException("Request 表 structure 配置的 " + IF.name() - + ":{ " + k + ":value } 中 value 不合法,必须是 JSONObject {} !"); + + ":{ " + k + ":value } 中 value 不合法,必须是 JSONRequest {} !"); } if (nkl.contains(k) || real.get(k) != null) { - real = parse(method, name, (JSONObject) v, real, database, schema, datasource, idCallback, creator, callback); + real = parse(method, name, (M) v, real, database, schema, datasource, idCallback, creator, callback); } } } @@ -1316,8 +1313,8 @@ public static ScriptEngine getScriptEngine(String lang) { * @return * @throws Exception */ - private static JSONObject operate(Operation opt, JSONObject targetChild - , JSONObject real, SQLCreator creator) throws Exception { + private static , L extends List> M operate(Operation opt, M targetChild + , M real, SQLCreator creator) throws Exception { if (targetChild == null) { return real; } @@ -1367,7 +1364,7 @@ else if (opt == UPDATE) { * @param real * @throws Exception */ - public static void verifyType(@NotNull String tk, Object tv, @NotNull JSONObject real) + public static void verifyType(@NotNull String tk, Object tv, @NotNull Map real) throws UnsupportedDataTypeException { if (tv instanceof String == false) { throw new UnsupportedDataTypeException("服务器内部错误," + tk + ":value 的value不合法!" @@ -1411,8 +1408,8 @@ public static void verifyType(@NotNull String tk, @NotNull String tv, Object rv, //这里不抽取 enum,因为 enum 不能满足扩展需求,子类需要可以自定义,而且 URL[] 这种也不符合命名要求,得用 constructor + getter + setter switch (tv) { - case "BOOLEAN": //Boolean.parseBoolean(real.getString(tk)); 只会判断null和true - if (rv instanceof Boolean == false) { //JSONObject.getBoolean 可转换Number类型 + case "BOOLEAN": //Boolean.parseBoolean(getString(real, tk)); 只会判断null和true + if (rv instanceof Boolean == false) { //apijson.JSONObject.getBoolean 可转换Number类型 throw new UnsupportedDataTypeException(tk + ":value 的value不合法!类型必须是 BOOLEAN" + (isInArray ? "[] !" : " !")); } break; @@ -1432,7 +1429,7 @@ public static void verifyType(@NotNull String tk, @NotNull String tv, Object rv, } break; case "STRING": - if (rv instanceof String == false) { //JSONObject.getString 可转换任何类型 + if (rv instanceof String == false) { //apijson.JSONObject.getString 可转换任何类型 throw new UnsupportedDataTypeException(tk + ":value 的value不合法!" + "类型必须是 STRING" + (isInArray ? "[] !" : " !")); } @@ -1470,13 +1467,13 @@ public static void verifyType(@NotNull String tk, @NotNull String tv, Object rv, } break; case "OBJECT": - if (rv instanceof Map == false) { //JSONObject.getJSONObject 可转换String类型 + if (rv instanceof Map == false) { //apijson.JSONObject.getJSONObject 可转换String类型 throw new UnsupportedDataTypeException(tk + ":value 的value不合法!" + "类型必须是 OBJECT" + (isInArray ? "[] !" : " !") + " OBJECT 结构为 {} !"); } break; case "ARRAY": - if (rv instanceof Collection == false) { //JSONObject.getJSONArray 可转换String类型 + if (rv instanceof Collection == false) { //apijson.JSONObject.getJSONArray 可转换String类型 throw new UnsupportedDataTypeException(tk + ":value 的value不合法!" + "类型必须是 ARRAY" + (isInArray ? "[] !" : " !") + " ARRAY 结构为 [] !"); } @@ -1484,7 +1481,7 @@ public static void verifyType(@NotNull String tk, @NotNull String tv, Object rv, //目前在业务表中还用不上,单一的类型校验已经够用 // case "JSON": // try { - // com.alibaba.fastjson.JSON.parse(rv.toString()); + // com.alibaba.fastjson.parseJSON(rv.toString()); // } catch (Exception e) { // throw new UnsupportedDataTypeException(tk + ":value 的value不合法!类型必须是 JSON !" // + "也就是 {Object}, [Array] 或 它们对应的字符串 '{Object}', '[Array]' 4种中的一个 !"); @@ -1507,7 +1504,8 @@ public static void verifyType(@NotNull String tk, @NotNull String tv, Object rv, * @param creator * @throws Exception */ - private static void verifyValue(@NotNull String tk, @NotNull Object tv, @NotNull JSONObject real, SQLCreator creator) throws Exception { + private static , L extends List> void verifyValue(@NotNull String tk + , @NotNull Object tv, @NotNull M real, SQLCreator creator) throws Exception { if (tv == null) { throw new IllegalArgumentException("operate operate == VERIFY " + tk + ":" + tv + " , >> tv == null!!!"); } @@ -1526,7 +1524,17 @@ else if (tk.endsWith("~")) { // 正则匹配 return; } - JSONArray array = AbstractSQLConfig.newJSONArray(tv); + L array = AbstractSQLConfig.newJSONArray(tv, new JSONCreator() { + @Override + public M createJSONObject() { + return JSON.createJSONObject(); + } + + @Override + public L createJSONArray() { + return JSON.createJSONArray(); + } + }); boolean m; boolean isOr = false; @@ -1563,7 +1571,7 @@ else if (tk.endsWith("{}")) { //rv符合tv条件或在tv内 if (tv instanceof String) {//TODO >= 0, < 10 verifyCondition("{}", real, tk, tv, creator); } - else if (tv instanceof JSONArray) { + else if (tv instanceof List) { logic = new Logic(tk.substring(0, tk.length() - 2)); rk = logic.getKey(); rv = real.get(rk); @@ -1571,7 +1579,7 @@ else if (tv instanceof JSONArray) { return; } - if (((JSONArray) tv).contains(rv) == logic.isNot()) { + if (((L) tv).contains(rv) == logic.isNot()) { throw new IllegalArgumentException(rk + ":value 中value不合法!必须匹配 " + tk + ":" + tv + " !"); } } @@ -1607,15 +1615,25 @@ else if (tk.endsWith("<>")) { //rv包含tv内的值 return; } - if (rv instanceof JSONArray == false) { + if (rv instanceof Collection == false) { throw new UnsupportedDataTypeException("服务器Request表verify配置错误!"); } - JSONArray array = AbstractSQLConfig.newJSONArray(tv); + L array = AbstractSQLConfig.newJSONArray(tv, new JSONCreator, L>() { + @Override + public M createJSONObject() { + return JSON.createJSONObject(); + } + + @Override + public L createJSONArray() { + return JSON.createJSONArray(); + } + }); boolean isOr = false; for (Object o : array) { - if (((JSONArray) rv).contains(o)) { + if (((L) rv).contains(o)) { if (logic.isNot()) { throw new IllegalArgumentException(rk + ":value 中value不合法!必须匹配 " + tk + ":" + tv + " !"); } @@ -1686,8 +1704,9 @@ private static boolean verifyRV(String rule,String content) throws UnsupportedDa * @param creator * @throws Exception */ - private static void verifyCondition(@NotNull String funChar, @NotNull JSONObject real, @NotNull String tk, @NotNull Object tv - , @NotNull SQLCreator creator) throws Exception { + private static , L extends List> void verifyCondition( + @NotNull String funChar, @NotNull M real, @NotNull String tk, @NotNull Object tv + , @NotNull SQLCreator creator) throws Exception { //不能用Parser, 0 这种不符合 StringUtil.isName ! Logic logic = new Logic(tk.substring(0, tk.length() - funChar.length())); String rk = logic.getKey(); @@ -1700,7 +1719,7 @@ private static void verifyCondition(@NotNull String funChar, @NotNull JSONObject throw new IllegalArgumentException(rk + ":value 中value不合法!value 中不允许有单引号 ' !"); } - SQLConfig config = creator.createSQLConfig().setMethod(RequestMethod.GET).setCount(1).setPage(0); + SQLConfig config = creator.createSQLConfig().setMethod(RequestMethod.GET).setCount(1).setPage(0); config.setTest(true); // config.setTable(Test.class.getSimpleName()); // config.setColumn(rv + logic.getChar() + funChar) @@ -1708,15 +1727,15 @@ private static void verifyCondition(@NotNull String funChar, @NotNull JSONObject config.putWhere(rv + logic.getChar() + funChar, tv, false); config.setCount(1); - SQLExecutor executor = creator.createSQLExecutor(); - JSONObject result = null; + SQLExecutor executor = creator.createSQLExecutor(); + M result = null; try { result = executor.execute(config, false); } finally { executor.close(); } - if (result != null && JSONResponse.isExist(result.getIntValue(JSONResponse.KEY_COUNT)) == false) { + if (result != null && JSONResponse.isExist(getIntValue(result, JSONResponse.KEY_COUNT)) == false) { throw new IllegalArgumentException(rk + ":value 中value不合法!必须匹配 '" + tk + "': '" + tv + "' !"); } } @@ -1728,7 +1747,8 @@ private static void verifyCondition(@NotNull String funChar, @NotNull JSONObject * @param value * @throws Exception */ - public static void verifyExist(String table, String key, Object value, long exceptId, @NotNull SQLCreator creator) throws Exception { + public static , L extends List>void verifyExist(String table, String key + , Object value, long exceptId, @NotNull SQLCreator creator) throws Exception { if (key == null || value == null) { Log.e(TAG, "verifyExist key == null || value == null >> return;"); return; @@ -1746,23 +1766,24 @@ public static void verifyExist(String table, String key, Object value, long exce * @param param * @throws Exception */ - public static void verifyExist(String table, Map param, long exceptId, @NotNull SQLCreator creator) throws Exception { + public static , L extends List> void verifyExist(String table + , Map param, long exceptId, @NotNull SQLCreator creator) throws Exception { if (param.isEmpty()) { Log.e(TAG, "verifyExist is empty >> return;"); return; } - SQLConfig config = creator.createSQLConfig().setMethod(RequestMethod.HEAD).setCount(1).setPage(0); + SQLConfig config = creator.createSQLConfig().setMethod(RequestMethod.HEAD).setCount(1).setPage(0); config.setTable(table); param.forEach((key,value) -> config.putWhere(key, value, false)); - SQLExecutor executor = creator.createSQLExecutor(); + SQLExecutor executor = creator.createSQLExecutor(); try { - JSONObject result = executor.execute(config, false); + M result = executor.execute(config, false); if (result == null) { throw new Exception("服务器内部错误 verifyExist result == null"); } - if (result.getIntValue(JSONResponse.KEY_COUNT) <= 0) { + if (getIntValue(result, JSONResponse.KEY_COUNT) <= 0) { StringBuilder sb = new StringBuilder(); param.forEach((key,value) -> sb.append("key:").append(key).append(" value:").append(value).append(" ")); throw new ConflictException(sb + "的数据不存在!如果必要请先创建!"); @@ -1778,7 +1799,8 @@ public static void verifyExist(String table, Map param, long exce * @param value * @throws Exception */ - public static void verifyRepeat(String table, String key, Object value, @NotNull SQLCreator creator) throws Exception { + public static , L extends List> void verifyRepeat(String table, String key + , Object value, @NotNull SQLCreator creator) throws Exception { verifyRepeat(table, key, value, 0, creator); } @@ -1789,7 +1811,8 @@ public static void verifyRepeat(String table, String key, Object value, @NotNull * @param exceptId 不包含id * @throws Exception */ - public static void verifyRepeat(String table, String key, Object value, long exceptId, @NotNull SQLCreator creator) throws Exception { + public static , L extends List> void verifyRepeat(String table, String key + , Object value, long exceptId, @NotNull SQLCreator creator) throws Exception { verifyRepeat(table, key, value, exceptId, null, creator); } @@ -1803,8 +1826,8 @@ public static void verifyRepeat(String table, String key, Object value, long exc * @param creator * @throws Exception */ - public static void verifyRepeat(String table, String key, Object value - , long exceptId, String idKey, @NotNull SQLCreator creator) throws Exception { + public static , L extends List>void verifyRepeat(String table, String key + , Object value, long exceptId, String idKey, @NotNull SQLCreator creator) throws Exception { if (key == null || value == null) { Log.e(TAG, "verifyRepeat key == null || value == null >> return;"); return; @@ -1826,7 +1849,8 @@ public static void verifyRepeat(String table, String key, Object value * @param creator * @throws Exception */ - public static void verifyRepeat(String table, Map param, long exceptId, String idKey, @NotNull SQLCreator creator) throws Exception { + public static , L extends List> void verifyRepeat(String table + , Map param, long exceptId, String idKey, @NotNull SQLCreator creator) throws Exception { if (param.isEmpty()) { Log.e(TAG, "verifyRepeat is empty >> return;"); return; @@ -1834,20 +1858,20 @@ public static void verifyRepeat(String table, Map param, long exc String finalIdKey = StringUtil.isEmpty(idKey, false) ? apijson.JSONObject.KEY_ID : idKey; - SQLConfig config = creator.createSQLConfig().setMethod(RequestMethod.HEAD).setCount(1).setPage(0); + SQLConfig config = creator.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 executor = creator.createSQLExecutor(); + SQLExecutor executor = creator.createSQLExecutor(); try { - JSONObject result = executor.execute(config, false); + M result = executor.execute(config, false); if (result == null) { throw new Exception("服务器内部错误 verifyRepeat result == null"); } - if (result.getIntValue(JSONResponse.KEY_COUNT) > 0) { + if (getIntValue(result, JSONResponse.KEY_COUNT) > 0) { StringBuilder sb = new StringBuilder(); param.forEach((key,value) -> sb.append("key:").append(key).append(" value:").append(value).append(" ")); throw new ConflictException(sb + "的数据已经存在,不能重复!"); @@ -1862,5 +1886,4 @@ public static String getCacheKeyForRequest(String method, String tag) { return method + "/" + tag; } - } diff --git a/APIJSONORM/src/main/java/apijson/orm/FunctionParser.java b/APIJSONORM/src/main/java/apijson/orm/FunctionParser.java index ec5aefbd6..155d80fae 100644 --- a/APIJSONORM/src/main/java/apijson/orm/FunctionParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/FunctionParser.java @@ -5,51 +5,50 @@ package apijson.orm; -import com.alibaba.fastjson.JSONObject; +import java.util.List; +import java.util.Map; -import apijson.NotNull; -import apijson.RequestMethod; +import apijson.*; /**远程函数解析器 * @author Lemon */ -public interface FunctionParser { +public interface FunctionParser, L extends List> { - Object invoke(@NotNull String function, @NotNull JSONObject currentObject) throws Exception; - Object invoke(@NotNull String function, @NotNull JSONObject currentObject, boolean containRaw) throws Exception; + Object invoke(@NotNull String function, @NotNull M currentObject) throws Exception; + Object invoke(@NotNull String function, @NotNull M currentObject, boolean containRaw) throws Exception; - Parser getParser(); + Parser getParser(); - FunctionParser setParser(Parser parser); + FunctionParser setParser(Parser parser); RequestMethod getMethod(); - FunctionParser setMethod(RequestMethod method); + FunctionParser setMethod(RequestMethod method); String getTag(); - FunctionParser setTag(String tag); + FunctionParser setTag(String tag); int getVersion(); - FunctionParser setVersion(int version); + FunctionParser setVersion(int version); @NotNull - JSONObject getRequest(); - FunctionParser setRequest(@NotNull JSONObject request); + M getRequest(); + FunctionParser setRequest(@NotNull M request); String getKey(); - FunctionParser setKey(String key); + FunctionParser setKey(String key); String getParentPath(); - FunctionParser setParentPath(String parentPath); + FunctionParser setParentPath(String parentPath); String getCurrentName(); - FunctionParser setCurrentName(String currentName); - - @NotNull - JSONObject getCurrentObject(); - FunctionParser setCurrentObject(@NotNull JSONObject currentObject); + FunctionParser setCurrentName(String currentName); + @NotNull + M getCurrentObject(); + FunctionParser setCurrentObject(@NotNull M currentObject); } diff --git a/APIJSONORM/src/main/java/apijson/orm/JSONRequest.java b/APIJSONORM/src/main/java/apijson/orm/JSONRequest.java index 89d17f7d2..ddc22365c 100755 --- a/APIJSONORM/src/main/java/apijson/orm/JSONRequest.java +++ b/APIJSONORM/src/main/java/apijson/orm/JSONRequest.java @@ -10,10 +10,10 @@ import apijson.JSON; import apijson.StringUtil; -/**JSONRequest for Server to replace apijson.JSONRequest, +/**JSONRequest for Server to replace apijson.JSONObject, * put JSON.parseObject(value) and not encode in default cases * @author Lemon - * @see #put(String, Object, boolean) + * @see #put(String, Object) */ public class JSONRequest extends apijson.JSONRequest { private static final long serialVersionUID = 1L; @@ -81,8 +81,13 @@ public Object put(String key, Object value) { return null; } - Object target = JSON.parse(value); - // if (target == null) { // "tag":"User" 报错 + Object target = null; + try { + target = JSON.parseJSON(value); + } catch (Exception e) { + throw new RuntimeException(e); + } + // if (target == null) { // "tag":"User" 报错 // return null; // } return super.put(StringUtil.isNotEmpty(key, true) ? key : value.getClass().getSimpleName() //must handle key here diff --git a/APIJSONORM/src/main/java/apijson/orm/Join.java b/APIJSONORM/src/main/java/apijson/orm/Join.java index 449208bd9..39ca09a61 100644 --- a/APIJSONORM/src/main/java/apijson/orm/Join.java +++ b/APIJSONORM/src/main/java/apijson/orm/Join.java @@ -6,8 +6,7 @@ package apijson.orm; import java.util.List; - -import com.alibaba.fastjson.JSONObject; +import java.util.Map; import apijson.NotNull; import apijson.StringUtil; @@ -15,7 +14,7 @@ /**连表 配置 * @author Lemon */ -public class Join { +public class Join, L extends List> { private String path; // /User/id@ @@ -25,12 +24,12 @@ public class Join { private int count = 1; // 当app join子表,需要返回子表的行数,默认1行; private List onList; // ON User.id = Moment.userId AND ... - private JSONObject request; // { "id@":"/Moment/userId" } - private JSONObject outer; // "join": { " joinConfig; + private SQLConfig cacheConfig; + private SQLConfig outerConfig; public String getPath() { @@ -73,35 +72,35 @@ public void setOnList(List onList) { this.onList = onList; } - public JSONObject getRequest() { + public M getRequest() { return request; } - public void setRequest(JSONObject request) { + public void setRequest(M request) { this.request = request; } - public JSONObject getOuter() { + public M getOuter() { return outer; } - public void setOuter(JSONObject outer) { + public void setOuter(M outer) { this.outer = outer; } - public SQLConfig getJoinConfig() { + public SQLConfig getJoinConfig() { return joinConfig; } - public void setJoinConfig(SQLConfig joinConfig) { + public void setJoinConfig(SQLConfig joinConfig) { this.joinConfig = joinConfig; } - public SQLConfig getCacheConfig() { + public SQLConfig getCacheConfig() { return cacheConfig; } - public void setCacheConfig(SQLConfig cacheConfig) { + public void setCacheConfig(SQLConfig cacheConfig) { this.cacheConfig = cacheConfig; } - public SQLConfig getOuterConfig() { + public SQLConfig getOuterConfig() { return outerConfig; } - public void setOuterConfig(SQLConfig outerConfig) { + public void setOuterConfig(SQLConfig outerConfig) { this.outerConfig = outerConfig; } @@ -162,15 +161,15 @@ public boolean isSQLJoin() { return ! isAppJoin(); } - public static boolean isSQLJoin(Join j) { + public static boolean isSQLJoin(Join j) { return j != null && j.isSQLJoin(); } - public static boolean isAppJoin(Join j) { + public static boolean isAppJoin(Join j) { return j != null && j.isAppJoin(); } - public static boolean isLeftOrRightJoin(Join j) { + public static boolean isLeftOrRightJoin(Join j) { return j != null && j.isLeftOrRightJoin(); } diff --git a/APIJSONORM/src/main/java/apijson/orm/ObjectParser.java b/APIJSONORM/src/main/java/apijson/orm/ObjectParser.java index 205126908..8817886d1 100755 --- a/APIJSONORM/src/main/java/apijson/orm/ObjectParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/ObjectParser.java @@ -8,26 +8,21 @@ import java.util.List; import java.util.Map; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; - -import apijson.NotNull; -import apijson.RequestMethod; +import apijson.*; /**简化Parser,getObject和getArray(getArrayConfig)都能用 * @author Lemon */ -public interface ObjectParser { +public interface ObjectParser, L extends List> { - Parser getParser(); - ObjectParser setParser(Parser parser); + Parser getParser(); + ObjectParser setParser(Parser parser); String getParentPath(); - ObjectParser setParentPath(String parentPath); + ObjectParser setParentPath(String parentPath); - ObjectParser setCache(JSONObject cache); - JSONObject getCache(); + ObjectParser setCache(M cache); + M getCache(); /**解析成员 @@ -37,7 +32,7 @@ public interface ObjectParser { * @return null or this * @throws Exception */ - ObjectParser parse(String name, boolean isReuse) throws Exception; + ObjectParser parse(String name, boolean isReuse) throws Exception; /**调用 parser 的 sqlExecutor 来解析结果 * @param method @@ -49,14 +44,14 @@ public interface ObjectParser { * @return * @throws Exception */ - JSONObject parseResponse(RequestMethod method, String table, String alias, JSONObject request, List joinList, boolean isProcedure) throws Exception; + M parseResponse(RequestMethod method, String table, String alias, M request, List> joinList, boolean isProcedure) throws Exception; /**调用 parser 的 sqlExecutor 来解析结果 * @param config * @param isProcedure * @return * @throws Exception */ - JSONObject parseResponse(SQLConfig config, boolean isProcedure) throws Exception; + M parseResponse(SQLConfig config, boolean isProcedure) throws Exception; @@ -75,7 +70,7 @@ public interface ObjectParser { * @return * @throws Exception */ - JSON onChildParse(int index, String key, JSONObject value, JSON cache) throws Exception; + Object onChildParse(int index, String key, M value, Object cache) throws Exception; /**解析赋值引用 * @param path @@ -89,55 +84,55 @@ public interface ObjectParser { * @param array * @throws Exception */ - void onPUTArrayParse(@NotNull String key, @NotNull JSONArray array) throws Exception; + void onPUTArrayParse(@NotNull String key, @NotNull L array) throws Exception; /**批量新增或修改 POST or PUT Table[]:[{}] * @param key * @param array * @throws Exception */ - void onTableArrayParse(@NotNull String key, @NotNull JSONArray array) throws Exception; + void onTableArrayParse(@NotNull String key, @NotNull L array) throws Exception; /**SQL 配置,for single object * @return {@link #setSQLConfig(int, int, int)} * @throws Exception */ - ObjectParser setSQLConfig() throws Exception; + ObjectParser setSQLConfig() throws Exception; /**SQL 配置 * @return * @throws Exception */ - ObjectParser setSQLConfig(int count, int page, int position) throws Exception; + ObjectParser setSQLConfig(int count, int page, int position) throws Exception; /**执行 SQL * @return * @throws Exception */ - ObjectParser executeSQL() throws Exception; + ObjectParser executeSQL() throws Exception; /** * @return * @throws Exception */ - JSONObject onSQLExecute() throws Exception; + M onSQLExecute() throws Exception; /** * @return response * @throws Exception */ - JSONObject response() throws Exception; + M response() throws Exception; void onFunctionResponse(String type) throws Exception; void onChildResponse() throws Exception; - SQLConfig newSQLConfig(boolean isProcedure) throws Exception; - SQLConfig newSQLConfig(RequestMethod method, String table, String alias, JSONObject request, List joinList, boolean isProcedure) throws Exception; + SQLConfig newSQLConfig(boolean isProcedure) throws Exception; + SQLConfig newSQLConfig(RequestMethod method, String table, String alias, M request, List> joinList, boolean isProcedure) throws Exception; /** * response has the final value after parse (and query if isTableKey) @@ -150,7 +145,7 @@ public interface ObjectParser { void recycle(); - ObjectParser setMethod(RequestMethod method); + ObjectParser setMethod(RequestMethod method); RequestMethod getMethod(); @@ -158,15 +153,15 @@ public interface ObjectParser { String getPath(); String getTable(); String getAlias(); - SQLConfig getArrayConfig(); + SQLConfig getArrayConfig(); - SQLConfig getSQLConfig(); - JSONObject getResponse(); - JSONObject getSqlRequest(); - JSONObject getSqlResponse(); + SQLConfig getSQLConfig(); + M getResponse(); + M getSQLRequest(); + M getSQLResponse(); Map getCustomMap(); Map> getFunctionMap(); - Map getChildMap(); + Map getChildMap(); } diff --git a/APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java b/APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java index 952c41e3b..243acf048 100755 --- a/APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java +++ b/APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java @@ -5,13 +5,13 @@ package apijson.orm; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; +import java.util.List; +import java.util.Map; /** * @author Lemon */ -public abstract class OnParseCallback { +public abstract class OnParseCallback, L extends List> { /** @@ -43,7 +43,7 @@ protected Object onParseObject(String key, Object to, Object ro) throws Exceptio * @return * @throws Exception */ - protected JSONObject onParseJSONObject(String key, JSONObject tobj, JSONObject robj) throws Exception { + protected M onParseJSONObject(String key, M tobj, M robj) throws Exception { return robj; } @@ -54,7 +54,7 @@ protected JSONObject onParseJSONObject(String key, JSONObject tobj, JSONObject r * @return * @throws Exception */ - protected JSONArray onParseJSONArray(String key, JSONArray tarray, JSONArray rarray) throws Exception { + protected L onParseJSONArray(String key, L tarray, L rarray) throws Exception { return rarray; } diff --git a/APIJSONORM/src/main/java/apijson/orm/Pair.java b/APIJSONORM/src/main/java/apijson/orm/Pair.java index 71ed7eb2c..a4bb22030 100755 --- a/APIJSONORM/src/main/java/apijson/orm/Pair.java +++ b/APIJSONORM/src/main/java/apijson/orm/Pair.java @@ -9,9 +9,6 @@ import java.util.HashMap; import java.util.Map; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; - import apijson.StringUtil; /**key:value @@ -37,8 +34,8 @@ public class Pair extends Entry { CLASS_MAP.put(String.class.getSimpleName(), String.class); CLASS_MAP.put(Collection.class.getSimpleName(), Collection.class);//不允许指定 CLASS_MAP.put(Map.class.getSimpleName(), Map.class);//不允许指定 - CLASS_MAP.put(JSONObject.class.getSimpleName(), JSONObject.class);//必须有,Map中没有getLongValue等方法 - CLASS_MAP.put(JSONArray.class.getSimpleName(), JSONArray.class);//必须有,Collection中没有getJSONObject等方法 +// CLASS_MAP.put(JSONObject.class.getSimpleName(), JSONObject.class);//必须有,Map中没有getLongValue等方法 +// CLASS_MAP.put(JSONArray.class.getSimpleName(), JSONArray.class);//必须有,Collection中没有getJSONObject等方法 } @@ -60,14 +57,14 @@ public static boolean isCorrect(Entry pair) { } /** - * @param pair * @return */ public String toPairString() { return toPairString(getKey(), getValue()); } /** - * @param pair + * @param typeKey + * @param valueKey * @return */ public static String toPairString(String typeKey, String valueKey) { diff --git a/APIJSONORM/src/main/java/apijson/orm/Parser.java b/APIJSONORM/src/main/java/apijson/orm/Parser.java index a272fc27a..dd7a21276 100755 --- a/APIJSONORM/src/main/java/apijson/orm/Parser.java +++ b/APIJSONORM/src/main/java/apijson/orm/Parser.java @@ -7,68 +7,66 @@ import java.sql.SQLException; import java.sql.Savepoint; +import java.util.List; +import java.util.Map; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; - -import apijson.NotNull; -import apijson.RequestMethod; +import apijson.*; /**解析器 * @author Lemon */ -public interface Parser { +public interface Parser, L extends List> { @NotNull Visitor getVisitor(); - Parser setVisitor(@NotNull Visitor visitor); + Parser setVisitor(@NotNull Visitor visitor); @NotNull RequestMethod getMethod(); - Parser setMethod(@NotNull RequestMethod method); + Parser setMethod(@NotNull RequestMethod method); int getVersion(); - Parser setVersion(int version); + Parser setVersion(int version); String getTag(); - Parser setTag(String tag); + Parser setTag(String tag); - JSONObject getRequest(); - Parser setRequest(JSONObject request); + M getRequest(); + Parser setRequest(M request); - Parser setNeedVerify(boolean needVerify); + Parser setNeedVerify(boolean needVerify); boolean isNeedVerifyLogin(); - Parser setNeedVerifyLogin(boolean needVerifyLogin); + Parser setNeedVerifyLogin(boolean needVerifyLogin); boolean isNeedVerifyRole(); - Parser setNeedVerifyRole(boolean needVerifyRole); + Parser setNeedVerifyRole(boolean needVerifyRole); boolean isNeedVerifyContent(); - Parser setNeedVerifyContent(boolean needVerifyContent); + Parser setNeedVerifyContent(boolean needVerifyContent); String parse(String request); - String parse(JSONObject request); + String parse(M request); - JSONObject parseResponse(String request); - JSONObject parseResponse(JSONObject request); + M parseResponse(String request); + M parseResponse(M request); - // 没必要性能还差 JSONObject parseCorrectResponse(String table, JSONObject response) throws Exception; + // 没必要性能还差 JSONRequest parseCorrectResponse(String table, JSONRequest response) throws Exception; - JSONObject parseCorrectRequest() throws Exception; - - JSONObject parseCorrectRequest(RequestMethod method, String tag, int version, String name, JSONObject request, - int maxUpdateCount, SQLCreator creator) throws Exception; - + M parseCorrectRequest() throws Exception; - JSONObject getStructure(String table, String method, String tag, int version) throws Exception; + M parseCorrectRequest(RequestMethod method, String tag, int version, String name, M request, + int maxUpdateCount, SQLCreator creator) throws Exception; + + + Map getStructure(String table, String method, String tag, int version) throws Exception; - JSONObject onObjectParse(JSONObject request, String parentPath, String name, SQLConfig arrayConfig, boolean isSubquery, JSONObject cache) throws Exception; + M onObjectParse(M request, String parentPath, String name, SQLConfig arrayConfig, boolean isSubquery, M cache) throws Exception; - JSONArray onArrayParse(JSONObject request, String parentPath, String name, boolean isSubquery, JSONArray cache) throws Exception; + L onArrayParse(M request, String parentPath, String name, boolean isSubquery, L cache) throws Exception; /**解析远程函数 * @param key @@ -79,9 +77,9 @@ JSONObject parseCorrectRequest(RequestMethod method, String tag, int version, St * @return * @throws Exception */ - Object onFunctionParse(String key, String function, String parentPath, String currentName, JSONObject currentObject, boolean containRaw) throws Exception; + Object onFunctionParse(String key, String function, String parentPath, String currentName, M currentObject, boolean containRaw) throws Exception; - ObjectParser createObjectParser(JSONObject request, String parentPath, SQLConfig arrayConfig, boolean isSubquery, boolean isTable, boolean isArrayMainTable) throws Exception; + ObjectParser createObjectParser(M request, String parentPath, SQLConfig arrayConfig, boolean isSubquery, boolean isTable, boolean isArrayMainTable) throws Exception; int getMinQueryPage(); int getMaxQueryPage(); @@ -101,12 +99,12 @@ JSONObject parseCorrectRequest(RequestMethod method, String tag, int version, St void onVerifyLogin() throws Exception; void onVerifyContent() throws Exception; - void onVerifyRole(SQLConfig config) throws Exception; + void onVerifyRole(SQLConfig config) throws Exception; - JSONObject executeSQL(SQLConfig config, boolean isSubquery) throws Exception; + M executeSQL(SQLConfig config, boolean isSubquery) throws Exception; - SQLExecutor getSQLExecutor(); - Verifier getVerifier(); + SQLExecutor getSQLExecutor(); + Verifier getVerifier(); Boolean getGlobalFormat(); @@ -129,5 +127,7 @@ JSONObject parseCorrectRequest(RequestMethod method, String tag, int version, St void commit() throws SQLException; void close(); + M newSuccessResult(); + M newErrorResult(Exception e); } diff --git a/APIJSONORM/src/main/java/apijson/orm/ParserCreator.java b/APIJSONORM/src/main/java/apijson/orm/ParserCreator.java index 4da410b46..d6eb1c7db 100755 --- a/APIJSONORM/src/main/java/apijson/orm/ParserCreator.java +++ b/APIJSONORM/src/main/java/apijson/orm/ParserCreator.java @@ -7,14 +7,17 @@ import apijson.NotNull; +import java.util.List; +import java.util.Map; + /**SQL相关创建器 * @author Lemon */ -public interface ParserCreator { +public interface ParserCreator, L extends List> { @NotNull - Parser createParser(); + Parser createParser(); @NotNull - FunctionParser createFunctionParser(); + FunctionParser createFunctionParser(); } diff --git a/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java index e86fd0fc0..44d4264be 100755 --- a/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java +++ b/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java @@ -15,7 +15,7 @@ /**SQL配置 * @author Lemon */ -public interface SQLConfig { +public interface SQLConfig, L extends List> { String DATABASE_MYSQL = "MYSQL"; // https://www.mysql.com String DATABASE_POSTGRESQL = "POSTGRESQL"; // https://www.postgresql.org @@ -62,21 +62,21 @@ public interface SQLConfig { int TYPE_ITEM = 1; int TYPE_ITEM_CHILD_0 = 2; - Parser getParser(); + Parser gainParser(); - SQLConfig setParser(Parser parser); + SQLConfig setParser(Parser parser); - ObjectParser getObjectParser(); + ObjectParser gainObjectParser(); - SQLConfig setObjectParser(ObjectParser objectParser); + SQLConfig setObjectParser(ObjectParser objectParser); int getVersion(); - SQLConfig setVersion(int version); + SQLConfig setVersion(int version); String getTag(); - SQLConfig setTag(String tag); + SQLConfig setTag(String tag); boolean isTSQL(); boolean isMSQL(); @@ -147,11 +147,11 @@ public interface SQLConfig { * MYSQL: 8.0, 5.7, 5.6 等; PostgreSQL: 11, 10, 9.6 等 * @return */ - String getDBVersion(); + String gainDBVersion(); @NotNull - default int[] getDBVersionNums() { - String dbVersion = StringUtil.noBlank(getDBVersion()); + default int[] gainDBVersionNums() { + String dbVersion = StringUtil.noBlank(gainDBVersion()); if (dbVersion.isEmpty()) { return new int[]{0}; } @@ -173,170 +173,170 @@ default int[] getDBVersionNums() { /**获取数据库地址 * @return */ - String getDBUri(); + String gainDBUri(); /**获取数据库账号 * @return */ - String getDBAccount(); + String gainDBAccount(); /**获取数据库密码 * @return */ - String getDBPassword(); + String gainDBPassword(); /**获取SQL语句 * @return * @throws Exception */ - String getSQL(boolean prepared) throws Exception; + String gainSQL(boolean prepared) throws Exception; boolean isTest(); - SQLConfig setTest(boolean test); + SQLConfig setTest(boolean test); int getType(); - SQLConfig setType(int type); + SQLConfig setType(int type); int getCount(); - SQLConfig setCount(int count); + SQLConfig setCount(int count); int getPage(); - SQLConfig setPage(int page); + SQLConfig setPage(int page); int getQuery(); - SQLConfig setQuery(int query); + SQLConfig setQuery(int query); Boolean getCompat(); - SQLConfig setCompat(Boolean compat); + SQLConfig setCompat(Boolean compat); int getPosition(); - SQLConfig setPosition(int position); + SQLConfig setPosition(int position); int getCache(); - SQLConfig setCache(int cache); + SQLConfig setCache(int cache); boolean isExplain(); - SQLConfig setExplain(boolean explain); + SQLConfig setExplain(boolean explain); RequestMethod getMethod(); - SQLConfig setMethod(RequestMethod method); + SQLConfig setMethod(RequestMethod method); Object getId(); - SQLConfig setId(Object id); + SQLConfig setId(Object id); Object getIdIn(); - SQLConfig setIdIn(Object idIn); + SQLConfig setIdIn(Object idIn); Object getUserId(); - SQLConfig setUserId(Object userId); + SQLConfig setUserId(Object userId); Object getUserIdIn(); - SQLConfig setUserIdIn(Object userIdIn); + SQLConfig setUserIdIn(Object userIdIn); String getRole(); - SQLConfig setRole(String role); + SQLConfig setRole(String role); public boolean isDistinct(); - public SQLConfig setDistinct(boolean distinct); + public SQLConfig setDistinct(boolean distinct); String getDatabase(); - SQLConfig setDatabase(String database); + SQLConfig setDatabase(String database); String getSQLNamespace(); String getNamespace(); - SQLConfig setNamespace(String namespace); + SQLConfig setNamespace(String namespace); - String getSQLCatalog(); + String gainSQLCatalog(); String getCatalog(); - SQLConfig setCatalog(String catalog); + SQLConfig setCatalog(String catalog); - String getSQLSchema(); + String gainSQLSchema(); String getSchema(); - SQLConfig setSchema(String schema); + SQLConfig setSchema(String schema); String getDatasource(); - SQLConfig setDatasource(String datasource); + SQLConfig setDatasource(String datasource); String getQuote(); List getJson(); - SQLConfig setJson(List json); + SQLConfig setJson(List json); /**请求传进来的Table名 * @return - * @see {@link #getSQLTable()} + * @see {@link #gainSQLTable()} */ String getTable(); - SQLConfig setTable(String table); + SQLConfig setTable(String table); /**数据库里的真实Table名 * 通过 {@link AbstractSQLConfig.TABLE_KEY_MAP} 映射 * @return */ - String getSQLTable(); + String gainSQLTable(); - String getTablePath(); + String gainTablePath(); Map getKeyMap(); - SQLConfig setKeyMap(Map keyMap); + SQLConfig setKeyMap(Map keyMap); List getRaw(); - SQLConfig setRaw(List raw); + SQLConfig setRaw(List raw); - Subquery getFrom(); - SQLConfig setFrom(Subquery from); + Subquery getFrom(); + SQLConfig setFrom(Subquery from); List getColumn(); - SQLConfig setColumn(List column); + SQLConfig setColumn(List column); List> getValues(); - SQLConfig setValues(List> values); + SQLConfig setValues(List> values); Map getContent(); - SQLConfig setContent(Map content); + SQLConfig setContent(Map content); Map> getCombineMap(); - SQLConfig setCombineMap(Map> combineMap); + SQLConfig setCombineMap(Map> combineMap); String getCombine(); - SQLConfig setCombine(String combine); + SQLConfig setCombine(String combine); Map getCast(); - SQLConfig setCast(Map cast); + SQLConfig setCast(Map cast); List getNull(); - SQLConfig setNull(List nulls); + SQLConfig setNull(List nulls); Map getWhere(); - SQLConfig setWhere(Map where); + SQLConfig setWhere(Map where); String getGroup(); - SQLConfig setGroup(String group); + SQLConfig setGroup(String group); Map getHaving(); - SQLConfig setHaving(Map having); + SQLConfig setHaving(Map having); String getHavingCombine(); - SQLConfig setHavingCombine(String havingCombine); + SQLConfig setHavingCombine(String havingCombine); String getSample(); - SQLConfig setSample(String order); + SQLConfig setSample(String order); String getLatest(); - SQLConfig setLatest(String latest); + SQLConfig setLatest(String latest); String getPartition(); - SQLConfig setPartition(String partition); + SQLConfig setPartition(String partition); String getFill(); - SQLConfig setFill(String fill); + SQLConfig setFill(String fill); String getOrder(); - SQLConfig setOrder(String order); + SQLConfig setOrder(String order); /** * exactMatch = false @@ -355,65 +355,62 @@ default int[] getDBVersionNums() { * @param value * @return */ - SQLConfig putWhere(String key, Object value, boolean prior); + SQLConfig putWhere(String key, Object value, boolean prior); boolean isPrepared(); - SQLConfig setPrepared(boolean prepared); + SQLConfig setPrepared(boolean prepared); boolean isMain(); - SQLConfig setMain(boolean main); + SQLConfig setMain(boolean main); List getPreparedValueList(); - SQLConfig setPreparedValueList(List preparedValueList); + SQLConfig setPreparedValueList(List preparedValueList); String getAlias(); - SQLConfig setAlias(String alias); + SQLConfig setAlias(String alias); - default String getTableKey() { + default String gainTableKey() { String alias = getAlias(); return getTable() + (StringUtil.isEmpty(alias) ? "" : ":" + alias); } - default String getSQLAlias() { - return getSQLAlias(getTable(), getAlias()); + default String gainSQLAlias() { + return gainSQLAlias(getTable(), getAlias()); } - static String getSQLAlias(@NotNull String table, String alias) { + static String gainSQLAlias(@NotNull String table, String alias) { // 这里不用 : $ 等符号,因为部分数据库/引擎似乎不支持 `key`, "key", [key] 等避免关键词冲突的方式,只能使用符合变量命名的表别名 return StringUtil.isEmpty(alias) ? table : table + "__" + alias; // 带上原表名,避免 alias 和其它表名/字段名冲突 } - String getWhereString(boolean hasPrefix) throws Exception; + String gainWhereString(boolean hasPrefix) throws Exception; - String getRawSQL(String key, Object value) throws Exception; - String getRawSQL(String key, Object value, boolean throwWhenMissing) throws Exception; + String gainRawSQL(String key, Object value) throws Exception; + String gainRawSQL(String key, Object value, boolean throwWhenMissing) throws Exception; boolean isKeyPrefix(); - SQLConfig setKeyPrefix(boolean keyPrefix); + SQLConfig setKeyPrefix(boolean keyPrefix); - - List getJoinList(); - - SQLConfig setJoinList(List joinList); + List> getJoinList(); + SQLConfig setJoinList(List> joinList); boolean hasJoin(); - String getSubqueryString(Subquery subquery) throws Exception; - - SQLConfig setProcedure(String procedure); + String gainSubqueryString(Subquery subquery) throws Exception; + SQLConfig setProcedure(String procedure); List getWithAsExprPreparedValueList(); - SQLConfig setWithAsExprPreparedValueList(List withAsExprePreparedValueList); + SQLConfig setWithAsExprPreparedValueList(List withAsExprePreparedValueList); boolean isFakeDelete(); diff --git a/APIJSONORM/src/main/java/apijson/orm/SQLCreator.java b/APIJSONORM/src/main/java/apijson/orm/SQLCreator.java index 11d7d2c89..bb5af96d8 100755 --- a/APIJSONORM/src/main/java/apijson/orm/SQLCreator.java +++ b/APIJSONORM/src/main/java/apijson/orm/SQLCreator.java @@ -7,14 +7,17 @@ import apijson.NotNull; +import java.util.List; +import java.util.Map; + /**SQL相关创建器 * @author Lemon */ -public interface SQLCreator { +public interface SQLCreator, L extends List> { @NotNull - SQLConfig createSQLConfig(); + SQLConfig createSQLConfig(); @NotNull - SQLExecutor createSQLExecutor(); + SQLExecutor createSQLExecutor(); } diff --git a/APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java b/APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java index 2805682e8..a4467af8e 100755 --- a/APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java +++ b/APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java @@ -12,31 +12,30 @@ import java.sql.Savepoint; import java.sql.Statement; import java.util.List; +import java.util.Map; -import com.alibaba.fastjson.JSONObject; - -import apijson.NotNull; +import apijson.*; /**executor for query(read) or update(write) MySQL database * @author Lemon */ -public interface SQLExecutor { - Parser getParser(); - SQLExecutor setParser(Parser parser); +public interface SQLExecutor, L extends List> { + Parser getParser(); + SQLExecutor setParser(Parser parser); /**保存缓存 * @param sql * @param list * @param config */ - void putCache(String sql, List list, SQLConfig config); + void putCache(String sql, List list, SQLConfig config); /**获取缓存 * @param sql * @param config * @return */ - List getCache(String sql, SQLConfig config); + List getCache(String sql, SQLConfig config); /**获取缓存 * @param sql @@ -44,13 +43,13 @@ public interface SQLExecutor { * @param config * @return */ - JSONObject getCacheItem(String sql, int position, SQLConfig config); + M getCacheItem(String sql, int position, SQLConfig config); /**移除缓存 * @param sql * @param config */ - void removeCache(String sql, SQLConfig config); + void removeCache(String sql, SQLConfig config); /**执行SQL * @param config @@ -58,7 +57,7 @@ public interface SQLExecutor { * @return * @throws Exception */ - JSONObject execute(@NotNull SQLConfig config, boolean unknownType) throws Exception; + M execute(@NotNull SQLConfig config, boolean unknownType) throws Exception; //executeQuery和executeUpdate这两个函数因为返回类型不同,所以不好合并 /**执行查询 @@ -66,37 +65,37 @@ public interface SQLExecutor { * @return * @throws SQLException */ - default ResultSet executeQuery(@NotNull SQLConfig config) throws Exception { + default ResultSet executeQuery(@NotNull SQLConfig config) throws Exception { return executeQuery(config, null); } - ResultSet executeQuery(@NotNull SQLConfig config, String sql) throws Exception; + ResultSet executeQuery(@NotNull SQLConfig config, String sql) throws Exception; /**执行增、删、改 * @param config * @return * @throws SQLException */ - default int executeUpdate(@NotNull SQLConfig config) throws Exception { + default int executeUpdate(@NotNull SQLConfig config) throws Exception { return executeUpdate(config, null); } - int executeUpdate(@NotNull SQLConfig config, String sql) throws Exception; + int executeUpdate(@NotNull SQLConfig config, String sql) throws Exception; /**判断是否为JSON类型 * @param config * @param rsmd * @param position - * @param lable + * @param label * @return */ - boolean isJSONType(@NotNull SQLConfig config, ResultSetMetaData rsmd, int position, String lable); + boolean isJSONType(@NotNull SQLConfig config, ResultSetMetaData rsmd, int position, String label); - Connection getConnection(@NotNull SQLConfig config) throws Exception; - default Statement getStatement(@NotNull SQLConfig config) throws Exception { + Connection getConnection(@NotNull SQLConfig config) throws Exception; + default Statement getStatement(@NotNull SQLConfig config) throws Exception { return getStatement(config, null); } - Statement getStatement(@NotNull SQLConfig config, String sql) throws Exception; + Statement getStatement(@NotNull SQLConfig config, String sql) throws Exception; int getTransactionIsolation(); void setTransactionIsolation(int transactionIsolation); diff --git a/APIJSONORM/src/main/java/apijson/orm/Subquery.java b/APIJSONORM/src/main/java/apijson/orm/Subquery.java index de8603b6d..20e5cc389 100644 --- a/APIJSONORM/src/main/java/apijson/orm/Subquery.java +++ b/APIJSONORM/src/main/java/apijson/orm/Subquery.java @@ -5,79 +5,72 @@ package apijson.orm; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.annotation.JSONField; +import apijson.JSONField; + +import java.util.List; +import java.util.Map; /**子查询 配置 * @author Lemon */ -public class Subquery { +public class Subquery, L extends List> { private String path; // []/0/User private String originKey; //id{}@ - private JSONObject originValue; // { "from": "Comment", "Comment": {...} } + private M originValue; // { "from": "Comment", "Comment": {...} } private String from; // Comment private String range; // ANY, ALL private String key; //id{} - private SQLConfig config; + private SQLConfig config; - @JSONField(serialize = false) //解决泄漏 SQLConfig 里的 dbPassword 等 - public String getPath() { + public String gainPath() { return path; } public void setPath(String path) { this.path = path; } - @JSONField(serialize = false) //解决泄漏 SQLConfig 里的 dbPassword 等 - public String getOriginKey() { + public String gainOriginKey() { return originKey; } public void setOriginKey(String originKey) { this.originKey = originKey; } - @JSONField(serialize = false) //解决泄漏 SQLConfig 里的 dbPassword 等 - public JSONObject getOriginValue() { + public M gainOriginValue() { return originValue; } - public void setOriginValue(JSONObject originValue) { + public void setOriginValue(M originValue) { this.originValue = originValue; } - @JSONField(serialize = false) //解决泄漏 SQLConfig 里的 dbPassword 等 - public String getFrom() { + public String gainFrom() { return from; } public void setFrom(String from) { this.from = from; } - @JSONField(serialize = false) //解决泄漏 SQLConfig 里的 dbPassword 等 - public String getRange() { + public String gainRange() { return range; } public void setRange(String range) { this.range = range; } - @JSONField(serialize = false) //解决泄漏 SQLConfig 里的 dbPassword 等 - public String getKey() { + public String gainKey() { return key; } public void setKey(String key) { this.key = key; } - @JSONField(serialize = false) //解决泄漏 SQLConfig 里的 dbPassword 等 - public SQLConfig getConfig() { + public SQLConfig gainConfig() { return config; } - public void setConfig(SQLConfig config) { + public void setConfig(SQLConfig config) { this.config = config; } - - } diff --git a/APIJSONORM/src/main/java/apijson/orm/Verifier.java b/APIJSONORM/src/main/java/apijson/orm/Verifier.java index a4ab72055..8ee508e11 100755 --- a/APIJSONORM/src/main/java/apijson/orm/Verifier.java +++ b/APIJSONORM/src/main/java/apijson/orm/Verifier.java @@ -5,15 +5,15 @@ package apijson.orm; -import com.alibaba.fastjson.JSONObject; +import java.util.List; +import java.util.Map; -import apijson.NotNull; -import apijson.RequestMethod; +import apijson.*; /**校验器(权限、请求参数、返回结果等) * @author Lemon */ -public interface Verifier { +public interface Verifier, L extends List> { /**验证权限是否通过 @@ -21,7 +21,7 @@ public interface Verifier { * @return * @throws Exception */ - boolean verifyAccess(SQLConfig config) throws Exception; + boolean verifyAccess(SQLConfig config) throws Exception; /**校验请求使用的角色,角色不好判断,让访问者发过来角色名,OWNER,CONTACT,ADMIN等 @@ -33,7 +33,7 @@ public interface Verifier { * @throws Exception * @see {@link apijson.JSONObject#KEY_ROLE} */ - void verifyRole(SQLConfig config, String table, RequestMethod method, String role) throws Exception; + void verifyRole(SQLConfig config, String table, RequestMethod method, String role) throws Exception; /**登录校验 * @throws Exception @@ -75,8 +75,8 @@ public interface Verifier { * @return * @throws Exception */ - JSONObject verifyRequest(RequestMethod method, String name, JSONObject target, JSONObject request, - int maxUpdateCount, String globalDatabase, String globalSchema, SQLCreator creator) throws Exception; + M verifyRequest(RequestMethod method, String name, M target, M request, + int maxUpdateCount, String globalDatabase, String globalSchema, SQLCreator creator) throws Exception; /**验证返回结果的数据和结构 * @param method @@ -90,20 +90,19 @@ JSONObject verifyRequest(RequestMethod method, String name, JSONObject target, J * @return * @throws Exception */ - JSONObject verifyResponse( - RequestMethod method, String name, JSONObject target, JSONObject response, - String database, String schema, SQLCreator creator, OnParseCallback callback + M verifyResponse( + RequestMethod method, String name, M target, M response, + String database, String schema, SQLCreator creator, OnParseCallback callback ) throws Exception; @NotNull - Parser createParser(); + Parser createParser(); @NotNull Visitor getVisitor(); - Verifier setVisitor(@NotNull Visitor visitor); + Verifier setVisitor(@NotNull Visitor visitor); - String getVisitorIdKey(SQLConfig config); - + String getVisitorIdKey(SQLConfig config); } diff --git a/APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java b/APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java index 0caa6f8b1..a3c51694a 100644 --- a/APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java +++ b/APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java @@ -7,11 +7,14 @@ import apijson.NotNull; +import java.util.List; +import java.util.Map; + /**验证器相关创建器 * @author Lemon */ -public interface VerifierCreator { +public interface VerifierCreator, L extends List> { @NotNull - Verifier createVerifier(); + Verifier createVerifier(); } diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/CommonException.java b/APIJSONORM/src/main/java/apijson/orm/exception/CommonException.java index 0acced3be..565cef453 100755 --- a/APIJSONORM/src/main/java/apijson/orm/exception/CommonException.java +++ b/APIJSONORM/src/main/java/apijson/orm/exception/CommonException.java @@ -147,7 +147,7 @@ public CommonException(Throwable t, String environment) { } - public static Exception wrap(Exception e, SQLConfig config) { + public static Exception wrap(Exception e, SQLConfig config) { if (Log.DEBUG == false && e instanceof SQLException) { return new SQLException("数据库驱动执行异常SQLException,非 Log.DEBUG 模式下不显示详情,避免泄漏真实模式名、表名等隐私信息", e); } @@ -158,10 +158,10 @@ public static Exception wrap(Exception e, SQLConfig config) { // msg != null && msg.contains(Log.KEY_SYSTEM_INFO_DIVIDER) == false) { try { String db = config == null ? AbstractSQLConfig.DEFAULT_DATABASE : (config instanceof AbstractSQLConfig - ? ((AbstractSQLConfig) config).getSQLDatabase() : config.getDatabase() + ? ((AbstractSQLConfig) config).gainSQLDatabase() : config.getDatabase() ); - String dbVersion = config == null ? null : config.getDBVersion(); + String dbVersion = config == null ? null : config.gainDBVersion(); if (StringUtil.isEmpty(dbVersion)) { dbVersion = ""; } diff --git a/APIJSONORM/src/main/java/apijson/orm/script/JSR223ScriptExecutor.java b/APIJSONORM/src/main/java/apijson/orm/script/JSR223ScriptExecutor.java index a657075d3..59dba0117 100644 --- a/APIJSONORM/src/main/java/apijson/orm/script/JSR223ScriptExecutor.java +++ b/APIJSONORM/src/main/java/apijson/orm/script/JSR223ScriptExecutor.java @@ -1,6 +1,7 @@ package apijson.orm.script; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -11,20 +12,18 @@ import javax.script.ScriptEngineManager; import javax.script.SimpleBindings; -import com.alibaba.fastjson.JSONObject; - import apijson.orm.AbstractFunctionParser; /** * JSR223 script engine的统一实现抽象类 */ -public abstract class JSR223ScriptExecutor implements ScriptExecutor { +public abstract class JSR223ScriptExecutor, L extends List> implements ScriptExecutor { protected ScriptEngine scriptEngine; private final Map compiledScriptMap = new ConcurrentHashMap<>(); @Override - public ScriptExecutor init() { + public ScriptExecutor init() { ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); scriptEngine = scriptEngineManager.getEngineByName(scriptEngineName()); return this; @@ -32,7 +31,7 @@ public ScriptExecutor init() { protected abstract String scriptEngineName(); - protected abstract Object extendParameter(AbstractFunctionParser parser, JSONObject currentObject, String methodName, Object[] args); + protected abstract Object extendParameter(AbstractFunctionParser parser, Map currentObject, String methodName, Object[] args); protected abstract boolean isLockScript(String methodName); @@ -52,7 +51,7 @@ public void load(String name, String script) { } @Override - public Object execute(AbstractFunctionParser parser, JSONObject currentObject, String methodName, Object[] args) throws Exception { + public Object execute(AbstractFunctionParser parser, Map currentObject, String methodName, Object[] args) throws Exception { CompiledScript compiledScript = compiledScriptMap.get(methodName); Bindings bindings = new SimpleBindings(); // 往脚本上下文里放入元数据 diff --git a/APIJSONORM/src/main/java/apijson/orm/script/JavaScriptExecutor.java b/APIJSONORM/src/main/java/apijson/orm/script/JavaScriptExecutor.java index 893ac6d11..3f636b64a 100644 --- a/APIJSONORM/src/main/java/apijson/orm/script/JavaScriptExecutor.java +++ b/APIJSONORM/src/main/java/apijson/orm/script/JavaScriptExecutor.java @@ -1,13 +1,14 @@ package apijson.orm.script; -import com.alibaba.fastjson.JSONObject; +import java.util.List; +import java.util.Map; import apijson.orm.AbstractFunctionParser; /** * JavaScript脚本语言的执行器实现 */ -public class JavaScriptExecutor extends JSR223ScriptExecutor { +public class JavaScriptExecutor, L extends List> extends JSR223ScriptExecutor { @Override protected String scriptEngineName() { @@ -15,7 +16,7 @@ protected String scriptEngineName() { } @Override - protected Object extendParameter(AbstractFunctionParser parser, JSONObject currentObject, String methodName, Object[] args) { + protected Object extendParameter(AbstractFunctionParser parser, Map currentObject, String methodName, Object[] args) { return null; } diff --git a/APIJSONORM/src/main/java/apijson/orm/script/ScriptExecutor.java b/APIJSONORM/src/main/java/apijson/orm/script/ScriptExecutor.java index b9296d153..c90ce7b15 100644 --- a/APIJSONORM/src/main/java/apijson/orm/script/ScriptExecutor.java +++ b/APIJSONORM/src/main/java/apijson/orm/script/ScriptExecutor.java @@ -1,16 +1,17 @@ package apijson.orm.script; -import com.alibaba.fastjson.JSONObject; +import java.util.List; +import java.util.Map; import apijson.orm.AbstractFunctionParser; -public interface ScriptExecutor { +public interface ScriptExecutor, L extends List> { - ScriptExecutor init(); + ScriptExecutor init(); void load(String name, String script); - Object execute(AbstractFunctionParser parser, JSONObject currentObject, String methodName, Object[] args) throws Exception; + Object execute(AbstractFunctionParser parser, Map currentObject, String methodName, Object[] args) throws Exception; void cleanCache();