diff --git a/APIJSONORM/pom.xml b/APIJSONORM/pom.xml index 8b36d0da..5f869837 100644 --- a/APIJSONORM/pom.xml +++ b/APIJSONORM/pom.xml @@ -5,7 +5,7 @@ com.github.Tencent APIJSON - 8.1.3 + 8.1.6 jar APIJSONORM diff --git a/APIJSONORM/src/main/java/apijson/Log.java b/APIJSONORM/src/main/java/apijson/Log.java index d301cdf0..5a4d2169 100755 --- a/APIJSONORM/src/main/java/apijson/Log.java +++ b/APIJSONORM/src/main/java/apijson/Log.java @@ -21,7 +21,7 @@ public class Log { public static String LEVEL = LEVEL_WARN; - public static final String VERSION = "8.1.5"; + public static final String VERSION = "8.1.6"; 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/AbstractObjectParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java index c49c9cd2..c4f7c5ff 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java @@ -720,7 +720,7 @@ public void onPUTArrayParse(@NotNull String key, @NotNull L array) throws Except if (apijson.JSON.isBoolOrNumOrStr(target)) { throw new NullPointerException("PUT " + path + ", " + realKey + " 类型为 " + target.getClass().getSimpleName() + "," + "不支持 Boolean, String, Number 等类型字段使用 'key+': [] 或 'key-': [] !" - + "对应字段在数据库的值必须为 L, JSONRequest 中的一种!" + + "对应字段在数据库的值必须为 JSONArray, JSONObject 中的一种!" + "值为 JSONRequest 类型时传参必须是 'key+': [{'key': value, 'key2': value2}] 或 'key-': ['key', 'key2'] !" ); } @@ -734,7 +734,7 @@ public void onPUTArrayParse(@NotNull String key, @NotNull L array) throws Except if (isAdd == false) { throw new NullPointerException("PUT " + path + ", " + realKey + (target == null ? " 值为 null,不支持移除!" : " 类型为 " + target.getClass().getSimpleName() + ",不支持这样移除!") - + "对应字段在数据库的值必须为 L, JSONRequest 中的一种,且 key- 移除时,本身的值不能为 null!" + + "对应字段在数据库的值必须为 JSONArray, JSONObject 中的一种,且 key- 移除时,本身的值不能为 null!" + "值为 JSONRequest 类型时传参必须是 'key+': [{'key': value, 'key2': value2}] 或 'key-': ['key', 'key2'] !" ); } diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java index e2403122..defccc93 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java @@ -527,6 +527,28 @@ public M parseResponse(M request) { return extendErrorResult(requestObject, e, requestMethod, getRequestURL(), isRoot); } + try { + setGlobalDatabase(getString(requestObject, KEY_DATABASE)); + setGlobalDatasource(getString(requestObject, KEY_DATASOURCE)); + setGlobalNamespace(getString(requestObject, KEY_NAMESPACE)); + setGlobalCatalog(getString(requestObject, KEY_CATALOG)); + setGlobalSchema(getString(requestObject, KEY_SCHEMA)); + + setGlobalExplain(getBoolean(requestObject, KEY_EXPLAIN)); + setGlobalCache(getString(requestObject, KEY_CACHE)); + + requestObject.remove(KEY_DATABASE); + requestObject.remove(KEY_DATASOURCE); + requestObject.remove(KEY_NAMESPACE); + requestObject.remove(KEY_CATALOG); + requestObject.remove(KEY_SCHEMA); + + requestObject.remove(KEY_EXPLAIN); + requestObject.remove(KEY_CACHE); + } catch (Exception e) { + return extendErrorResult(requestObject, e, requestMethod, getRequestURL(), isRoot); + } + verifier = createVerifier().setVisitor(getVisitor()); if (RequestMethod.isPublicMethod(requestMethod) == false) { @@ -552,28 +574,6 @@ public M parseResponse(M request) { } } - try { - setGlobalDatabase(getString(requestObject, KEY_DATABASE)); - setGlobalDatasource(getString(requestObject, KEY_DATASOURCE)); - setGlobalNamespace(getString(requestObject, KEY_NAMESPACE)); - setGlobalCatalog(getString(requestObject, KEY_CATALOG)); - setGlobalSchema(getString(requestObject, KEY_SCHEMA)); - - setGlobalExplain(getBoolean(requestObject, KEY_EXPLAIN)); - setGlobalCache(getString(requestObject, KEY_CACHE)); - - requestObject.remove(KEY_DATABASE); - requestObject.remove(KEY_DATASOURCE); - requestObject.remove(KEY_NAMESPACE); - requestObject.remove(KEY_CATALOG); - requestObject.remove(KEY_SCHEMA); - - requestObject.remove(KEY_EXPLAIN); - requestObject.remove(KEY_CACHE); - } catch (Exception e) { - return extendErrorResult(requestObject, e, requestMethod, getRequestURL(), isRoot); - } - final String requestString = JSON.toJSONString(request);//request传进去解析后已经变了 queryResultMap = new HashMap(); @@ -1516,10 +1516,10 @@ else if (childKeys.length == 1 && isTableKey(childKeys[0])) { // 可能无需 JOIN_COPY_KEY_LIST = new ArrayList(); JOIN_COPY_KEY_LIST.add(KEY_ROLE); JOIN_COPY_KEY_LIST.add(KEY_DATABASE); + JOIN_COPY_KEY_LIST.add(KEY_DATASOURCE); JOIN_COPY_KEY_LIST.add(KEY_NAMESPACE); JOIN_COPY_KEY_LIST.add(KEY_CATALOG); JOIN_COPY_KEY_LIST.add(KEY_SCHEMA); - JOIN_COPY_KEY_LIST.add(KEY_DATASOURCE); JOIN_COPY_KEY_LIST.add(KEY_COLUMN); JOIN_COPY_KEY_LIST.add(KEY_NULL); JOIN_COPY_KEY_LIST.add(KEY_CAST); @@ -2382,9 +2382,11 @@ protected M batchVerify(RequestMethod method, String tag, int version, String na } switch (objAttrKey) { + case KEY_DATABASE: case KEY_DATASOURCE: + case KEY_NAMESPACE: + case KEY_CATALOG: case KEY_SCHEMA: - case KEY_DATABASE: case KEY_VERSION: case KEY_ROLE: objAttrMap.put(objAttrKey, entry.getValue()); @@ -2432,17 +2434,21 @@ protected M batchVerify(RequestMethod method, String tag, int version, String na } } else { setRequestAttribute(key, true, KEY_METHOD, request); + setRequestAttribute(key, true, KEY_DATABASE, request); setRequestAttribute(key, true, KEY_DATASOURCE, request); + setRequestAttribute(key, true, KEY_NAMESPACE, request); + setRequestAttribute(key, true, KEY_CATALOG, request); setRequestAttribute(key, true, KEY_SCHEMA, request); - setRequestAttribute(key, true, KEY_DATABASE, request); setRequestAttribute(key, true, KEY_VERSION, request); setRequestAttribute(key, true, KEY_ROLE, request); } } else { setRequestAttribute(key, false, KEY_METHOD, request); + setRequestAttribute(key, false, KEY_DATABASE, request); setRequestAttribute(key, false, KEY_DATASOURCE, request); + setRequestAttribute(key, false, KEY_NAMESPACE, request); + setRequestAttribute(key, false, KEY_CATALOG, request); setRequestAttribute(key, false, KEY_SCHEMA, request); - setRequestAttribute(key, false, KEY_DATABASE, request); setRequestAttribute(key, false, KEY_VERSION, request); setRequestAttribute(key, false, KEY_ROLE, request); } @@ -2569,7 +2575,9 @@ protected M objectVerify(RequestMethod method, String tag, int version, String n // 获取指定的JSON结构 >>>>>>>>>>>>>> M target = wrapRequest(method, tag, object, true); // Map clone 浅拷贝没用,Structure.parse 会导致 structure 里面被清空,第二次从缓存里取到的就是 {} - return getVerifier().setParser(this).verifyRequest(method, name, target, request, maxUpdateCount, getGlobalDatabase(), getGlobalSchema()); + return getVerifier().setParser(this).verifyRequest(method, name, target, request, maxUpdateCount + , getGlobalDatabase(), getGlobalDatasource(), getGlobalNamespace(), getGlobalCatalog(), getGlobalSchema() + ); } /*** diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java index d9e9eb01..c3532314 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java @@ -5490,7 +5490,7 @@ public static , L extends List> SQLConf String catalog = getString(request, KEY_CATALOG); String schema = getString(request, KEY_SCHEMA); - SQLConfig config = (SQLConfig) callback.getSQLConfig(method, database, schema, datasource, table); + SQLConfig config = (SQLConfig) callback.getSQLConfig(method, database, datasource, namespace, catalog, schema, table); config.setAlias(alias); config.setDatabase(database); // 不删,后面表对象还要用的,必须放在 parseJoin 前 @@ -5511,9 +5511,9 @@ public static , L extends List> SQLConf // 对 id, id{}, userId, userId{} 处理,这些只要不为 null 就一定会作为 AND 条件 <<<<<<<<<<<<<<<<<<<<<<<<< - String idKey = callback.getIdKey(datasource, database, schema, table); + String idKey = callback.getIdKey(database, datasource, namespace, catalog, schema, table); String idInKey = idKey + "{}"; - String userIdKey = callback.getUserIdKey(datasource, database, schema, table); + String userIdKey = callback.getUserIdKey(database, datasource, namespace, catalog, schema, table); String userIdInKey = userIdKey + "{}"; Object idIn = request.get(idInKey); // 可能是 id{}:">0" @@ -5539,7 +5539,7 @@ public static , L extends List> SQLConf Object id = request.get(idKey); if (id == null && method == POST) { - id = callback.newId(method, database, schema, datasource, table); // null 表示数据库自增 id + id = callback.newId(method, database, datasource, namespace, catalog, schema, table); // null 表示数据库自增 id } if (id != null) { // null 无效 @@ -6532,44 +6532,59 @@ public static interface IdCallback { /**为 post 请求新建 id, 只能是 Long 或 String * @param method * @param database + * @param datasource + * @param namespace + * @param catalog * @param schema * @param table * @return */ - T newId(RequestMethod method, String database, String schema, String datasource, String table); + T newId(RequestMethod method, String database, String datasource, String namespace, String catalog, String schema, String table); /**获取主键名 * @param database + * @param datasource + * @param namespace + * @param catalog * @param schema * @param table * @return */ - String getIdKey(String database, String schema, String datasource, String table); + String getIdKey(String database, String datasource, String namespace, String catalog, String schema, String table); /**获取 User 的主键名 * @param database + * @param datasource + * @param namespace + * @param catalog * @param schema * @param table * @return */ - String getUserIdKey(String database, String schema, String datasource, String table); + String getUserIdKey(String database, String datasource, String namespace, String catalog, String schema, String table); } public static interface Callback, L extends List> extends IdCallback { /**获取 SQLConfig 的实例 * @param method * @param database + * @param datasource + * @param namespace + * @param catalog * @param schema * @param table * @return */ - SQLConfig getSQLConfig(RequestMethod method, String database, String schema, String datasource, String table); + SQLConfig getSQLConfig(RequestMethod method, String database, String datasource, String namespace, String catalog, String schema, String table); /**combine 里的 key 在 request 中 value 为 null 或不存在,即 request 中缺少用来作为 combine 条件的 key: value + * @param name + * @param request * @param combine + * @param item * @param key - * @param request + * @throws Exception */ void onMissingKey4Combine(String name, M request, String combine, String item, String key) throws Exception; } @@ -6583,7 +6598,7 @@ public static abstract class SimpleCallback, L @SuppressWarnings("unchecked") @Override - public T newId(RequestMethod method, String database, String schema, String datasource, String table) { + public T newId(RequestMethod method, String database, String datasource, String namespace, String catalog, String schema, String table) { Long id = System.currentTimeMillis(); if (id <= LAST_ID) { id = LAST_ID + 1; // 解决高并发下 id 冲突导致新增记录失败 @@ -6594,12 +6609,12 @@ public T newId(RequestMethod method, String database, String schema, String data } @Override - public String getIdKey(String database, String schema, String datasource, String table) { + public String getIdKey(String database, String datasource, String namespace, String catalog, String schema, String table) { return KEY_ID; } @Override - public String getUserIdKey(String database, String schema, String datasource, String table) { + public String getUserIdKey(String database, String datasource, String namespace, String catalog, String schema, String table) { return KEY_USER_ID; } diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java index 8a2862eb..3107b905 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java @@ -158,6 +158,8 @@ public ResultSet execute(@NotNull Statement statement, String sql) throws Except return rs; } + public static int MIN_OPTIMIZE_CAPACITY = 2^16 - 1; + /**执行SQL * @param config * @return @@ -330,7 +332,7 @@ public M execute(@NotNull SQLConfig config, boolean unknownType) throws } else { // 预估容量 capacity = config.getCount() <= 0 ? AbstractParser.MAX_QUERY_COUNT : config.getCount(); - if (capacity > 100) { + if (capacity > MIN_OPTIMIZE_CAPACITY) { // 有 WHERE 条件,条件越多过滤数据越多,暂时不考虑 @combine:"a | (b & !c)" 里面 | OR 和 ! NOT 条件,太复杂也不是很必要 Map> combine = config.getCombineMap(); @@ -354,14 +356,15 @@ public M execute(@NotNull SQLConfig config, boolean unknownType) throws Map having = config.getHaving(); int havingCount = having == null ? 0 : having.size(); - capacity /= Math.pow(1.5, Math.log10(capacity) + double cap = capacity / Math.pow(1.5, Math.log10(capacity)/8 // LIMIT 10^9 = 1 亿 以内无任何条件时 最多扩容 1 次 + andCondCount + ((orCondCount <= 0 ? 0 : 2.0d/orCondCount) // 1: 2.3, 2: 1.5, 3: 1.3, 4: 1.23, 5: 1.18 + (notCondCount/5.0d) // 1: 1.08, 2: 1.18, 3: 1.28, 4: 1.38, 1.50 - + (groupCount <= 0 ? 0 : 10.0d/groupCount)) // 1: 57.7, 7.6, 3: 3.9, 4: 2.8, 5: 2.3 + + (groupCount <= 0 ? 0 : 10.0d/Math.min(5, groupCount))) // 1: 57.7, 7.6, 3: 3.9, 4: 2.8, 5: 2.3 + havingCount ); - capacity += 1; // 避免正好比需要容量少一点点导致多一次扩容,大量数据 System.arrayCopy + cap = groupCount > 0 ? cap : Math.max(MIN_OPTIMIZE_CAPACITY, Math.max(cap, capacity/Math.pow(1.5, 5))); // 1/(1.5^5) = 0.13 + capacity = (int) (cap + 1); // 避免正好比需要容量少一点点导致多一次扩容,大量数据 System.arrayCopy } } } diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java index 5e665815..9824d488 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java @@ -209,21 +209,21 @@ public static HashMap getAccessMap(MethodAccess access) @Override public String getVisitorIdKey(SQLConfig config) { - return config == null ? getUserIdKey(null, null, null, null) : config.getUserIdKey(); + return config == null ? getUserIdKey(null, null, null, null, null, null) : config.getUserIdKey(); } @Override - public String getIdKey(String database, String schema, String datasource, String table) { + public String getIdKey(String database, String datasource, String namespace, String catalog, String schema, String table) { return KEY_ID; } @Override - public String getUserIdKey(String database, String schema, String datasource, String table) { + public String getUserIdKey(String database, String datasource, String namespace, String catalog, String schema, String table) { return KEY_USER_ID; } @SuppressWarnings("unchecked") @Override - public T newId(RequestMethod method, String database, String schema, String datasource, String table) { + public T newId(RequestMethod method, String database, String datasource, String namespace, String catalog, String schema, String table) { return (T) Long.valueOf(System.currentTimeMillis()); } @@ -555,9 +555,9 @@ public void verifyRepeat(String table, String key, Object value, long exceptId) * @throws Exception */ @Override - public M verifyRequest(@NotNull final RequestMethod method, final String name, final M target, final M request, final int maxUpdateCount - , final String database, final String schema) throws Exception { - return verifyRequest(method, name, target, request, maxUpdateCount, database, schema, this, getParser()); + public M verifyRequest(@NotNull RequestMethod method, String name, M target, M request, int maxUpdateCount + , String database, String datasource, String namespace, String catalog, String schema) throws Exception { + return verifyRequest(method, name, target, request, maxUpdateCount, database, datasource, namespace, catalog, schema, this, getParser()); } /**从request提取target指定的内容 @@ -609,27 +609,32 @@ public static , L extends List> M verif @NotNull RequestMethod method, String name, M target, M request, int maxUpdateCount, String database , String schema, IdCallback idCallback, @NotNull Parser parser) throws Exception { - return verifyRequest(method, name, target, request, maxUpdateCount, database, schema, null, idCallback, parser); + return verifyRequest(method, name, target, request, maxUpdateCount, database, null, null, null, schema, idCallback, parser); } /**从request提取target指定的内容 - * @param method - * @param name - * @param target - * @param request - * @param maxUpdateCount - * @param database - * @param schema - * @param datasource - * @param idCallback - * @param parser - * @return - * @param - * @throws Exception - */ + * @param method + * @param name + * @param target + * @param request + * @param maxUpdateCount + * @param database + * @param datasource + * @param namespace + * @param catalog + * @param schema + * @param idCallback + * @param parser + * @return + * @param + * @param + * @param + * @throws Exception + */ 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, @NotNull Parser parser) throws Exception { + , final int maxUpdateCount, final String database, final String datasource, final String namespace + , final String catalog, final String schema, final IdCallback idCallback + , @NotNull Parser parser) throws Exception { if (ENABLE_VERIFY_CONTENT == false) { throw new UnsupportedOperationException("AbstractVerifier.ENABLE_VERIFY_CONTENT == false" + " 时不支持校验请求传参内容!如需支持则设置 AbstractVerifier.ENABLE_VERIFY_CONTENT = true !"); @@ -652,7 +657,7 @@ public static , L extends List> M verif //解析 - return parse(method, name, target, request, database, schema, idCallback, parser, new OnParseCallback() { + return parse(method, name, target, request, database, datasource, namespace, catalog, schema, idCallback, parser, new OnParseCallback() { @Override public M onParseJSONObject(String key, M tobj, M robj) throws Exception { @@ -664,19 +669,27 @@ public M onParseJSONObject(String key, M tobj, M robj) throws Exception { } } else if (isTableKey(key)) { String db = getString(request, KEY_DATABASE); - String sh = getString(request, KEY_SCHEMA); String ds = getString(request, KEY_DATASOURCE); + String ns = getString(request, KEY_NAMESPACE); + String cl = getString(request, KEY_CATALOG); + String sh = getString(request, KEY_SCHEMA); if (StringUtil.isEmpty(db, false)) { db = database; } - if (StringUtil.isEmpty(sh, false)) { - sh = schema; - } if (StringUtil.isEmpty(ds, false)) { ds = datasource; } + if (StringUtil.isEmpty(ns, false)) { + ns = namespace; + } + if (StringUtil.isEmpty(cl, false)) { + cl = catalog; + } + if (StringUtil.isEmpty(sh, false)) { + sh = schema; + } - String idKey = idCallback == null ? null : idCallback.getIdKey(db, sh, ds, key); + String idKey = idCallback == null ? null : idCallback.getIdKey(db, ds, ns, cl, sh, key); String finalIdKey = StringUtil.isEmpty(idKey, false) ? KEY_ID : idKey; if (method == POST) { @@ -688,14 +701,14 @@ public M onParseJSONObject(String key, M tobj, M robj) throws Exception { 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); - String userIdKey = idCallback == null ? null : idCallback.getUserIdKey(db, sh, ds, key); + String userIdKey = idCallback == null ? null : idCallback.getUserIdKey(db, ds, ns, cl, sh, key); String finalUserIdKey = StringUtil.isEmpty(userIdKey, false) ? KEY_USER_ID : userIdKey; verifyId(method.name(), name, key, robj, finalUserIdKey, maxUpdateCount, false); } } } - return verifyRequest(method, key, tobj, robj, maxUpdateCount, database, schema, idCallback, parser); + return verifyRequest(method, key, tobj, robj, maxUpdateCount, database, datasource, namespace, catalog, schema, idCallback, parser); } @Override @@ -888,7 +901,7 @@ public static , L extends List> M parse 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, @NotNull Parser parser, @NotNull OnParseCallback callback) throws Exception { - return parse(method, name, target, real, database, schema, null, idCallback, parser, callback); + return parse(method, name, target, real, database, null, null, null, schema, idCallback, parser, callback); } /**对request和response不同的解析用callback返回 * @param method @@ -896,16 +909,21 @@ public static , L extends List> M parse * @param target * @param real * @param database - * @param schema * @param datasource + * @param namespace + * @param catalog + * @param schema * @param idCallback * @param parser * @param callback * @return + * @param + * @param + * @param * @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 + , String name, M target, M real, String database, String datasource, String namespace, String catalog, String schema , final IdCallback idCallback, @NotNull Parser parser, @NotNull OnParseCallback callback) throws Exception { if (target == null) { return null; @@ -1153,18 +1171,26 @@ && rv instanceof List && isArrayKey(rk)) { String db = getString(real, KEY_DATABASE); - String sh = getString(real, KEY_SCHEMA); String ds = getString(real, KEY_DATASOURCE); + String ns = getString(real, KEY_NAMESPACE); + String cl = getString(real, KEY_CATALOG); + String sh = getString(real, KEY_SCHEMA); if (StringUtil.isEmpty(db, false)) { db = database; } - if (StringUtil.isEmpty(sh, false)) { - sh = schema; - } if (StringUtil.isEmpty(ds, false)) { ds = datasource; } - String idKey = idCallback == null ? null : idCallback.getIdKey(db, sh, ds, name); + if (StringUtil.isEmpty(ns, false)) { + ns = namespace; + } + if (StringUtil.isEmpty(cl, false)) { + cl = catalog; + } + if (StringUtil.isEmpty(sh, false)) { + sh = schema; + } + String idKey = idCallback == null ? null : idCallback.getIdKey(db, ds, ns, cl, sh, name); String finalIdKey = StringUtil.isEmpty(idKey, false) ? KEY_ID : idKey; // TODO 放在operate前?考虑性能、operate修改后再验证的值是否和原来一样 @@ -1298,7 +1324,7 @@ && rv instanceof List && isArrayKey(rk)) { } if (nkl.contains(k) || real.get(k) != null) { - real = parse(method, name, (M) v, real, database, schema, datasource, idCallback, parser, callback); + real = parse(method, name, (M) v, real, database, datasource, namespace, catalog, schema, idCallback, parser, callback); } } } diff --git a/APIJSONORM/src/main/java/apijson/orm/Verifier.java b/APIJSONORM/src/main/java/apijson/orm/Verifier.java index 4b926519..97db58a9 100755 --- a/APIJSONORM/src/main/java/apijson/orm/Verifier.java +++ b/APIJSONORM/src/main/java/apijson/orm/Verifier.java @@ -69,14 +69,17 @@ public interface Verifier, L extends List +## 中文 | [English](https://github.com/Tencent/APIJSON/blob/master/Document.md) # APIJSON 通用文档 本文是通用文档,只和 APIJSON 协议有关,和 C#, Go, Java, JavaScript, PHP, Python, TypeScript 等开发语言无关。
diff --git a/Document.md b/Document.md index 7574e569..d3f18d4a 100644 --- a/Document.md +++ b/Document.md @@ -1,3 +1,5 @@ +## English | [中文](https://github.com/Tencent/APIJSON/blob/master/Document-Chinese.md) + #### A better online document is available at https://apijsondocs.readthedocs.io ### Examples: diff --git a/README-Chinese.md b/README-Chinese.md index efd1858f..3e9b446f 100644 --- a/README-Chinese.md +++ b/README-Chinese.md @@ -376,117 +376,14 @@ https://github.com/Tencent/APIJSON/issues/187 ### 贡献者们 主项目 APIJSON 的贡献者们(6 个腾讯工程师、1 个微软工程师、1 个阿里云工程师、1 个字节跳动工程师、1 个网易工程师、1 个 Zoom 工程师、1 个圆通工程师、1 个知乎基础研发架构师、1 个智联招聘工程师、gorm-plus 作者、1 个美国加州大学学生、3 个 SUSTech 学生等):
https://github.com/Tencent/APIJSON/blob/master/CONTRIBUTING.md
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

+Screenshot 2026-04-18 at 05 28 48 生态周边项目的作者们(2 个腾讯工程师、1 个 BAT 技术专家、1 个微软工程师、2 个字节跳动工程师、1 个神州数码工程师&Apache dubbo2js 作者 等):
https://github.com/search?o=desc&q=apijson&s=stars&type=Repositories
https://search.gitee.com/?skin=rec&type=repository&q=apijson&sort=stars_count
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

+Screenshot 2026-04-18 at 05 29 36 还有为 APIJSON 扫描代码贡献 Issue 的 [蚂蚁集团源伞](https://www.sourcebrella.com) 和 [奇安信代码卫士](https://github.com/QiAnXinCodeSafe)
@@ -699,7 +596,7 @@ Issue/问卷 一般解答顺序:贡献者 > 帮助他人的用户 > 提供任 [uliweb-apijson](https://github.com/zhangchunlin/uliweb-apijson) Python 版 APIJSON,支持 MySQL, PostgreSQL, SQL Server, Oracle, SQLite 等 -[apijson-rust](https://gitee.com/APIJSON/panda-base) APIJSON 的 Rust 版,一个优雅、高性能的 Rust 多数据源管理系统,支持 MySQL 和 PostgreSQL +[apijson-rust](https://github.com/APIJSON/apijson-rust) APIJSON 的 Rust 版,一个优雅、高性能的 Rust 多数据源管理系统,支持 MySQL 和 PostgreSQL [APIJSONParser](https://github.com/Zerounary/APIJSONParser) 第三方 APIJSON 解析器,将 JSON 动态解析成 SQL diff --git a/README.md b/README.md index 8811a3bd..f6c637fd 100644 --- a/README.md +++ b/README.md @@ -301,97 +301,14 @@ https://github.com/Tencent/APIJSON/issues/187 ### Contributers of APIJSON: Contributers for the APIJSON core project(6 Tencent engineers, 1 Microsoft engineer, 1 Zhihu architect, 1 Bytedance(TikTok) engineer, 1 NetEase engineer, 1 Zoom engineer, 1 YTO Express engineer, 1 Zhilian engineer, 1 UC student、3 SUSTech students, etc.):
https://github.com/Tencent/APIJSON/blob/master/CONTRIBUTING.md
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- +Screenshot 2026-04-18 at 05 28 48 + Authors of other projects for ecosystem of APIJSON(2 Tencent engineers, 1 BAT(Baidu/Alibaba/Tencent) expert, 1 Microsoft engineer, 2 Bytedance(TikTok) engineers, 1 Digital China engineer & Apache dubbo2js author, etc.):
https://github.com/search?o=desc&q=apijson&s=stars&type=Repositories
https://search.gitee.com/?skin=rec&type=repository&q=apijson&sort=stars_count
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

+Screenshot 2026-04-18 at 05 29 36 Thanks to all contributers of APIJSON!