From f6f27e49282f090dfa0ddfe98fcde62a7b9a85f8 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年5月18日 23:02:17 +0800
Subject: [PATCH 01/41] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=96=87=E7=AB=A0?=
=?UTF-8?q?=EF=BC=9AAPIJSON=E5=BF=AB=E9=80=9F=E5=85=A5=E9=97=A8-=E9=9B=B6?=
=?UTF-8?q?=E5=90=8E=E7=AB=AF=E4=BB=A3=E7=A0=81=EF=BC=8C=E6=8E=A5=E5=8F=A3?=
=?UTF-8?q?=E6=89=80=E8=A7=81=E5=8D=B3=E6=89=80=E5=BE=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
创作不易,点赞、收藏支持下热心的文章作者吧 ~
https://www.toutiao.com/article/7503844050689376783
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index 82ec117f..edc82100 100644
--- a/README.md
+++ b/README.md
@@ -631,6 +631,8 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[apijson 快速上手](https://blog.csdn.net/qq_16381291/article/details/147110737)
+[APIJSON快速入门-零后端代码,接口所见即所得](https://www.toutiao.com/article/7503844050689376783)
+
### 生态项目
[APIJSON-Demo](https://github.com/APIJSON/APIJSON-Demo) APIJSON 各种语言、各种框架 的 使用示例项目、上手文档、测试数据 SQL 文件 等
From efb4f6a362fd2fb00ff363e0dd1344451b2da87f Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年5月27日 23:32:35 +0800
Subject: [PATCH 02/41] =?UTF-8?q?=E6=96=B0=E5=A2=9E=208.0=20=E7=89=88?=
=?UTF-8?q?=E5=AE=9E=E8=B7=B5=E5=8D=9A=E6=96=87=EF=BC=9A=E8=85=BE=E8=AE=AF?=
=?UTF-8?q?=E5=BC=80=E6=BA=90=EF=BC=81=E9=9B=B6=E4=BB=A3=E7=A0=81=EF=BC=8C?=
=?UTF-8?q?=E5=85=A8=E8=87=AA=E5=8A=A8=E4=B8=87=E8=83=BDAPI=E6=8E=A5?=
=?UTF-8?q?=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
创作不易,点赞、收藏、转发支持热心的文章作者吧~
https://mp.weixin.qq.com/s/WWndAa68BqBfflWgL5592A
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index edc82100..858c4f5c 100644
--- a/README.md
+++ b/README.md
@@ -633,6 +633,8 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[APIJSON快速入门-零后端代码,接口所见即所得](https://www.toutiao.com/article/7503844050689376783)
+[腾讯开源!零代码,全自动万能API接口](https://mp.weixin.qq.com/s/WWndAa68BqBfflWgL5592A)
+
### 生态项目
[APIJSON-Demo](https://github.com/APIJSON/APIJSON-Demo) APIJSON 各种语言、各种框架 的 使用示例项目、上手文档、测试数据 SQL 文件 等
From 38dfb9335df47216fe84d52eee255c919d2e2e6a Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: Sun, 8 Jun 2025 19:49:40 +0800
Subject: [PATCH 03/41] =?UTF-8?q?=E7=94=9F=E6=80=81=E9=A1=B9=E7=9B=AE?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E=20apijson-gson=20=E5=92=8C=20apijson-fastjso?=
=?UTF-8?q?n2=20=E8=BF=99=E4=B8=A4=E4=B8=AA=20JSON=20=E5=BA=8F=E5=88=97?=
=?UTF-8?q?=E5=8C=96=E5=92=8C=E5=8F=8D=E5=BA=8F=E5=88=97=E5=8C=96=E6=8F=92?=
=?UTF-8?q?=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
创作不易,右上角点 ⭐Star 来支持/收藏下吧,谢谢 ^_^
https://github.com/APIJSON/apijson-gson
https://github.com/APIJSON/apijson-fastjson2
---
README.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/README.md b/README.md
index 858c4f5c..098c17fc 100644
--- a/README.md
+++ b/README.md
@@ -646,6 +646,10 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[apijson-column](https://github.com/APIJSON/apijson-column) APIJSON 的字段插件,支持 字段名映射 和 !key 反选字段
+[apijson-gson](https://github.com/APIJSON/apijson-gson) APIJSON 的 gson 插件,简化使用
+
+[apijson-fastjson2](https://github.com/APIJSON/apijson-fastjson2) APIJSON 的 fastjson2 插件,简化使用
+
[apijson-milvus](https://github.com/APIJSON/apijson-milvus) APIJSON 的 Milvus AI 向量数据库插件
[apijson-influxdb](https://github.com/APIJSON/apijson-influxdb) APIJSON 的 InfluxDB 物联网时序数据库插件
From a25bbc57d633792c83ac8d99748515fc04d52614 Mon Sep 17 00:00:00 2001
From: TommyLemon
Date: 2025年6月15日 00:19:24 +0800
Subject: [PATCH 04/41] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20IS=5FRETURN=5FSTACK?=
=?UTF-8?q?=5FTRACE=20=E9=85=8D=E7=BD=AE=E6=98=AF=E5=90=A6=E8=BF=94?=
=?UTF-8?q?=E5=9B=9E=20trace:stack=20=E5=AD=97=E6=AE=B5=EF=BC=8C=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/java/apijson/orm/AbstractParser.java | 11 ++++++++++-
.../main/java/apijson/orm/AbstractSQLExecutor.java | 11 ++++++-----
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
index 36f2b417..ba6ad3ce 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
@@ -62,6 +62,12 @@ public abstract class AbstractParser, L extends
*/
public static boolean IS_PRINT_REQUEST_ENDTIME_LOG = false;
+ /**
+ * 可以通过切换该变量来控制返回 trace:stack 字段,如果是 gson 则不设置为 false,避免序列化报错。
+ * 与 {@link Log#DEBUG} 任何一个为 true 返回 trace:stack 字段。
+ */
+ public static boolean IS_RETURN_STACK_TRACE = true;
+
/**
* 分页页码是否从 1 开始,默认为从 0 开始
@@ -622,7 +628,10 @@ public M parseResponse(M request) {
// }
Throwable t = error instanceof CommonException && error.getCause() != null ? error.getCause() : error;
res.put("trace:throw", t.getClass().getName());
- res.put("trace:stack", t.getStackTrace());
+
+ if (IS_RETURN_STACK_TRACE) {
+ res.put("trace:stack", t.getStackTrace());
+ }
}
}
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
index c9d180bd..5ec59f36 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
@@ -1213,14 +1213,15 @@ public PreparedStatement getStatement(@NotNull SQLConfig config, String
sql = config.gainSQL(config.isPrepared());
}
+ Connection conn = getConnection(config);
PreparedStatement statement; //创建Statement对象
if (config.getMethod() == RequestMethod.POST && config.getId() == null) { //自增id
if (config.isOracle()) {
// 解决 oracle 使用自增主键 插入获取不到id问题
String[] generatedColumns = {config.getIdKey()};
- statement = getConnection(config).prepareStatement(sql, generatedColumns);
+ statement = conn.prepareStatement(sql, generatedColumns);
} else {
- statement = getConnection(config).prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
+ statement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
}
}
else if (RequestMethod.isGetMethod(config.getMethod(), true)) {
@@ -1234,13 +1235,13 @@ else if (RequestMethod.isGetMethod(config.getMethod(), true)) {
if (config.isMySQL() || config.isTiDB() || config.isMariaDB() || config.isOracle() || config.isSQLServer() || config.isDb2()
|| config.isPostgreSQL() || config.isCockroachDB() || config.isOpenGauss() || config.isTimescaleDB() || config.isQuestDB()
) {
- statement = getConnection(config).prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
+ statement = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
} else {
- statement = getConnection(config).prepareStatement(sql);
+ statement = conn.prepareStatement(sql);
}
}
else {
- statement = getConnection(config).prepareStatement(sql);
+ statement = conn.prepareStatement(sql);
}
List valueList = config.isPrepared() ? config.getPreparedValueList() : null;
From 3158fcea5ebe9fd33ea45f5447edfb41039ad8b0 Mon Sep 17 00:00:00 2001
From: TommyLemon
Date: 2025年6月15日 01:04:57 +0800
Subject: [PATCH 05/41] =?UTF-8?q?=E6=8A=8A=20trace:stack=20=E5=AD=97?=
=?UTF-8?q?=E6=AE=B5=E5=80=BC=E8=BD=AC=E4=B8=BA=20List=20=E8=BF=94?=
=?UTF-8?q?=E5=9B=9E=EF=BC=8C=E9=81=BF=E5=85=8D=20Gson=20=E7=AD=89=20JSON?=
=?UTF-8?q?=20=E5=BA=93=E5=8F=8D=E5=BA=8F=E5=88=97=E5=8C=96=E6=8A=A5?=
=?UTF-8?q?=E9=94=99=EF=BC=8C=E5=B9=B6=E4=B8=94=E8=BF=98=E6=9B=B4=E6=96=B9?=
=?UTF-8?q?=E4=BE=BF=E6=B5=8F=E8=A7=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/java/apijson/orm/AbstractParser.java | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
index ba6ad3ce..eab5a368 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
@@ -630,7 +630,16 @@ public M parseResponse(M request) {
res.put("trace:throw", t.getClass().getName());
if (IS_RETURN_STACK_TRACE) {
- res.put("trace:stack", t.getStackTrace());
+ L list = JSON.createJSONArray();
+
+ StackTraceElement[] traces = t.getStackTrace();
+ if (traces != null) { // && traces.length> 0) {
+ for (StackTraceElement trace : traces) {
+ list.add(trace == null ? null : trace.toString());
+ }
+ }
+
+ res.put("trace:stack", list);
}
}
}
From 1b72c3afd41582a934f1349c0a5cf32d5b740f8d Mon Sep 17 00:00:00 2001
From: TommyLemon
Date: 2025年6月15日 01:06:18 +0800
Subject: [PATCH 06/41] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E7=89=88=E6=9C=AC?=
=?UTF-8?q?=E4=B8=BA=208.0.2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
APIJSONORM/pom.xml | 2 +-
APIJSONORM/src/main/java/apijson/Log.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/APIJSONORM/pom.xml b/APIJSONORM/pom.xml
index 391319be..bd340fa5 100644
--- a/APIJSONORM/pom.xml
+++ b/APIJSONORM/pom.xml
@@ -5,7 +5,7 @@
com.github.Tencent
APIJSON
- 8.0.0
+ 8.0.2
jar
APIJSONORM
diff --git a/APIJSONORM/src/main/java/apijson/Log.java b/APIJSONORM/src/main/java/apijson/Log.java
index bd091c4e..b7b909d6 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 = "8.0.0";
+ public static final String VERSION = "8.0.2";
public static final String KEY_SYSTEM_INFO_DIVIDER = "\n---|-----APIJSON SYSTEM INFO-----|---\n";
public static final String OS_NAME;
From 4636380573931af5361f0910eff89a8577b7c784 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年6月29日 16:08:16 +0800
Subject: [PATCH 07/41] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=A4=B1=E6=95=88?=
=?UTF-8?q?=E6=96=87=E7=AB=A0=EF=BC=8C=E6=96=B0=E5=A2=9E=20[APIJSON?=
=?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=AE=9E=E6=88=98=E6=95=99=E7=A8=8B=EF=BC=9A?=
=?UTF-8?q?=E9=9B=B6=E4=BB=A3=E7=A0=81=E5=AE=9E=E7=8E=B0=E9=AB=98=E6=95=88?=
=?UTF-8?q?JSON=E6=8E=A5=E5=8F=A3=E5=BC=80=E5=8F=91](https://blog.csdn.net?=
=?UTF-8?q?/gitblog=5F00682/article/details/148375065)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
感谢文章作者的热心贡献,点赞、收藏、转发 支持下 TA 吧 ^_^
---
README.md | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/README.md b/README.md
index 098c17fc..44d0cc4c 100644
--- a/README.md
+++ b/README.md
@@ -559,7 +559,7 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[3步创建APIJSON后端新表及配置](https://my.oschina.net/tommylemon/blog/889074)
-[APIJSON对接分布式HTAP数据库TiDB](https://asktug.com/t/htap-tidb/395)
+[APIJSON对接分布式HTAP数据库TiDB](https://my.oschina.net/tommylemon/blog/3081913)
[APIJSON教程(一):上手apijson项目,学习apijson语法,并实现持久层配置](https://zhuanlan.zhihu.com/p/375681893)
@@ -572,13 +572,7 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[学习自动化接口APIJSON](https://www.jianshu.com/p/981a2a630c7b)
[APIJSON 接口调试实践](https://github.com/Tencent/APIJSON/issues/189)
-
-[关于APIJSON远程函数](https://mp.weixin.qq.com/s?__biz=Mzg3NTc1NDUyNA==&mid=2247483950&idx=1&sn=b11e70bdf083c55d72238e107449ae2e&chksm=cf3de75df84a6e4b3a4acd0846531b0bd12bc90379523fbaf6b4f900fc3cdc1b1ce3eff97fd9&scene=178&cur_album_id=2548737392338354178#rd)
-
-[APIJSON新增方法实例](https://cloud.tencent.com/developer/article/2098890)
-
-[APIJSON-APIJSON的那些事儿](https://cloud.tencent.com/developer/article/2098888)
-
+
[APIJSON-零代码接口和文档 JSON 协议 与 ORM 库](https://cloud.tencent.com/developer/article/2077042)
[APIJSON使用例子总结](https://blog.csdn.net/weixin_41077841/article/details/110518007)
@@ -589,8 +583,6 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[APIJSON复杂业务深入实践(类似12306订票系统)](https://blog.csdn.net/aa330233789/article/details/105309571)
-[全国行政区划数据抓取与处理](https://www.xlongwei.com/detail/21032616)
-
[新手搭建 APIJSON 项目指北](https://github.com/jerrylususu/apijson_todo_demo/blob/master/FULLTEXT.md)
[使用APIJSON写低代码Crud接口](https://blog.csdn.net/weixin_42375862/article/details/121654264)
@@ -635,6 +627,8 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[腾讯开源!零代码,全自动万能API接口](https://mp.weixin.qq.com/s/WWndAa68BqBfflWgL5592A)
+[APIJSON项目实战教程:零代码实现高效JSON接口开发](https://blog.csdn.net/gitblog_00682/article/details/148375065)
+
### 生态项目
[APIJSON-Demo](https://github.com/APIJSON/APIJSON-Demo) APIJSON 各种语言、各种框架 的 使用示例项目、上手文档、测试数据 SQL 文件 等
From f6703c9c061569c8397ef4fe4f66b560910f450d Mon Sep 17 00:00:00 2001
From: wuzeng
Date: Tue, 1 Jul 2025 20:30:57 +0800
Subject: [PATCH 08/41] =?UTF-8?q?fix:=20=E5=9C=A8Head=20Method=EF=BC=8CPG?=
=?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=20left=20join=20=E5=89=AF=E8=A1=A8?=
=?UTF-8?q?=20=E5=A4=9A=E4=B8=AA=E4=B8=9A=E5=8A=A1=E9=94=AE=E5=85=B3?=
=?UTF-8?q?=E8=81=94=EF=BC=8C=E5=87=BA=E7=8E=B0=E6=89=BE=E4=B8=8D=E5=88=B0?=
=?UTF-8?q?column?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
index a919b273..82808e3e 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
@@ -6324,7 +6324,10 @@ LEFT JOIN ( SELECT count(*) AS count FROM sys.Comment ) AS Comment ON Comment.m
List column = onList == null ? null : new ArrayList(onList.size());
if (column != null) {
for (On on : onList) {
- column.add(on.getKey());
+ //解决 pg 如果只查询关联键,会报找不到column的错误
+ ///* SELECT count(*) AS count FROM sys.Moment AS Moment
+ // LEFT JOIN ( SELECT * FROM sys.Comment ) AS Comment ON Comment.momentId = Moment.id LIMIT 1 OFFSET 0 */
+ //column.add(on.getKey());
}
}
From 7314336f074c69ba748b9c1f17f3a09a74d90084 Mon Sep 17 00:00:00 2001
From: wuzeng
Date: Thu, 3 Jul 2025 09:55:00 +0800
Subject: [PATCH 09/41] =?UTF-8?q?fix:=20=E5=9C=A8Head=20Method=EF=BC=8CMyS?=
=?UTF-8?q?ql=E6=95=B0=E6=8D=AE=E6=80=A7=E8=83=BD=E6=9C=80=E4=BC=98?=
=?UTF-8?q?=E8=A7=A3=EF=BC=8C=E5=85=B6=E4=BB=96=E6=95=B0=E6=8D=AE=E5=BA=93?=
=?UTF-8?q?=E5=A6=82PG=E6=95=B0=E6=8D=AE=E5=BA=93=E9=9C=80=E8=A6=81=20=20L?=
=?UTF-8?q?EFT=20JOIN=20=E5=85=B6=E4=BB=96=E9=94=AE=E6=97=B6=E7=9B=B4?=
=?UTF-8?q?=E6=8E=A5(select=20*=20from=20A.a)=20=E9=81=BF=E5=85=8D?=
=?UTF-8?q?=E6=89=BE=E4=B8=8D=E5=88=B0column=E7=9A=84=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../main/java/apijson/orm/AbstractSQLConfig.java | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
index 82808e3e..de1d17dc 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
@@ -6322,12 +6322,15 @@ LEFT JOIN ( SELECT count(*) AS count FROM sys.Comment ) AS Comment ON Comment.m
if (RequestMethod.isHeadMethod(method, true)) {
List onList = join.getOnList();
List column = onList == null ? null : new ArrayList(onList.size());
- if (column != null) {
- for (On on : onList) {
- //解决 pg 如果只查询关联键,会报找不到column的错误
- ///* SELECT count(*) AS count FROM sys.Moment AS Moment
- // LEFT JOIN ( SELECT * FROM sys.Comment ) AS Comment ON Comment.momentId = Moment.id LIMIT 1 OFFSET 0 */
- //column.add(on.getKey());
+ //解决 pg 如果只查询关联键,会报找不到column的错误
+ ///* SELECT count(*) AS count FROM sys.Moment AS Moment
+ // LEFT JOIN ( SELECT * FROM sys.Comment ) AS Comment ON Comment.momentId = Moment.id LIMIT 1 OFFSET 0 */
+ if (joinConfig.isMySQL()) {
+ if (column != null) {
+ for (On on : onList) {
+ column.add(on.getKey());
+ }
+
}
}
From 957ba3dbe17ace0dfc7ec8404239a701cf0fdb7b Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: Sat, 5 Jul 2025 14:36:55 +0800
Subject: [PATCH 10/41] =?UTF-8?q?=E4=BC=98=E5=8C=96=20JOIN=20=E4=B8=8B=20S?=
=?UTF-8?q?ELECT=20=E5=AD=97=E6=AE=B5=E7=9A=84=E4=BB=A3=E7=A0=81=EF=BC=8C?=
=?UTF-8?q?=E6=89=80=E4=BB=A5=E5=85=BC=E5=AE=B9=20MySQL=20SQL=20=E8=AF=AD?=
=?UTF-8?q?=E6=B3=95=E7=9A=84=E6=95=B0=E6=8D=AE=E5=BA=93=E9=83=BD=E4=BF=9D?=
=?UTF-8?q?=E6=8C=81=E5=8E=9F=E6=9D=A5=E7=9A=84=E5=A4=84=E7=90=86=E6=96=B9?=
=?UTF-8?q?=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/java/apijson/orm/AbstractSQLConfig.java | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
index de1d17dc..c1e33e0b 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
@@ -6325,12 +6325,9 @@ LEFT JOIN ( SELECT count(*) AS count FROM sys.Comment ) AS Comment ON Comment.m
//解决 pg 如果只查询关联键,会报找不到column的错误
///* SELECT count(*) AS count FROM sys.Moment AS Moment
// LEFT JOIN ( SELECT * FROM sys.Comment ) AS Comment ON Comment.momentId = Moment.id LIMIT 1 OFFSET 0 */
- if (joinConfig.isMySQL()) {
- if (column != null) {
- for (On on : onList) {
- column.add(on.getKey());
- }
-
+ if (column != null && joinConfig.isMSQL()) { // 暂时这样兼容 PostgreSQL 等不支持 SELECT 中不包含对应 key 的隐式 ON 关联字段的数据库
+ for (On on : onList) {
+ column.add(on.getKey()); // TODO PostgreSQL 等需要找到具体的 targetTable 对应 targetKey 来加到 SELECT,比直接 SELECT * 性能更好
}
}
From 47d76bbaa65464a9d1349326d6f0ecadc7e94d60 Mon Sep 17 00:00:00 2001
From: TommyLemon
Date: Sun, 6 Jul 2025 03:19:08 +0800
Subject: [PATCH 11/41] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=94=AF=E6=8C=81=20Da?=
=?UTF-8?q?tabend=20-=20=E5=B8=A6=20AI=20=E7=9A=84=E6=96=B0=E4=B8=80?=
=?UTF-8?q?=E4=BB=A3=E4=BA=91=E5=8E=9F=E7=94=9F=E6=95=B0=E6=8D=AE=E6=B9=96?=
=?UTF-8?q?=E4=BB=93(Snowflake=20=E5=BC=80=E6=BA=90=E6=9B=BF=E4=BB=A3)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/java/apijson/orm/AbstractSQLConfig.java | 9 +++++++++
APIJSONORM/src/main/java/apijson/orm/SQLConfig.java | 2 ++
.../main/java/apijson/orm/exception/CommonException.java | 3 +++
3 files changed, 14 insertions(+)
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
index c1e33e0b..1a8a4f73 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
@@ -190,6 +190,7 @@ public abstract class AbstractSQLConfig, L exte
DATABASE_LIST.add(DATABASE_QUESTDB);
DATABASE_LIST.add(DATABASE_IOTDB);
DATABASE_LIST.add(DATABASE_SNOWFLAKE);
+ DATABASE_LIST.add(DATABASE_DATABEND);
DATABASE_LIST.add(DATABASE_DATABRICKS);
DATABASE_LIST.add(DATABASE_REDIS);
DATABASE_LIST.add(DATABASE_MONGODB);
@@ -1252,6 +1253,14 @@ public static boolean isSnowflake(String db) {
return DATABASE_SNOWFLAKE.equals(db);
}
+ @Override
+ public boolean isDatabend() {
+ return isDatabend(gainSQLDatabase());
+ }
+ public static boolean isDatabend(String db) {
+ return DATABASE_DATABEND.equals(db);
+ }
+
@Override
public boolean isDatabricks() {
return isDatabricks(gainSQLDatabase());
diff --git a/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java
index b8c9fad8..fd4eca1d 100755
--- a/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java
+++ b/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java
@@ -35,6 +35,7 @@ public interface SQLConfig, L extends List, L extends List
Date: Tue, 8 Jul 2025 23:16:13 +0800
Subject: [PATCH 12/41] =?UTF-8?q?=E8=85=BE=E8=AE=AF=E5=BC=80=E6=BA=90?=
=?UTF-8?q?=E4=B8=BB=E4=BD=93=E5=85=AC=E5=8F=B8=20THL=20A29=20Limited=20?=
=?UTF-8?q?=E6=94=B9=E4=B8=BA=20Tencent=EF=BC=8C=E5=B9=B6=E5=9C=A8=20LICEN?=
=?UTF-8?q?SE=20=E5=A4=B4=E9=83=A8=E8=AF=B4=E6=98=8E=E5=8F=98=E6=9B=B4?=
=?UTF-8?q?=E3=80=81=E4=BE=9D=E8=B5=96=E8=AF=B4=E6=98=8E=E7=A7=BB=E9=99=A4?=
=?UTF-8?q?=208.0=20=E8=B5=B7=E4=B8=8D=E5=86=8D=E4=BE=9D=E8=B5=96=E7=9A=84?=
=?UTF-8?q?=20fastjson?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
APIJSONORM/src/main/java/apijson/JSON.java | 2 +-
APIJSONORM/src/main/java/apijson/JSONCreator.java | 2 +-
APIJSONORM/src/main/java/apijson/JSONList.java | 2 +-
APIJSONORM/src/main/java/apijson/JSONMap.java | 2 +-
APIJSONORM/src/main/java/apijson/JSONParser.java | 2 +-
APIJSONORM/src/main/java/apijson/JSONRequest.java | 2 +-
APIJSONORM/src/main/java/apijson/JSONResponse.java | 2 +-
APIJSONORM/src/main/java/apijson/Log.java | 2 +-
APIJSONORM/src/main/java/apijson/MethodAccess.java | 2 +-
APIJSONORM/src/main/java/apijson/NotNull.java | 2 +-
APIJSONORM/src/main/java/apijson/RequestMethod.java | 2 +-
APIJSONORM/src/main/java/apijson/SQL.java | 2 +-
APIJSONORM/src/main/java/apijson/StringUtil.java | 2 +-
.../src/main/java/apijson/orm/AbstractFunctionParser.java | 2 +-
.../src/main/java/apijson/orm/AbstractObjectParser.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/AbstractParser.java | 2 +-
.../src/main/java/apijson/orm/AbstractSQLConfig.java | 2 +-
.../src/main/java/apijson/orm/AbstractSQLExecutor.java | 2 +-
.../src/main/java/apijson/orm/AbstractVerifier.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/Entry.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/FunctionParser.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/JSONRequest.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/Join.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/Logic.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/ObjectParser.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/Operation.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/Pair.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/Parser.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/ParserCreator.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/SQLConfig.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/SQLCreator.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/Subquery.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/Verifier.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/Visitor.java | 2 +-
.../main/java/apijson/orm/exception/CommonException.java | 2 +-
.../apijson/orm/exception/ConditionErrorException.java | 2 +-
.../java/apijson/orm/exception/ConflictException.java | 2 +-
.../java/apijson/orm/exception/NotExistException.java | 2 +-
.../java/apijson/orm/exception/NotLoggedInException.java | 2 +-
.../java/apijson/orm/exception/OutOfRangeException.java | 2 +-
.../orm/exception/UnsupportedDataTypeException.java | 2 +-
.../src/main/java/apijson/orm/exception/package-info.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/model/Access.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/model/AllColumn.java | 2 +-
.../src/main/java/apijson/orm/model/AllColumnComment.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/model/AllTable.java | 2 +-
.../src/main/java/apijson/orm/model/AllTableComment.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/model/Column.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/model/Document.java | 2 +-
.../src/main/java/apijson/orm/model/ExtendedProperty.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/model/Function.java | 2 +-
.../src/main/java/apijson/orm/model/PgAttribute.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/model/PgClass.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/model/Request.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/model/Script.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/model/SysColumn.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/model/SysTable.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/model/Table.java | 2 +-
.../src/main/java/apijson/orm/model/TestRecord.java | 2 +-
.../src/main/java/apijson/orm/model/package-info.java | 2 +-
APIJSONORM/src/main/java/apijson/orm/package-info.java | 2 +-
APIJSONORM/src/main/java/apijson/package-info.java | 2 +-
LICENSE | 8 ++++----
README-English.md | 2 +-
README.md | 2 +-
68 files changed, 71 insertions(+), 71 deletions(-)
diff --git a/APIJSONORM/src/main/java/apijson/JSON.java b/APIJSONORM/src/main/java/apijson/JSON.java
index c31170c4..61557985 100755
--- a/APIJSONORM/src/main/java/apijson/JSON.java
+++ b/APIJSONORM/src/main/java/apijson/JSON.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/JSONCreator.java b/APIJSONORM/src/main/java/apijson/JSONCreator.java
index fcabe2fe..df0d9066 100755
--- a/APIJSONORM/src/main/java/apijson/JSONCreator.java
+++ b/APIJSONORM/src/main/java/apijson/JSONCreator.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/JSONList.java b/APIJSONORM/src/main/java/apijson/JSONList.java
index 0aa448fc..092bf9f3 100644
--- a/APIJSONORM/src/main/java/apijson/JSONList.java
+++ b/APIJSONORM/src/main/java/apijson/JSONList.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/JSONMap.java b/APIJSONORM/src/main/java/apijson/JSONMap.java
index 0bf0b682..29d88f75 100755
--- a/APIJSONORM/src/main/java/apijson/JSONMap.java
+++ b/APIJSONORM/src/main/java/apijson/JSONMap.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/JSONParser.java b/APIJSONORM/src/main/java/apijson/JSONParser.java
index 6762e2bf..7c38a39d 100755
--- a/APIJSONORM/src/main/java/apijson/JSONParser.java
+++ b/APIJSONORM/src/main/java/apijson/JSONParser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/JSONRequest.java b/APIJSONORM/src/main/java/apijson/JSONRequest.java
index 0dccbd3e..c74dfe34 100755
--- a/APIJSONORM/src/main/java/apijson/JSONRequest.java
+++ b/APIJSONORM/src/main/java/apijson/JSONRequest.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/JSONResponse.java b/APIJSONORM/src/main/java/apijson/JSONResponse.java
index ab0564f9..c39aa1ac 100755
--- a/APIJSONORM/src/main/java/apijson/JSONResponse.java
+++ b/APIJSONORM/src/main/java/apijson/JSONResponse.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/Log.java b/APIJSONORM/src/main/java/apijson/Log.java
index b7b909d6..ba1a03bd 100755
--- a/APIJSONORM/src/main/java/apijson/Log.java
+++ b/APIJSONORM/src/main/java/apijson/Log.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/MethodAccess.java b/APIJSONORM/src/main/java/apijson/MethodAccess.java
index 31d45843..1804f7a7 100755
--- a/APIJSONORM/src/main/java/apijson/MethodAccess.java
+++ b/APIJSONORM/src/main/java/apijson/MethodAccess.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/NotNull.java b/APIJSONORM/src/main/java/apijson/NotNull.java
index d10a9369..1265ccac 100755
--- a/APIJSONORM/src/main/java/apijson/NotNull.java
+++ b/APIJSONORM/src/main/java/apijson/NotNull.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/RequestMethod.java b/APIJSONORM/src/main/java/apijson/RequestMethod.java
index 875200b7..27e4cab6 100755
--- a/APIJSONORM/src/main/java/apijson/RequestMethod.java
+++ b/APIJSONORM/src/main/java/apijson/RequestMethod.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/SQL.java b/APIJSONORM/src/main/java/apijson/SQL.java
index 110ae3d4..868f0d2a 100755
--- a/APIJSONORM/src/main/java/apijson/SQL.java
+++ b/APIJSONORM/src/main/java/apijson/SQL.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/StringUtil.java b/APIJSONORM/src/main/java/apijson/StringUtil.java
index 13b0ff21..17916100 100755
--- a/APIJSONORM/src/main/java/apijson/StringUtil.java
+++ b/APIJSONORM/src/main/java/apijson/StringUtil.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java
index ff2e484d..42831775 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java
index 5a39fd1f..c546ae24 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
index eab5a368..f02e7866 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
index 82808e3e..03e98e92 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
index 5ec59f36..4d6d28c0 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
index 0c52dca4..b10828ee 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/Entry.java b/APIJSONORM/src/main/java/apijson/orm/Entry.java
index a8aaf7bf..3e010435 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Entry.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Entry.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/FunctionParser.java b/APIJSONORM/src/main/java/apijson/orm/FunctionParser.java
index 155d80fa..8af02923 100644
--- a/APIJSONORM/src/main/java/apijson/orm/FunctionParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/FunctionParser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/JSONRequest.java b/APIJSONORM/src/main/java/apijson/orm/JSONRequest.java
index 0b772c23..40bfa147 100755
--- a/APIJSONORM/src/main/java/apijson/orm/JSONRequest.java
+++ b/APIJSONORM/src/main/java/apijson/orm/JSONRequest.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/Join.java b/APIJSONORM/src/main/java/apijson/orm/Join.java
index 39ca09a6..ea6f1059 100644
--- a/APIJSONORM/src/main/java/apijson/orm/Join.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Join.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/Logic.java b/APIJSONORM/src/main/java/apijson/orm/Logic.java
index bb8e806e..f860aa9a 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Logic.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Logic.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/ObjectParser.java b/APIJSONORM/src/main/java/apijson/orm/ObjectParser.java
index 8817886d..5d207f41 100755
--- a/APIJSONORM/src/main/java/apijson/orm/ObjectParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/ObjectParser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java b/APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java
index 243acf04..e02fd90f 100755
--- a/APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java
+++ b/APIJSONORM/src/main/java/apijson/orm/OnParseCallback.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/Operation.java b/APIJSONORM/src/main/java/apijson/orm/Operation.java
index 2976d09b..1c4f2dc5 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Operation.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Operation.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/Pair.java b/APIJSONORM/src/main/java/apijson/orm/Pair.java
index 94f2abcc..7661d07b 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Pair.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Pair.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/Parser.java b/APIJSONORM/src/main/java/apijson/orm/Parser.java
index ce726eb7..1492dfc1 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Parser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Parser.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/ParserCreator.java b/APIJSONORM/src/main/java/apijson/orm/ParserCreator.java
index d6eb1c7d..f3f8d375 100755
--- a/APIJSONORM/src/main/java/apijson/orm/ParserCreator.java
+++ b/APIJSONORM/src/main/java/apijson/orm/ParserCreator.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java
index b8c9fad8..f515b03c 100755
--- a/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java
+++ b/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/SQLCreator.java b/APIJSONORM/src/main/java/apijson/orm/SQLCreator.java
index bb5af96d..77625cfa 100755
--- a/APIJSONORM/src/main/java/apijson/orm/SQLCreator.java
+++ b/APIJSONORM/src/main/java/apijson/orm/SQLCreator.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java b/APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java
index a4467af8..6540771d 100755
--- a/APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java
+++ b/APIJSONORM/src/main/java/apijson/orm/SQLExecutor.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/Subquery.java b/APIJSONORM/src/main/java/apijson/orm/Subquery.java
index b3059e8c..ce6e7244 100644
--- a/APIJSONORM/src/main/java/apijson/orm/Subquery.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Subquery.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/Verifier.java b/APIJSONORM/src/main/java/apijson/orm/Verifier.java
index e2a0e8b4..4b926519 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Verifier.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Verifier.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java b/APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java
index a3c51694..37429098 100644
--- a/APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java
+++ b/APIJSONORM/src/main/java/apijson/orm/VerifierCreator.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/Visitor.java b/APIJSONORM/src/main/java/apijson/orm/Visitor.java
index f474bd91..5d1b6063 100755
--- a/APIJSONORM/src/main/java/apijson/orm/Visitor.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Visitor.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/CommonException.java b/APIJSONORM/src/main/java/apijson/orm/exception/CommonException.java
index e9ea583d..0086989b 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/CommonException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/CommonException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/ConditionErrorException.java b/APIJSONORM/src/main/java/apijson/orm/exception/ConditionErrorException.java
index fe2ccd76..44c43a29 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/ConditionErrorException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/ConditionErrorException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/ConflictException.java b/APIJSONORM/src/main/java/apijson/orm/exception/ConflictException.java
index ee258eee..a39d88d3 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/ConflictException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/ConflictException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/NotExistException.java b/APIJSONORM/src/main/java/apijson/orm/exception/NotExistException.java
index 5c5a42bc..69e34a80 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/NotExistException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/NotExistException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/NotLoggedInException.java b/APIJSONORM/src/main/java/apijson/orm/exception/NotLoggedInException.java
index 2fbbb89b..1e16b579 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/NotLoggedInException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/NotLoggedInException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/OutOfRangeException.java b/APIJSONORM/src/main/java/apijson/orm/exception/OutOfRangeException.java
index bde6fa42..043ba5a6 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/OutOfRangeException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/OutOfRangeException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/UnsupportedDataTypeException.java b/APIJSONORM/src/main/java/apijson/orm/exception/UnsupportedDataTypeException.java
index e272141c..1c7d7c27 100644
--- a/APIJSONORM/src/main/java/apijson/orm/exception/UnsupportedDataTypeException.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/UnsupportedDataTypeException.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/exception/package-info.java b/APIJSONORM/src/main/java/apijson/orm/exception/package-info.java
index 70d3bb96..073c6bda 100755
--- a/APIJSONORM/src/main/java/apijson/orm/exception/package-info.java
+++ b/APIJSONORM/src/main/java/apijson/orm/exception/package-info.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Access.java b/APIJSONORM/src/main/java/apijson/orm/model/Access.java
index e114f565..ab44f866 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/Access.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Access.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/AllColumn.java b/APIJSONORM/src/main/java/apijson/orm/model/AllColumn.java
index 90da2664..02906c6e 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/AllColumn.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/AllColumn.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/AllColumnComment.java b/APIJSONORM/src/main/java/apijson/orm/model/AllColumnComment.java
index fe98fa51..81e2c9fe 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/AllColumnComment.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/AllColumnComment.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/AllTable.java b/APIJSONORM/src/main/java/apijson/orm/model/AllTable.java
index 215fde31..2934ad0b 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/AllTable.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/AllTable.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/AllTableComment.java b/APIJSONORM/src/main/java/apijson/orm/model/AllTableComment.java
index 5dd4b0a4..49a4dee3 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/AllTableComment.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/AllTableComment.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Column.java b/APIJSONORM/src/main/java/apijson/orm/model/Column.java
index d38d4fda..573ab7fc 100755
--- a/APIJSONORM/src/main/java/apijson/orm/model/Column.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Column.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Document.java b/APIJSONORM/src/main/java/apijson/orm/model/Document.java
index 6f2a8bba..2e8db19c 100755
--- a/APIJSONORM/src/main/java/apijson/orm/model/Document.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Document.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/ExtendedProperty.java b/APIJSONORM/src/main/java/apijson/orm/model/ExtendedProperty.java
index 81227eb1..393a7e0d 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/ExtendedProperty.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/ExtendedProperty.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Function.java b/APIJSONORM/src/main/java/apijson/orm/model/Function.java
index b02175f4..da6c3f53 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/Function.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Function.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/PgAttribute.java b/APIJSONORM/src/main/java/apijson/orm/model/PgAttribute.java
index 7c85f9f4..dbd4b4b6 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/PgAttribute.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/PgAttribute.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/PgClass.java b/APIJSONORM/src/main/java/apijson/orm/model/PgClass.java
index 3a47b279..199a7ef8 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/PgClass.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/PgClass.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Request.java b/APIJSONORM/src/main/java/apijson/orm/model/Request.java
index 8e83a270..5d0d0409 100755
--- a/APIJSONORM/src/main/java/apijson/orm/model/Request.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Request.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Script.java b/APIJSONORM/src/main/java/apijson/orm/model/Script.java
index ddb60843..53cda432 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/Script.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Script.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/SysColumn.java b/APIJSONORM/src/main/java/apijson/orm/model/SysColumn.java
index 3e2c5c2b..a4d7ca88 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/SysColumn.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/SysColumn.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/SysTable.java b/APIJSONORM/src/main/java/apijson/orm/model/SysTable.java
index 221807c4..bb614231 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/SysTable.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/SysTable.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Table.java b/APIJSONORM/src/main/java/apijson/orm/model/Table.java
index 0135fd94..1ab004cc 100755
--- a/APIJSONORM/src/main/java/apijson/orm/model/Table.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Table.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/TestRecord.java b/APIJSONORM/src/main/java/apijson/orm/model/TestRecord.java
index b1ceaa77..32ad98f9 100644
--- a/APIJSONORM/src/main/java/apijson/orm/model/TestRecord.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/TestRecord.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/package-info.java b/APIJSONORM/src/main/java/apijson/orm/model/package-info.java
index af556632..a0b5641c 100755
--- a/APIJSONORM/src/main/java/apijson/orm/model/package-info.java
+++ b/APIJSONORM/src/main/java/apijson/orm/model/package-info.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/orm/package-info.java b/APIJSONORM/src/main/java/apijson/orm/package-info.java
index e0f9a3d5..76569c93 100755
--- a/APIJSONORM/src/main/java/apijson/orm/package-info.java
+++ b/APIJSONORM/src/main/java/apijson/orm/package-info.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/APIJSONORM/src/main/java/apijson/package-info.java b/APIJSONORM/src/main/java/apijson/package-info.java
index 42e24018..a4fcbeb2 100755
--- a/APIJSONORM/src/main/java/apijson/package-info.java
+++ b/APIJSONORM/src/main/java/apijson/package-info.java
@@ -1,4 +1,4 @@
-/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+/*Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0.*/
diff --git a/LICENSE b/LICENSE
index 1a71560c..9743dd5a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,18 +1,18 @@
Tencent is pleased to support the open source community by making APIJSON available.
-Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+Copyright (C) 2020 Tencent. All rights reserved.
APIJSON is licensed under the Apache License Version 2.0.
A copy of the Apache License Version 2.0 is included in this file.
+The copyright notice pertaining to the Tencent code in this repo was previously in the name of "THL A29 Limited."
+That entity has now been de-registered.
+You should treat all previously distributed copies of the code as if the copyright notice was in the name of "Tencent."
Other dependencies and licenses:
Open Source Software Licensed under the Apache License Version 2.0:
--------------------------------------------------------------------
-1. fastjson
-Copyright 1999-2019 Alibaba Group Holding Ltd.
-
Terms of Apache License Version 2.0
diff --git a/README-English.md b/README-English.md
index e7c9e6d0..ccafb985 100644
--- a/README-English.md
+++ b/README-English.md
@@ -1,5 +1,5 @@
Tencent is pleased to support the open source community by making APIJSON available.
-Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0
diff --git a/README.md b/README.md
index 44d0cc4c..c4b0cb8b 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
Tencent is pleased to support the open source community by making APIJSON available.
-Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+Copyright (C) 2020 Tencent. All rights reserved.
This source code is licensed under the Apache License Version 2.0
From 3c214394b8484ae422de41e25863d7298fa195ad Mon Sep 17 00:00:00 2001
From: wuzeng
Date: 2025年7月18日 16:39:06 +0800
Subject: [PATCH 13/41] =?UTF-8?q?fix:=20=E7=8E=B0=E5=9C=A8=E7=9A=84=20Join?=
=?UTF-8?q?.java=20=E4=B8=AD=20SQLConfig=20outerConfig=20=E9=87=8D?=
=?UTF-8?q?=E5=91=BD=E5=90=8D=E6=88=90=20onConfig=20=E5=8F=8A=E5=AF=B9?=
=?UTF-8?q?=E5=BA=94=E7=9A=84=20get=20set=20=E6=96=B9=E6=B3=95=EF=BC=8C?=
=?UTF-8?q?=E7=84=B6=E5=90=8E=E5=86=8D=E5=8A=A0=E5=9B=9E=E6=9D=A5=20SQLCon?=
=?UTF-8?q?fig=20outerConfig=EF=BC=8C=E7=84=B6=E5=90=8E=E4=B8=8B=E6=96=B9?=
=?UTF-8?q?=E7=9A=84=E9=94=AE=E5=80=BC=E5=AF=B9=E6=94=BE=E5=88=B0=20outerC?=
=?UTF-8?q?onfig=20=E4=B8=8A=EF=BC=8C=E5=90=8E=E9=9D=A2=E5=86=8D=E5=85=B7?=
=?UTF-8?q?=E4=BD=93=20AbstractSQLConfig=20gainWhereString=E3=80=82=201?=
=?UTF-8?q?=E3=80=81inner=20join=20=E6=9C=AC=E8=BA=AB=E6=98=AF=E6=9C=80?=
=?UTF-8?q?=E5=A4=96=E9=9D=A2=E5=A2=9E=E5=8A=A0=E6=9D=A1=E4=BB=B6=EF=BC=8C?=
=?UTF-8?q?=E6=B2=A1=E6=9C=89=E5=A2=9E=E5=8A=A0=202=E3=80=81onConfig=20=20?=
=?UTF-8?q?=20=20=20=20=20"@group":=20"key2+"=20=20//=20JOIN=20=E5=A4=96?=
=?UTF-8?q?=E5=B1=82=20GROYP=20BY=20key2=わ20=わ20=わ20=わ20=わ20=わ20=わ20=わ20=わ20=わ20=わ20?=
=?UTF-8?q?=20=わ20=わ20=わ20=わ20=わ20=わ20"@having":=20"count(key3)>0"=20=20//=20JOI?=
=?UTF-8?q?N=20=E5=A4=96=E5=B1=82=20HAVING=20count(key3)>0=20=20=20=20=20?=
=?UTF-8?q?=20=わ20=わ20=わ20=わ20=わ20=わ20=わ20=わ20=わ20=わ20=わ20=わ20"@order":=20"key2+,key3-?=
=?UTF-8?q?"=20=20//=20JOIN=20=E5=A4=96=E5=B1=82=20ORDER=20BY=20key2=20ASC?=
=?UTF-8?q?,=20key3=20DESC=20=20=E6=9C=AC=E8=BA=AB=E8=BF=99=E4=BA=9B?=
=?UTF-8?q?=E6=9D=A1=E4=BB=B6=E5=B0=B1=E6=98=AF=E5=8A=A0=E5=88=B0=E6=9C=80?=
=?UTF-8?q?=E5=A4=96=E5=B1=82=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../main/java/apijson/orm/AbstractParser.java | 42 ++++++-
.../java/apijson/orm/AbstractSQLConfig.java | 105 +++++++++++-------
.../src/main/java/apijson/orm/Join.java | 34 ++++--
3 files changed, 131 insertions(+), 50 deletions(-)
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
index eab5a368..93657a1c 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
@@ -1563,7 +1563,39 @@ else if (join != null){
throw new UnsupportedDataTypeException(TAG + ".onJoinParse join 只能是 String 或 Map 类型!");
}
- Set> set = joinMap == null ? null : joinMap.entrySet();
+ List> slashKeys = new ArrayList();
+ List> nonSlashKeys = new ArrayList();
+ Set> entries = joinMap == null ? null : joinMap.entrySet();
+
+ if (entries == null || entries.isEmpty()) {
+ Log.e(TAG, "onJoinParse set == null || set.isEmpty()>> return null;");
+ return null;
+ }
+ for (Entry e : entries) {
+ String path = e.getKey();
+ if (path != null && path.indexOf("/")> 0) {
+ slashKeys.add(e); // 以 / 开头的 key,例如 whereJoinMap = new LinkedHashMap();
+
+ for (Entry e : nonSlashKeys) {
+ String tableKey = e.getKey(); // 如 "Location_info"
+ Object tableObj = e.getValue(); // value 是 Map
+
+ if (request.containsKey(tableKey)) {
+ whereJoinMap.put(tableKey, tableObj);
+ } else {
+ Log.w(TAG, "跳过 join 中 key = " + tableKey + ",因为它不在 request 中");
+ }
+ }
+
+
+ Set> set = joinMap == null ? null : new LinkedHashSet(slashKeys);
+ ;
if (set == null || set.isEmpty()) {
Log.e(TAG, "onJoinParse set == null || set.isEmpty()>> return null;");
return null;
@@ -1759,9 +1791,15 @@ else if (join != null){
j.setAlias(alias);
M outerObj = (M) JSON.createJSONObject((Map) outer);
- j.setOuter(outerObj);
+ j.setOn(outerObj);
j.setRequest(requestObj);
+ if (whereJoinMap.containsKey(table)) {
+ Object rawOuter = whereJoinMap.get(table);
+ M outerObj1 = (M) JSON.createJSONObject((Map) rawOuter);
+ j.setOuter(outerObj1);
+ }
+
if (arrKey != null) {
Integer count = getInteger(parentPathObj, apijson.JSONRequest.KEY_COUNT);
j.setCount(count == null ? getDefaultQueryCount() : count);
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
index de1d17dc..2d9c156f 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
@@ -5,42 +5,21 @@
package apijson.orm;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.regex.Pattern;
-
import apijson.*;
import apijson.orm.Join.On;
import apijson.orm.exception.NotExistException;
import apijson.orm.exception.UnsupportedDataTypeException;
-import apijson.orm.model.Access;
-import apijson.orm.model.AllColumn;
-import apijson.orm.model.AllColumnComment;
-import apijson.orm.model.AllTable;
-import apijson.orm.model.AllTableComment;
-import apijson.orm.model.Column;
-import apijson.orm.model.Document;
-import apijson.orm.model.ExtendedProperty;
-import apijson.orm.model.Function;
-import apijson.orm.model.PgAttribute;
-import apijson.orm.model.PgClass;
-import apijson.orm.model.Request;
-import apijson.orm.model.SysColumn;
-import apijson.orm.model.SysTable;
-import apijson.orm.model.Table;
-import apijson.orm.model.TestRecord;
+import apijson.orm.model.*;
+
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
import static apijson.JSON.getBoolean;
import static apijson.JSON.getString;
import static apijson.JSONMap.*;
-import static apijson.RequestMethod.DELETE;
-import static apijson.RequestMethod.GET;
-import static apijson.RequestMethod.POST;
-import static apijson.RequestMethod.PUT;
-import static apijson.SQL.AND;
-import static apijson.SQL.NOT;
-import static apijson.SQL.ON;
-import static apijson.SQL.OR;
+import static apijson.RequestMethod.*;
+import static apijson.SQL.*;
/**config sql for JSON Request
* @author Lemon
@@ -1574,7 +1553,7 @@ public String gainGroupString(boolean hasPrefix) {
continue;
}
- SQLConfig ocfg = join.getOuterConfig();
+ SQLConfig ocfg = join.getOnConfig();
SQLConfig cfg = (ocfg != null && ocfg.getGroup() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
if (cfg != null) {
@@ -1589,6 +1568,23 @@ public String gainGroupString(boolean hasPrefix) {
first = false;
}
}
+
+ ////先处理左/右关联,内关联忽略
+ //SQLConfig outerConfig = join.getOuterConfig();
+ //SQLConfig outerConfig2 = (outerConfig != null && outerConfig.getGroup() != null) || join.isLeftOrRightJoin() ? outerConfig : null;
+ //
+ //if (outerConfig2 != null) {
+ // outerConfig2.setMain(false).setKeyPrefix(true);
+ // //if (StringUtil.isEmpty(cfg.getAlias(), true)) {
+ // // cfg.setAlias(cfg.getTable());
+ // //}
+ // String c = ((AbstractSQLConfig, ?, ?>) outerConfig2).gainGroupString(false);
+ //
+ // if (StringUtil.isNotEmpty(c, true)) {
+ // joinGroup += (first ? "" : ", ") + c;
+ // first = false;
+ // }
+ //}
}
}
@@ -1650,7 +1646,7 @@ public String gainHavingString(boolean hasPrefix) throws Exception {
continue;
}
- SQLConfig ocfg = join.getOuterConfig();
+ SQLConfig ocfg = join.getOnConfig();
SQLConfig cfg = (ocfg != null && ocfg.getHaving() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
if (cfg != null) {
@@ -1763,7 +1759,7 @@ public String gainSampleString(boolean hasPrefix) {
continue;
}
- SQLConfig ocfg = join.getOuterConfig();
+ SQLConfig ocfg = join.getOnConfig();
SQLConfig cfg = (ocfg != null && ocfg.getSample() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
if (cfg != null) {
@@ -1833,7 +1829,7 @@ public String gainLatestString(boolean hasPrefix) {
continue;
}
- SQLConfig ocfg = join.getOuterConfig();
+ SQLConfig ocfg = join.getOnConfig();
SQLConfig cfg = (ocfg != null && ocfg.getLatest() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
if (cfg != null) {
@@ -1898,7 +1894,7 @@ public String gainPartitionString(boolean hasPrefix) {
continue;
}
- SQLConfig ocfg = join.getOuterConfig();
+ SQLConfig ocfg = join.getOnConfig();
SQLConfig cfg = (ocfg != null && ocfg.getPartition() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
if (cfg != null) {
@@ -1963,7 +1959,7 @@ public String gainFillString(boolean hasPrefix) {
continue;
}
- SQLConfig ocfg = join.getOuterConfig();
+ SQLConfig ocfg = join.getOnConfig();
SQLConfig cfg = (ocfg != null && ocfg.getFill() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
if (cfg != null) {
@@ -2029,6 +2025,7 @@ public AbstractSQLConfig setOrder(String order) {
public String gainOrderString(boolean hasPrefix) {
//加上子表的 order
String joinOrder = "";
+ String joinOuterOrder = "";
if (joinList != null) {
boolean first = true;
for (Join join : joinList) {
@@ -2036,7 +2033,7 @@ public String gainOrderString(boolean hasPrefix) {
continue;
}
- SQLConfig ocfg = join.getOuterConfig();
+ SQLConfig ocfg = join.getOnConfig();
SQLConfig cfg = (ocfg != null && ocfg.getOrder() != null) || join.isLeftOrRightJoin() ? ocfg : join.getJoinConfig();
if (cfg != null) {
@@ -2345,7 +2342,7 @@ public String gainColumnString(boolean inSQLJoin) throws Exception {
continue;
}
- SQLConfig ocfg = join.getOuterConfig();
+ SQLConfig ocfg = join.getOnConfig();
boolean isEmpty = ocfg == null || ocfg.getColumn() == null;
boolean isLeftOrRightJoin = join.isLeftOrRightJoin();
@@ -3729,8 +3726,9 @@ protected String concatJoinWhereString(String whereString) throws Exception {
List pvl = new ArrayList(getPreparedValueList());
SQLConfig jc;
+ SQLConfig outerConfig;
String js;
-
+ boolean isWsEmpty = StringUtil.isEmpty(ws, true);
boolean changed = false;
// 各种 JOIN 没办法统一用 & | !连接,只能按优先级,和 @combine 一样?
for (Join j : joinList) {
@@ -3741,6 +3739,24 @@ protected String concatJoinWhereString(String whereString) throws Exception {
case "@": // APP JOIN
case "<": // LEFT JOIN case ">": // RIGHT JOIN
+ outerConfig = j.getOuterConfig();
+ if (outerConfig == null){
+ break;
+ }
+ boolean isMain1 = outerConfig.isMain();
+ outerConfig.setMain(false).setPrepared(isPrepared()).setPreparedValueList(new ArrayList());
+ String outerWhere = outerConfig.gainWhereString(false);
+
+ int logic1 = Logic.getType(jt);
+ newWs += " ( "
+ + gainCondition(
+ Logic.isNot(logic1),
+ ws
+ + ( isWsEmpty ? "" : (Logic.isAnd(logic1) ? AND : OR) )
+ + " ( " + outerWhere + " ) "
+ )
+ + " ) ";
+ changed = true;
break;
case "&": // INNER JOIN: A & B
@@ -3761,7 +3777,7 @@ protected String concatJoinWhereString(String whereString) throws Exception {
boolean isSideJoin = "^".equals(jt);
boolean isAntiJoin = "(".equals(jt);
boolean isForeignJoin = ")".equals(jt);
- boolean isWsEmpty = StringUtil.isEmpty(ws, true);
+ //boolean isWsEmpty = StringUtil.isEmpty(ws, true);
if (isWsEmpty) {
if (isOuterJoin) { // ! OUTER JOIN: ! (A | B)
@@ -5202,7 +5218,7 @@ public String gainJoinString() throws Exception {
);
}
- SQLConfig oc = j.getOuterConfig();
+ SQLConfig oc = j.getOnConfig();
String ow = null;
if (oc != null) {
oc.setPrepared(isPrepared());
@@ -6305,13 +6321,22 @@ else if (joinConfig.getDatabase().equals(config.getDatabase()) == false) {
joinConfig.setMain(false).setKeyPrefix(true);
+ if (join.getOn() != null) {
+ SQLConfig onConfig = newSQLConfig(method, table, alias, join.getOn(), null, false, callback);
+ onConfig.setMain(false)
+ .setKeyPrefix(true)
+ .setDatabase(joinConfig.getDatabase())
+ .setSchema(joinConfig.getSchema()); //解决主表 JOIN 副表,引号不一致
+
+ join.setOnConfig(onConfig);
+ }
+
if (join.getOuter() != null) {
SQLConfig outerConfig = newSQLConfig(method, table, alias, join.getOuter(), null, false, callback);
outerConfig.setMain(false)
.setKeyPrefix(true)
.setDatabase(joinConfig.getDatabase())
.setSchema(joinConfig.getSchema()); //解决主表 JOIN 副表,引号不一致
-
join.setOuterConfig(outerConfig);
}
}
diff --git a/APIJSONORM/src/main/java/apijson/orm/Join.java b/APIJSONORM/src/main/java/apijson/orm/Join.java
index 39ca09a6..411bb29c 100644
--- a/APIJSONORM/src/main/java/apijson/orm/Join.java
+++ b/APIJSONORM/src/main/java/apijson/orm/Join.java
@@ -25,12 +25,14 @@ public class Join, L extends List> {
private List onList; // ON User.id = Moment.userId AND ...
private M request; // { "id@":"/Moment/userId" }
- private M outer; // "join": { " joinConfig;
private SQLConfig cacheConfig;
- private SQLConfig outerConfig;
+ private SQLConfig onConfig;
+ private SQLConfig outerConfig;
public String getPath() {
return path;
@@ -78,13 +80,29 @@ public M getRequest() {
public void setRequest(M request) {
this.request = request;
}
- public M getOuter() {
- return outer;
+ public M getOn() {
+ return on;
+ }
+ public void setOn(M on) {
+ this.on = on;
}
+
public void setOuter(M outer) {
this.outer = outer;
}
+ public M getOuter() {
+ return outer;
+ }
+
+ public SQLConfig getOuterConfig() {
+ return outerConfig;
+ }
+
+ public void setOuterConfig(SQLConfig outerConfig) {
+ this.outerConfig = outerConfig;
+ }
+
public SQLConfig getJoinConfig() {
return joinConfig;
}
@@ -97,11 +115,11 @@ public SQLConfig getCacheConfig() {
public void setCacheConfig(SQLConfig cacheConfig) {
this.cacheConfig = cacheConfig;
}
- public SQLConfig getOuterConfig() {
- return outerConfig;
+ public SQLConfig getOnConfig() {
+ return onConfig;
}
- public void setOuterConfig(SQLConfig outerConfig) {
- this.outerConfig = outerConfig;
+ public void setOnConfig(SQLConfig onConfig) {
+ this.onConfig = onConfig;
}
public boolean isOne2One() {
From 2122b8c89408bfb48ec60862057cb428c74904fb Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年7月20日 12:37:47 +0800
Subject: [PATCH 14/41] =?UTF-8?q?=E4=BC=98=E5=8C=96=20AbstractParser.java?=
=?UTF-8?q?=20=E7=BC=A9=E8=BF=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../main/java/apijson/orm/AbstractParser.java | 54 +++++++++----------
1 file changed, 27 insertions(+), 27 deletions(-)
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
index 93657a1c..8e3c3a29 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
@@ -1563,39 +1563,39 @@ else if (join != null){
throw new UnsupportedDataTypeException(TAG + ".onJoinParse join 只能是 String 或 Map 类型!");
}
- List> slashKeys = new ArrayList();
- List> nonSlashKeys = new ArrayList();
- Set> entries = joinMap == null ? null : joinMap.entrySet();
+ List> slashKeys = new ArrayList();
+ List> nonSlashKeys = new ArrayList();
+ Set> entries = joinMap == null ? null : joinMap.entrySet();
- if (entries == null || entries.isEmpty()) {
- Log.e(TAG, "onJoinParse set == null || set.isEmpty()>> return null;");
- return null;
- }
- for (Entry e : entries) {
- String path = e.getKey();
- if (path != null && path.indexOf("/")> 0) {
- slashKeys.add(e); // 以 / 开头的 key,例如 > return null;");
+ return null;
+ }
+ for (Entry e : entries) {
+ String path = e.getKey();
+ if (path != null && path.indexOf("/")> 0) {
+ slashKeys.add(e); // 以 / 开头的 key,例如 whereJoinMap = new LinkedHashMap();
+ Map whereJoinMap = new LinkedHashMap();
- for (Entry e : nonSlashKeys) {
- String tableKey = e.getKey(); // 如 "Location_info"
- Object tableObj = e.getValue(); // value 是 Map
+ for (Entry e : nonSlashKeys) {
+ String tableKey = e.getKey(); // 如 "Location_info"
+ Object tableObj = e.getValue(); // value 是 Map
+
+ if (request.containsKey(tableKey)) {
+ whereJoinMap.put(tableKey, tableObj);
+ } else {
+ Log.w(TAG, "跳过 join 中 key = " + tableKey + ",因为它不在 request 中");
+ }
+ }
- if (request.containsKey(tableKey)) {
- whereJoinMap.put(tableKey, tableObj);
- } else {
- Log.w(TAG, "跳过 join 中 key = " + tableKey + ",因为它不在 request 中");
- }
- }
+ Set> set = joinMap == null ? null : new LinkedHashSet(slashKeys);
- Set> set = joinMap == null ? null : new LinkedHashSet(slashKeys);
- ;
if (set == null || set.isEmpty()) {
Log.e(TAG, "onJoinParse set == null || set.isEmpty()>> return null;");
return null;
From 5451f4be55e57d26e60813da5afb88c9b001f52d Mon Sep 17 00:00:00 2001
From: GeXin97 <141294410+gexin97@users.noreply.github.com>
Date: 2025年7月24日 09:57:21 +0800
Subject: [PATCH 15/41] Update Document.md
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
3.2添加对compat: true的描述
---
Document.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document.md b/Document.md
index a97f7b82..29543da9 100644
--- a/Document.md
+++ b/Document.md
@@ -420,7 +420,7 @@ DELETE:
删除数据 | base_url/delete/ | {
TableName:{< 减少 或 去除 | "key-":Object,与"key+"相反 | "balance-":100.00,对应SQL是`balance = balance - 100.00`,余额减少100.00,即花费了100元 比较运算 |>, <,>=, <= 比较运算符,用于
1 提供 "id{}":"<=90000" 这种条件范围的简化写法
2 实现子查询相关比较运算
不支持 "key=":Object 和 "key!=":Object 这两种写法,直接用更简单的 "key":Object 和 "key!":Object 替代。 | 1 ["id<=":90000](http://apijson.cn:8080/get/{"[]":{"user":{"id<=":90000}}}),对应 SQL 是`id<=90000`,查询符合id<=90000的一个user数组
2 ["id>@":{
"from":"Comment",
"Comment":{
"@column":"min(userId)"
}
}](http://apijson.cn:8080/get/{"User":{"id>@":{"from":"Comment","Comment":{"@column":"min(userId)"}}}})
WHERE id>(SELECT min(userId) FROM Comment)
逻辑运算 | &, \|, ! 逻辑运算符,对应数据库 SQL 中的 AND, OR, NOT。
横或纵与:同一键值对的值内条件默认 \| 或连接,可以在 key 后加逻辑运算符来具体指定;不同键值对的条件默认 & 与连接,可以用下面说明的对象关键词 @combine 来具体指定。
1 & 可用于 "key&{}":"条件"等
2 \| 可用于 "key\|{}":"条件", "key\|{}":[]等,一般可省略
3 ! 可单独使用,如 "key!":Object,也可像 &,\| 一样配合其他功能符使用
"key!":null 无效,null 值会导致整个键值对被忽略解析,可以用 "key{}":"!=null" 替代,
"key":null 同理,用 "key{}":"=null" 替代。 | 1 ["id&{}":">80000,<=90000"](http://apijson.cn:8080/head/{"user":{"id&{}":">80000,<=90000"}}),对应sql是`id>80000 AND id<=90000`,即id满足id>80000 & id<=90000
2 ["id\|{}":">90000,<=80000"](http://apijson.cn:8080/head/{"user":{"id\|{}":">90000,<=80000"}}),同 "id{}":">90000,<=80000",对应 SQL 是`id>90000 OR id<=80000`,即 id 满足 id>90000 \| id<=80000
3 ["id!{}":[82001,38710]](http://apijson.cn:8080/head/{"User":{"id!{}":[82001,38710]}}),对应 SQL 是`id NOT IN(82001,38710)`,即 id 满足 ! (id=82001 \| id=38710),可过滤黑名单的消息
- 数组关键词,可自定义 | "key":Object,key为 "[]":{} 中 {} 内的关键词,Object 的类型由 key 指定
1 "count":5,查询数量,0 表示最大值,默认值为 10,默认最大值为 100
2 "page":1,查询页码,从 0 开始,默认值为 0,默认最大值为 100,一般和 count 一起用
3 "query":2,查询内容
0-对象,1-总数和分页详情,2-数据、总数和分页详情
总数关键词为 total,分页详情关键词为 info,
它们都和 query 同级,通过引用赋值得到自定义 key:value 键值对,不传则返回默认键值对,例如
"total@":"/[]/total", "info@":"/[]/info"
这里query及total仅为GET类型的请求提供方便,
一般可直接用HEAD类型的请求获取总数
4 "join":"&/Table0,\"join":{
"&/Table0":{}, // 支持 ON 多个字段关联,
"\ "key0":value0, // 其它ON条件
"key2":value2,
...
"@combine":"...", // 其它ON条件的组合方式
"@column":"...", // 外层 SELECT
"@group":"...", // 外层 GROUP BY
"@having":"..." // 外层 HAVING
}
}
多表连接方式:
"@" - APP JOIN
"\<" - LEFT JOIN
">" - RIGHT JOIN
"&" - INNER JOIN
"\|" - FULL JOIN
"!" - OUTER JOIN
"*" - CROSS JOIN
"^" - SIDE JOIN
"(" - ANTI JOIN
")" - FOREIGN JOIN
其中 @ APP JOIN 为应用层连表,会从已查出的主表里取得所有副表 key@ 关联的主表内的 refKey 作为一个数组 refKeys: [value0, value1...],然后把原来副表 count 次查询 key=$refKey 的 SQL 用 key IN($refKeys) 的方式合并为一条 SQL 来优化性能;
其它 JOIN 都是 SQL JOIN,具体功能和 MySQL,PostgreSQL 等数据库的 JOIN 一一对应
`"join":"`"MainTable":{},`
`"ViceTable":{"key@":"/MainTable/refKey"}`
会对应生成
`MainTable LEFT JOIN ViceTable`
`ON ViceTable.key=MainTable.refKey` AND 其它ON条件
除了 = 等价关联,也支持 ! 不等关联、\> \< \>= \<= 等比较关联和 $ ~ {} 等其它复杂关联方式
5 "otherKey":Object,自定义关键词,名称和以上系统关键词不一样,且原样返回上传的值 | 1 查询User数组,最多5个:
["count":5](http://apijson.cn:8080/get/{"[]":{"count":5,"User":{}}})
对应 SQL 是`LIMIT 5`
2 查询第3页的User数组,每页5个:
["count":5,
"page":3](http://apijson.cn:8080/get/{"[]":{"count":5,"page":3,"User":{}}})
对应 SQL 是`LIMIT 5 OFFSET 15`
3 查询User数组和对应的User总数:
["[]":{
"query":2,
"User":{}
},
"total@":"/[]/total", // 可省略
"info@":"/[]/info" // 可省略](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}},"total@":"%252F[]%252Ftotal","info@":"%252F[]%252Finfo"})
返回的数据中,总数及分页详情结构为:
"total":139, // 总数
"info":{ // 分页详情
"total":139, // 总数
"count":5, // 每页数量
"page":0, // 当前页码
"max":27, // 最大页码
"more":true, // 是否还有更多
"first":true, // 是否为首页
"last":false // 是否为尾页
}
4 Moment INNER JOIN User LEFT JOIN Comment:
["[]":{
"join":"&/User/id@,\ "Moment":{
"@group":"id" // 主副表不是一对一,要去除重复数据
},
"User":{
"name~":"t",
"id@":"/Moment/userId"
},
"Comment":{
"momentId@":"/Moment/id"
}
}](http://apijson.cn/api/?type=JSON&url=http://apijson.cn:8080/get&json=%7B%22%5B%5D%22:%7B%22count%22:5,%22join%22:%22%26%2FUser%2Fid@,%3C%2FComment%22,%22Moment%22:%7B%22@column%22:%22id,userId,content%22,%22@group%22:%22id%22%7D,%22User%22:%7B%22name~%22:%22t%22,%22id@%22:%22%2FMoment%2FuserId%22,%22@column%22:%22id,name,head%22%7D,%22Comment%22:%7B%22momentId@%22:%22%2FMoment%2Fid%22,%22@column%22:%22id,momentId,content%22%7D%7D%7D)
5 每一层都加当前用户名:
["User":{},
"[]":{
"name@":"User/name", // 自定义关键词
"Moment":{}
}](http://apijson.cn:8080/get/{"User":{},"[]":{"name@":"User%252Fname","Moment":{}}})
+ 数组关键词,可自定义 | "key":Object,key为 "[]":{} 中 {} 内的关键词,Object 的类型由 key 指定
1 "count":5,查询数量,0 表示最大值,默认值为 10,默认最大值为 100
2 "page":1,查询页码,从 0 开始,默认值为 0,默认最大值为 100,一般和 count 一起用
3 "query":2,查询内容
0-对象,1-总数和分页详情,2-数据、总数和分页详情
总数关键词为 total,分页详情关键词为 info,
它们都和 query 同级,通过引用赋值得到自定义 key:value 键值对,不传则返回默认键值对,例如
"total@":"/[]/total", "info@":"/[]/info"
这里query及total仅为GET类型的请求提供方便,
一般可直接用HEAD类型的请求获取总数
4 compat: true
处理最外层查询字段有特殊处理的情况下"query":2返回查询总数不准确的问题:
如DISTINCT去重、Aggregate 函数等
5 "join":"&/Table0,\"join":{
"&/Table0":{}, // 支持 ON 多个字段关联,
"\ "key0":value0, // 其它ON条件
"key2":value2,
...
"@combine":"...", // 其它ON条件的组合方式
"@column":"...", // 外层 SELECT
"@group":"...", // 外层 GROUP BY
"@having":"..." // 外层 HAVING
}
}
多表连接方式:
"@" - APP JOIN
"\<" - LEFT JOIN
">" - RIGHT JOIN
"&" - INNER JOIN
"\|" - FULL JOIN
"!" - OUTER JOIN
"*" - CROSS JOIN
"^" - SIDE JOIN
"(" - ANTI JOIN
")" - FOREIGN JOIN
其中 @ APP JOIN 为应用层连表,会从已查出的主表里取得所有副表 key@ 关联的主表内的 refKey 作为一个数组 refKeys: [value0, value1...],然后把原来副表 count 次查询 key=$refKey 的 SQL 用 key IN($refKeys) 的方式合并为一条 SQL 来优化性能;
其它 JOIN 都是 SQL JOIN,具体功能和 MySQL,PostgreSQL 等数据库的 JOIN 一一对应
`"join":"`"MainTable":{},`
`"ViceTable":{"key@":"/MainTable/refKey"}`
会对应生成
`MainTable LEFT JOIN ViceTable`
`ON ViceTable.key=MainTable.refKey` AND 其它ON条件
除了 = 等价关联,也支持 ! 不等关联、\> \< \>= \<= 等比较关联和 $ ~ {} 等其它复杂关联方式
6 "otherKey":Object,自定义关键词,名称和以上系统关键词不一样,且原样返回上传的值 | 1 查询User数组,最多5个:
["count":5](http://apijson.cn:8080/get/{"[]":{"count":5,"User":{}}})
对应 SQL 是`LIMIT 5`
2 查询第3页的User数组,每页5个:
["count":5,
"page":3](http://apijson.cn:8080/get/{"[]":{"count":5,"page":3,"User":{}}})
对应 SQL 是`LIMIT 5 OFFSET 15`
3 查询User数组和对应的User总数:
["[]":{
"query":2,
"User":{}
},
"total@":"/[]/total", // 可省略
"info@":"/[]/info" // 可省略](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}},"total@":"%252F[]%252Ftotal","info@":"%252F[]%252Finfo"})
返回的数据中,总数及分页详情结构为:
"total":139, // 总数
"info":{ // 分页详情
"total":139, // 总数
"count":5, // 每页数量
"page":0, // 当前页码
"max":27, // 最大页码
"more":true, // 是否还有更多
"first":true, // 是否为首页
"last":false // 是否为尾页
}
4查询User数组ID唯一情况下的User总数:
["[]":{
"query":2,
"compat":"true",
"User":{"@column":"DISTINCT id"}
},
"total@":"/[]/total", // 可省略
"info@":"/[]/info" // 可省略](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}},"total@":"%252F[]%252Ftotal","info@":"%252F[]%252Finfo"})
返回的数据中,总数及分页详情结构为:
"total":139, // 总数
"info":{ // 分页详情
"total":139, // 总数
"count":5, // 每页数量
"page":0, // 当前页码
"max":27, // 最大页码
"more":true, // 是否还有更多
"first":true, // 是否为首页
"last":false // 是否为尾页
}
5 Moment INNER JOIN User LEFT JOIN Comment:
["[]":{
"join":"&/User/id@,\ "Moment":{
"@group":"id" // 主副表不是一对一,要去除重复数据
},
"User":{
"name~":"t",
"id@":"/Moment/userId"
},
"Comment":{
"momentId@":"/Moment/id"
}
}](http://apijson.cn/api/?type=JSON&url=http://apijson.cn:8080/get&json=%7B%22%5B%5D%22:%7B%22count%22:5,%22join%22:%22%26%2FUser%2Fid@,%3C%2FComment%22,%22Moment%22:%7B%22@column%22:%22id,userId,content%22,%22@group%22:%22id%22%7D,%22User%22:%7B%22name~%22:%22t%22,%22id@%22:%22%2FMoment%2FuserId%22,%22@column%22:%22id,name,head%22%7D,%22Comment%22:%7B%22momentId@%22:%22%2FMoment%2Fid%22,%22@column%22:%22id,momentId,content%22%7D%7D%7D)
6 每一层都加当前用户名:
["User":{},
"[]":{
"name@":"User/name", // 自定义关键词
"Moment":{}
}](http://apijson.cn:8080/get/{"User":{},"[]":{"name@":"User%252Fname","Moment":{}}})
对象关键词,可自定义 | "@key":Object,@key 为 Table:{} 中 {} 内的关键词,Object 的类型由 @key 指定
1 "@combine":"key0 \| (key1 & (key2 \| !key3))...",条件组合方式,最终按
(其它key条件 AND 连接) AND (key0条件 OR (key1条件 AND (key2条件 OR (NOT key3条件))))
这种方式连接,其中 "其它key" 是指与 @combine 在同一对象,且未被它声明的条件 key,默认都是 & 连接。注意不要缺少或多余任何一个空格。
2 "@column":"column;function(arg)...",返回字段
3 "@order":"column0+,column1-...",排序方式
4 "@group":"column0,column1...",分组方式。如果 @column 里声明了 Table 的 id,则 id 也必须在 @group 中声明;其它情况下必须满足至少一个条件:
1.分组的 key 在 @column 里声明
2.Table 主键在 @group 中声明
5 "@having":"function0(...)?value0;function1(...)?value1;function2(...)?value2..." // OR 连接,或
"@having&":"function0(...)?value0;function1(...)?value1;function2(...)?value2..." // AND 连接,或
"@having":{
"h0":"function0(...)?value0",
"h1":function1(...)?value1",
"h2":function2(...)?value2...",
"@combine":"h0 & (h1 \| !h2)" // 任意组合,非必传
}
SQL 函数条件,一般和 @group 一起用,函数一般在 @column 里声明
6 "@schema":"sys",集合空间(数据库名/模式),非默认的值可通过它来指定,可以在最外层作为全局默认配置
7 "@database":"POSTGRESQL",数据库类型,非默认的值可通过它来指定,可以在最外层作为全局默认配置
8 "@datasource":"DRUID",跨数据源,非默认的值可通过它来指定,可以在最外层作为全局默认配置
9 "@json":"key0,key1...",转为 JSON 格式返回,符合 JSONObject 则转为 {...},符合 JSONArray 则转为 \[...]
10 "@role":"OWNER",来访角色,包括
UNKNOWN,LOGIN,CONTACT,CIRCLE,OWNER,ADMIN,
可以在最外层作为全局默认配置,
可自定义其它角色并重写 Verifier.verify 等相关方法来自定义校验
11 "@explain":true,性能分析,可以在最外层作为全局默认配置
12 "@raw":"key0,key1...",其中 key0, key1 都对应有键值对
"key0":"SQL片段或SQL片段的别名",
"key1":"SQL片段或SQL片段的别名"
自定义原始SQL片段,可扩展嵌套SQL函数等复杂语句,必须是后端已配置的,只有其它功能符都做不到才考虑,谨慎使用,注意防 SQL 注入
13 "@null":"key1,key2...",空值键值对,自动插入 key1:null, key2:null ... 并作为有效键值对执行,作为条件时对应 SQL 是 `WHERE tag IS NULL`,作为值时对应 SQL 是 `SET tag = NULL`
14 "@otherKey":Object,自定义关键词,名称和以上系统关键词不一样,且原样返回上传的值 | 1 搜索 name 或 tag 任何一个字段包含字符 a 的 User 列表:
["name~":"a",
"tag~":"a",
"@combine":"name~ \| tag~"](http://apijson.cn:8080/get/{"User[]":{"count":10,"User":{"@column":"id,name,tag","name~":"a","tag~":"a","@combine":"name~%20%7C%20tag~"}}})
对应SQL是`name REGEXP 'a' OR tag REGEXP 'a'`
2 只查询 id,sex,name 这几列并且请求结果也按照这个顺序:
["@column":"id,sex,name"](http://apijson.cn:8080/get/{"User":{"@column":"id,sex,name","id":38710}})
对应 SQL 是`SELECT id,sex,name`
3 查询按 name 降序、id 默认顺序 排序的 User 数组:
["@order":"name-,id"](http://apijson.cn:8080/get/{"[]":{"count":10,"User":{"@column":"name,id","@order":"name-,id"}}})
对应 SQL 是`ORDER BY name DESC,id`
4 查询按 userId 分组的 Moment 数组:
["@group":"userId,id"](http://apijson.cn:8080/get/{"[]":{"count":10,"Moment":%7B"@column":"userId,id","@group":"userId,id"}}})
对应 SQL 是`GROUP BY userId,id`
5 查询 按 userId 分组、id 最大值>=100 的 Moment 数组:
["@column":"userId;max(id)",
"@group":"userId",
"@having":"max(id)>=100"](http://apijson.cn:8080/get/{"[]":{"count":10,"Moment":{"@column":"userId%253Bmax(id)","@group":"userId","@having":"max(id)>=100"}}})
对应 SQL 是`SELECT userId,max(id) ... GROUP BY userId HAVING max(id)>=100`
还可以指定函数返回名:
["@column":"userId;max(id):maxId",
"@group":"userId",
"@having":"(maxId)>=100"](http://apijson.cn:8080/get/{"[]":{"count":10,"Moment":{"@column":"userId%253Bmax(id):maxId","@group":"userId","@having":"(maxId)>=100"}}})
对应 SQL 是`SELECT userId,max(id) AS maxId ... GROUP BY userId HAVING (maxId)>=100`
6 查询 sys 内的 User 表:
["@schema":"sys"](http://apijson.cn:8080/get/{"User":{"@schema":"sys"}})
对应 SQL 是`FROM sys.User`
7 查询 PostgreSQL 数据库的 User 表:
["@database":"POSTGRESQL"](http://apijson.cn:8080/get/{"User":{"@database":"POSTGRESQL","@explain":true}})
8 使用 Druid 连接池查询 User 表:
["@datasource":"DRUID"](http://apijson.cn:8080/get/{"User":{"@datasource":"DRUID"}})
9 将 VARCHAR 字符串字段 get 转为 JSONArray 返回:
["@json":"get"](http://apijson.cn:8080/get/{"Access":{"@json":"get"}})
10 查询当前用户的动态:
["@role":"OWNER"](http://apijson.cn:8080/get/{"[]":{"Moment":{"@role":"OWNER"}}})
11 开启性能分析:
["@explain":true](http://apijson.cn:8080/get/{"[]":{"Moment":{"@explain":true}}})
对应 SQL 是`EXPLAIN`
12 统计最近一周偶数 userId 的数量
["@column":"date;left(date,10):day;sum(if(userId%2=0,1,0))",
"@group":"day",
"@having":"to_days(now())-to_days(\`date\`)<=7",
"@raw":"@column,@having"](http://apijson.cn:8080/get/{"[]":{"Moment":{"@column":"date%3bleft(date,10):day%3bsum(if(userId%252=0,1,0))","@group":"day","@having":"to_days(now())-to_days(\`date\`)<=7","@raw":"@column,@having"}}})
对应 SQL 是``SELECT date, left(date,10) AS day, sum(if(userId%2=0,1,0)) ... GROUP BY day HAVING to_days(now())-to_days(`date`)<=7``
13 把用户的标签设置为空
["@null":"tag"](http://apijson.cn/api/?type=JSON&url=http://apijson.cn:8080/put/User&json={%22id%22:82001,%22@null%22:%22tag%22,%22@explain%22:true})
14 从pictureList 获取第 0 张图片:
["@position":0, // 自定义关键词
"firstPicture()":"getFromArray(pictureList,@position)"](http://apijson.cn:8080/get/{"User":{"id":38710,"@position":0,"firstPicture()":"getFromArray(pictureList,@position)"}})
全局关键词 | 为最外层对象 {} 内的关键词。其中 @database,@schema, @datasource, @role, @explain 基本同对象关键词,见上方说明,区别是全局关键词会每个表对象中没有时自动放入,作为默认值。
1 "tag":"Table",后面的 tag 是非 GET、HEAD 请求中匹配请求的 JSON 结构的标识,一般是要查询的 Table 的名称或该名称对应的数组 Table[] 或 Table:[],由后端 Request 表中指定。
2 "version":1,接口版本,version 不传、为 null 或 <=0 都会使用最高版本,传了其它有效值则会使用最接近它的最低版本,由后端 Request 表中指定。
3 "format":true,格式化返回 Response JSON 的 key,一般是将 TableName 转为 tableName, TableName[] 转为 tableNameList, Table:alias 转为 alias, TableName-key[] 转为 tableNameKeyList 等小驼峰格式。 | 1 查隐私信息:
[{"tag":"Privacy","Privacy":{"id":82001}}](http://apijson.cn/api?url=http%3A%2F%2Fapijson.cn%3A8080%2Fgets&type=JSON&json={%22tag%22:%22Privacy%22,%22Privacy%22:{%22id%22:82001}})
2 使用第 1 版接口查隐私信息:
[{"version":1,"tag":"Privacy","Privacy":{"id":82001}}](http://apijson.cn/api?url=http%3A%2F%2Fapijson.cn%3A8080%2Fgets&type=JSON&json={%22version%22:1,%22tag%22:%22Privacy%22,%22Privacy%22:{%22id%22:82001}})
3 格式化朋友圈接口返回 JSON 中的 key:
[{
"format":true,
"[]":{
"page":0,
"count":3,
"Moment":{},
"User":{
"id@":"/Moment/userId"
},
"Comment[]":{
"count":3,
"Comment":{
"momentId@":"[]/Moment/id"
}
}
}
}](http://apijson.cn:8080/get/{"format":true,"[]":{"page":0,"count":3,"Moment":{},"User":{"id@":"%252FMoment%252FuserId"},"Comment[]":{"count":3,"Comment":{"momentId@":"[]%252FMoment%252Fid"}}}})
From 7645a599b9171019afb35be1e0d120127f67c7ab Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年7月26日 22:28:26 +0800
Subject: [PATCH 16/41] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20compat=20=E5=85=BC?=
=?UTF-8?q?=E5=AE=B9=E5=90=84=E7=A7=8D=20count=20SQL=20=E7=9A=84=E8=AF=B4?=
=?UTF-8?q?=E6=98=8E=EF=BC=8C=E6=84=9F=E8=B0=A2=20GeXin97=20=E5=AE=8C?=
=?UTF-8?q?=E5=96=84=E9=80=9A=E7=94=A8=E6=96=87=E6=A1=A3=E7=9A=84=E8=B4=A1?=
=?UTF-8?q?=E7=8C=AE=20#832?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://github.com/Tencent/APIJSON/pull/832
---
Document.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document.md b/Document.md
index 29543da9..1d57d670 100644
--- a/Document.md
+++ b/Document.md
@@ -420,7 +420,7 @@ DELETE:
删除数据 | base_url/delete/ | {
TableName:{< 减少 或 去除 | "key-":Object,与"key+"相反 | "balance-":100.00,对应SQL是`balance = balance - 100.00`,余额减少100.00,即花费了100元 比较运算 |>, <,>=, <= 比较运算符,用于
1 提供 "id{}":"<=90000" 这种条件范围的简化写法
2 实现子查询相关比较运算
不支持 "key=":Object 和 "key!=":Object 这两种写法,直接用更简单的 "key":Object 和 "key!":Object 替代。 | 1 ["id<=":90000](http://apijson.cn:8080/get/{"[]":{"user":{"id<=":90000}}}),对应 SQL 是`id<=90000`,查询符合id<=90000的一个user数组
2 ["id>@":{
"from":"Comment",
"Comment":{
"@column":"min(userId)"
}
}](http://apijson.cn:8080/get/{"User":{"id>@":{"from":"Comment","Comment":{"@column":"min(userId)"}}}})
WHERE id>(SELECT min(userId) FROM Comment)
逻辑运算 | &, \|, ! 逻辑运算符,对应数据库 SQL 中的 AND, OR, NOT。
横或纵与:同一键值对的值内条件默认 \| 或连接,可以在 key 后加逻辑运算符来具体指定;不同键值对的条件默认 & 与连接,可以用下面说明的对象关键词 @combine 来具体指定。
1 & 可用于 "key&{}":"条件"等
2 \| 可用于 "key\|{}":"条件", "key\|{}":[]等,一般可省略
3 ! 可单独使用,如 "key!":Object,也可像 &,\| 一样配合其他功能符使用
"key!":null 无效,null 值会导致整个键值对被忽略解析,可以用 "key{}":"!=null" 替代,
"key":null 同理,用 "key{}":"=null" 替代。 | 1 ["id&{}":">80000,<=90000"](http://apijson.cn:8080/head/{"user":{"id&{}":">80000,<=90000"}}),对应sql是`id>80000 AND id<=90000`,即id满足id>80000 & id<=90000
2 ["id\|{}":">90000,<=80000"](http://apijson.cn:8080/head/{"user":{"id\|{}":">90000,<=80000"}}),同 "id{}":">90000,<=80000",对应 SQL 是`id>90000 OR id<=80000`,即 id 满足 id>90000 \| id<=80000
3 ["id!{}":[82001,38710]](http://apijson.cn:8080/head/{"User":{"id!{}":[82001,38710]}}),对应 SQL 是`id NOT IN(82001,38710)`,即 id 满足 ! (id=82001 \| id=38710),可过滤黑名单的消息
- 数组关键词,可自定义 | "key":Object,key为 "[]":{} 中 {} 内的关键词,Object 的类型由 key 指定
1 "count":5,查询数量,0 表示最大值,默认值为 10,默认最大值为 100
2 "page":1,查询页码,从 0 开始,默认值为 0,默认最大值为 100,一般和 count 一起用
3 "query":2,查询内容
0-对象,1-总数和分页详情,2-数据、总数和分页详情
总数关键词为 total,分页详情关键词为 info,
它们都和 query 同级,通过引用赋值得到自定义 key:value 键值对,不传则返回默认键值对,例如
"total@":"/[]/total", "info@":"/[]/info"
这里query及total仅为GET类型的请求提供方便,
一般可直接用HEAD类型的请求获取总数
4 compat: true
处理最外层查询字段有特殊处理的情况下"query":2返回查询总数不准确的问题:
如DISTINCT去重、Aggregate 函数等
5 "join":"&/Table0,\"join":{
"&/Table0":{}, // 支持 ON 多个字段关联,
"\ "key0":value0, // 其它ON条件
"key2":value2,
...
"@combine":"...", // 其它ON条件的组合方式
"@column":"...", // 外层 SELECT
"@group":"...", // 外层 GROUP BY
"@having":"..." // 外层 HAVING
}
}
多表连接方式:
"@" - APP JOIN
"\<" - LEFT JOIN
">" - RIGHT JOIN
"&" - INNER JOIN
"\|" - FULL JOIN
"!" - OUTER JOIN
"*" - CROSS JOIN
"^" - SIDE JOIN
"(" - ANTI JOIN
")" - FOREIGN JOIN
其中 @ APP JOIN 为应用层连表,会从已查出的主表里取得所有副表 key@ 关联的主表内的 refKey 作为一个数组 refKeys: [value0, value1...],然后把原来副表 count 次查询 key=$refKey 的 SQL 用 key IN($refKeys) 的方式合并为一条 SQL 来优化性能;
其它 JOIN 都是 SQL JOIN,具体功能和 MySQL,PostgreSQL 等数据库的 JOIN 一一对应
`"join":"`"MainTable":{},`
`"ViceTable":{"key@":"/MainTable/refKey"}`
会对应生成
`MainTable LEFT JOIN ViceTable`
`ON ViceTable.key=MainTable.refKey` AND 其它ON条件
除了 = 等价关联,也支持 ! 不等关联、\> \< \>= \<= 等比较关联和 $ ~ {} 等其它复杂关联方式
6 "otherKey":Object,自定义关键词,名称和以上系统关键词不一样,且原样返回上传的值 | 1 查询User数组,最多5个:
["count":5](http://apijson.cn:8080/get/{"[]":{"count":5,"User":{}}})
对应 SQL 是`LIMIT 5`
2 查询第3页的User数组,每页5个:
["count":5,
"page":3](http://apijson.cn:8080/get/{"[]":{"count":5,"page":3,"User":{}}})
对应 SQL 是`LIMIT 5 OFFSET 15`
3 查询User数组和对应的User总数:
["[]":{
"query":2,
"User":{}
},
"total@":"/[]/total", // 可省略
"info@":"/[]/info" // 可省略](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}},"total@":"%252F[]%252Ftotal","info@":"%252F[]%252Finfo"})
返回的数据中,总数及分页详情结构为:
"total":139, // 总数
"info":{ // 分页详情
"total":139, // 总数
"count":5, // 每页数量
"page":0, // 当前页码
"max":27, // 最大页码
"more":true, // 是否还有更多
"first":true, // 是否为首页
"last":false // 是否为尾页
}
4查询User数组ID唯一情况下的User总数:
["[]":{
"query":2,
"compat":"true",
"User":{"@column":"DISTINCT id"}
},
"total@":"/[]/total", // 可省略
"info@":"/[]/info" // 可省略](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}},"total@":"%252F[]%252Ftotal","info@":"%252F[]%252Finfo"})
返回的数据中,总数及分页详情结构为:
"total":139, // 总数
"info":{ // 分页详情
"total":139, // 总数
"count":5, // 每页数量
"page":0, // 当前页码
"max":27, // 最大页码
"more":true, // 是否还有更多
"first":true, // 是否为首页
"last":false // 是否为尾页
}
5 Moment INNER JOIN User LEFT JOIN Comment:
["[]":{
"join":"&/User/id@,\ "Moment":{
"@group":"id" // 主副表不是一对一,要去除重复数据
},
"User":{
"name~":"t",
"id@":"/Moment/userId"
},
"Comment":{
"momentId@":"/Moment/id"
}
}](http://apijson.cn/api/?type=JSON&url=http://apijson.cn:8080/get&json=%7B%22%5B%5D%22:%7B%22count%22:5,%22join%22:%22%26%2FUser%2Fid@,%3C%2FComment%22,%22Moment%22:%7B%22@column%22:%22id,userId,content%22,%22@group%22:%22id%22%7D,%22User%22:%7B%22name~%22:%22t%22,%22id@%22:%22%2FMoment%2FuserId%22,%22@column%22:%22id,name,head%22%7D,%22Comment%22:%7B%22momentId@%22:%22%2FMoment%2Fid%22,%22@column%22:%22id,momentId,content%22%7D%7D%7D)
6 每一层都加当前用户名:
["User":{},
"[]":{
"name@":"User/name", // 自定义关键词
"Moment":{}
}](http://apijson.cn:8080/get/{"User":{},"[]":{"name@":"User%252Fname","Moment":{}}})
+ 数组关键词,可自定义 | "key":Object,key为 "[]":{} 中 {} 内的关键词,Object 的类型由 key 指定
1 "count":5,查询数量,0 表示最大值,默认值为 10,默认最大值为 100
2 "page":1,查询页码,从 0 开始,默认值为 0,默认最大值为 100,一般和 count 一起用
3 "query":2,查询内容
0-对象,1-总数和分页详情,2-数据、总数和分页详情
总数关键词为 total,分页详情关键词为 info,
它们都和 query 同级,通过引用赋值得到自定义 key:value 键值对,不传则返回默认键值对,例如
"total@":"/[]/total", "info@":"/[]/info"
这里query及total仅为GET类型的请求提供方便,
一般可直接用HEAD类型的请求获取总数
4 "compat": true
处理最外层查询字段有特殊处理的情况下 "query":2 返回查询总数不准确的问题:如DISTINCT去重、Aggregate 函数等
5 "join":"&/Table0,\"join":{
"&/Table0":{}, // 支持 ON 多个字段关联,
"\ "key0":value0, // 其它ON条件
"key2":value2,
...
"@combine":"...", // 其它ON条件的组合方式
"@column":"...", // 外层 SELECT
"@group":"...", // 外层 GROUP BY
"@having":"..." // 外层 HAVING
}
}
多表连接方式:
"@" - APP JOIN
"\<" - LEFT JOIN
">" - RIGHT JOIN
"&" - INNER JOIN
"\|" - FULL JOIN
"!" - OUTER JOIN
"*" - CROSS JOIN
"^" - SIDE JOIN
"(" - ANTI JOIN
")" - FOREIGN JOIN
其中 @ APP JOIN 为应用层连表,会从已查出的主表里取得所有副表 key@ 关联的主表内的 refKey 作为一个数组 refKeys: [value0, value1...],然后把原来副表 count 次查询 key=$refKey 的 SQL 用 key IN($refKeys) 的方式合并为一条 SQL 来优化性能;
其它 JOIN 都是 SQL JOIN,具体功能和 MySQL,PostgreSQL 等数据库的 JOIN 一一对应
`"join":"`"MainTable":{},`
`"ViceTable":{"key@":"/MainTable/refKey"}`
会对应生成
`MainTable LEFT JOIN ViceTable`
`ON ViceTable.key=MainTable.refKey` AND 其它ON条件
除了 = 等价关联,也支持 ! 不等关联、\> \< \>= \<= 等比较关联和 $ ~ {} 等其它复杂关联方式
6 "otherKey":Object,自定义关键词,名称和以上系统关键词不一样,且原样返回上传的值 | 1 查询User数组,最多5个:
["count":5](http://apijson.cn:8080/get/{"[]":{"count":5,"User":{}}})
对应 SQL 是`LIMIT 5`
2 查询第3页的User数组,每页5个:
["count":5,
"page":3](http://apijson.cn:8080/get/{"[]":{"count":5,"page":3,"User":{}}})
对应 SQL 是`LIMIT 5 OFFSET 15`
3 查询User数组和对应的User总数:
["[]":{
"query":2,
"User":{}
},
"total@":"/[]/total", // 可省略
"info@":"/[]/info" // 可省略](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}},"total@":"%252F[]%252Ftotal","info@":"%252F[]%252Finfo"})
返回的数据中,总数及分页详情结构为:
"total":139, // 总数
"info":{ // 分页详情
"total":139, // 总数
"count":5, // 每页数量
"page":0, // 当前页码
"max":27, // 最大页码
"more":true, // 是否还有更多
"first":true, // 是否为首页
"last":false // 是否为尾页
}
4查询User数组ID唯一情况下的User总数:
["[]":{
"query":2,
"compat":"true",
"User":{
"@column":"DISTINCT id"
}
}](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}}})
返回的数据和结构同上
5 Moment INNER JOIN User LEFT JOIN Comment:
["[]":{
"join":"&/User/id@,\ "Moment":{
"@group":"id" // 主副表不是一对一,要去除重复数据
},
"User":{
"name~":"t",
"id@":"/Moment/userId"
},
"Comment":{
"momentId@":"/Moment/id"
}
}](http://apijson.cn/api/?type=JSON&url=http://apijson.cn:8080/get&json=%7B%22%5B%5D%22:%7B%22count%22:5,%22join%22:%22%26%2FUser%2Fid@,%3C%2FComment%22,%22Moment%22:%7B%22@column%22:%22id,userId,content%22,%22@group%22:%22id%22%7D,%22User%22:%7B%22name~%22:%22t%22,%22id@%22:%22%2FMoment%2FuserId%22,%22@column%22:%22id,name,head%22%7D,%22Comment%22:%7B%22momentId@%22:%22%2FMoment%2Fid%22,%22@column%22:%22id,momentId,content%22%7D%7D%7D)
6 每一层都加当前用户名:
["User":{},
"[]":{
"name@":"User/name", // 自定义关键词
"Moment":{}
}](http://apijson.cn:8080/get/{"User":{},"[]":{"name@":"User%252Fname","Moment":{}}})
对象关键词,可自定义 | "@key":Object,@key 为 Table:{} 中 {} 内的关键词,Object 的类型由 @key 指定
1 "@combine":"key0 \| (key1 & (key2 \| !key3))...",条件组合方式,最终按
(其它key条件 AND 连接) AND (key0条件 OR (key1条件 AND (key2条件 OR (NOT key3条件))))
这种方式连接,其中 "其它key" 是指与 @combine 在同一对象,且未被它声明的条件 key,默认都是 & 连接。注意不要缺少或多余任何一个空格。
2 "@column":"column;function(arg)...",返回字段
3 "@order":"column0+,column1-...",排序方式
4 "@group":"column0,column1...",分组方式。如果 @column 里声明了 Table 的 id,则 id 也必须在 @group 中声明;其它情况下必须满足至少一个条件:
1.分组的 key 在 @column 里声明
2.Table 主键在 @group 中声明
5 "@having":"function0(...)?value0;function1(...)?value1;function2(...)?value2..." // OR 连接,或
"@having&":"function0(...)?value0;function1(...)?value1;function2(...)?value2..." // AND 连接,或
"@having":{
"h0":"function0(...)?value0",
"h1":function1(...)?value1",
"h2":function2(...)?value2...",
"@combine":"h0 & (h1 \| !h2)" // 任意组合,非必传
}
SQL 函数条件,一般和 @group 一起用,函数一般在 @column 里声明
6 "@schema":"sys",集合空间(数据库名/模式),非默认的值可通过它来指定,可以在最外层作为全局默认配置
7 "@database":"POSTGRESQL",数据库类型,非默认的值可通过它来指定,可以在最外层作为全局默认配置
8 "@datasource":"DRUID",跨数据源,非默认的值可通过它来指定,可以在最外层作为全局默认配置
9 "@json":"key0,key1...",转为 JSON 格式返回,符合 JSONObject 则转为 {...},符合 JSONArray 则转为 \[...]
10 "@role":"OWNER",来访角色,包括
UNKNOWN,LOGIN,CONTACT,CIRCLE,OWNER,ADMIN,
可以在最外层作为全局默认配置,
可自定义其它角色并重写 Verifier.verify 等相关方法来自定义校验
11 "@explain":true,性能分析,可以在最外层作为全局默认配置
12 "@raw":"key0,key1...",其中 key0, key1 都对应有键值对
"key0":"SQL片段或SQL片段的别名",
"key1":"SQL片段或SQL片段的别名"
自定义原始SQL片段,可扩展嵌套SQL函数等复杂语句,必须是后端已配置的,只有其它功能符都做不到才考虑,谨慎使用,注意防 SQL 注入
13 "@null":"key1,key2...",空值键值对,自动插入 key1:null, key2:null ... 并作为有效键值对执行,作为条件时对应 SQL 是 `WHERE tag IS NULL`,作为值时对应 SQL 是 `SET tag = NULL`
14 "@otherKey":Object,自定义关键词,名称和以上系统关键词不一样,且原样返回上传的值 | 1 搜索 name 或 tag 任何一个字段包含字符 a 的 User 列表:
["name~":"a",
"tag~":"a",
"@combine":"name~ \| tag~"](http://apijson.cn:8080/get/{"User[]":{"count":10,"User":{"@column":"id,name,tag","name~":"a","tag~":"a","@combine":"name~%20%7C%20tag~"}}})
对应SQL是`name REGEXP 'a' OR tag REGEXP 'a'`
2 只查询 id,sex,name 这几列并且请求结果也按照这个顺序:
["@column":"id,sex,name"](http://apijson.cn:8080/get/{"User":{"@column":"id,sex,name","id":38710}})
对应 SQL 是`SELECT id,sex,name`
3 查询按 name 降序、id 默认顺序 排序的 User 数组:
["@order":"name-,id"](http://apijson.cn:8080/get/{"[]":{"count":10,"User":{"@column":"name,id","@order":"name-,id"}}})
对应 SQL 是`ORDER BY name DESC,id`
4 查询按 userId 分组的 Moment 数组:
["@group":"userId,id"](http://apijson.cn:8080/get/{"[]":{"count":10,"Moment":%7B"@column":"userId,id","@group":"userId,id"}}})
对应 SQL 是`GROUP BY userId,id`
5 查询 按 userId 分组、id 最大值>=100 的 Moment 数组:
["@column":"userId;max(id)",
"@group":"userId",
"@having":"max(id)>=100"](http://apijson.cn:8080/get/{"[]":{"count":10,"Moment":{"@column":"userId%253Bmax(id)","@group":"userId","@having":"max(id)>=100"}}})
对应 SQL 是`SELECT userId,max(id) ... GROUP BY userId HAVING max(id)>=100`
还可以指定函数返回名:
["@column":"userId;max(id):maxId",
"@group":"userId",
"@having":"(maxId)>=100"](http://apijson.cn:8080/get/{"[]":{"count":10,"Moment":{"@column":"userId%253Bmax(id):maxId","@group":"userId","@having":"(maxId)>=100"}}})
对应 SQL 是`SELECT userId,max(id) AS maxId ... GROUP BY userId HAVING (maxId)>=100`
6 查询 sys 内的 User 表:
["@schema":"sys"](http://apijson.cn:8080/get/{"User":{"@schema":"sys"}})
对应 SQL 是`FROM sys.User`
7 查询 PostgreSQL 数据库的 User 表:
["@database":"POSTGRESQL"](http://apijson.cn:8080/get/{"User":{"@database":"POSTGRESQL","@explain":true}})
8 使用 Druid 连接池查询 User 表:
["@datasource":"DRUID"](http://apijson.cn:8080/get/{"User":{"@datasource":"DRUID"}})
9 将 VARCHAR 字符串字段 get 转为 JSONArray 返回:
["@json":"get"](http://apijson.cn:8080/get/{"Access":{"@json":"get"}})
10 查询当前用户的动态:
["@role":"OWNER"](http://apijson.cn:8080/get/{"[]":{"Moment":{"@role":"OWNER"}}})
11 开启性能分析:
["@explain":true](http://apijson.cn:8080/get/{"[]":{"Moment":{"@explain":true}}})
对应 SQL 是`EXPLAIN`
12 统计最近一周偶数 userId 的数量
["@column":"date;left(date,10):day;sum(if(userId%2=0,1,0))",
"@group":"day",
"@having":"to_days(now())-to_days(\`date\`)<=7",
"@raw":"@column,@having"](http://apijson.cn:8080/get/{"[]":{"Moment":{"@column":"date%3bleft(date,10):day%3bsum(if(userId%252=0,1,0))","@group":"day","@having":"to_days(now())-to_days(\`date\`)<=7","@raw":"@column,@having"}}})
对应 SQL 是``SELECT date, left(date,10) AS day, sum(if(userId%2=0,1,0)) ... GROUP BY day HAVING to_days(now())-to_days(`date`)<=7``
13 把用户的标签设置为空
["@null":"tag"](http://apijson.cn/api/?type=JSON&url=http://apijson.cn:8080/put/User&json={%22id%22:82001,%22@null%22:%22tag%22,%22@explain%22:true})
14 从pictureList 获取第 0 张图片:
["@position":0, // 自定义关键词
"firstPicture()":"getFromArray(pictureList,@position)"](http://apijson.cn:8080/get/{"User":{"id":38710,"@position":0,"firstPicture()":"getFromArray(pictureList,@position)"}})
全局关键词 | 为最外层对象 {} 内的关键词。其中 @database,@schema, @datasource, @role, @explain 基本同对象关键词,见上方说明,区别是全局关键词会每个表对象中没有时自动放入,作为默认值。
1 "tag":"Table",后面的 tag 是非 GET、HEAD 请求中匹配请求的 JSON 结构的标识,一般是要查询的 Table 的名称或该名称对应的数组 Table[] 或 Table:[],由后端 Request 表中指定。
2 "version":1,接口版本,version 不传、为 null 或 <=0 都会使用最高版本,传了其它有效值则会使用最接近它的最低版本,由后端 Request 表中指定。
3 "format":true,格式化返回 Response JSON 的 key,一般是将 TableName 转为 tableName, TableName[] 转为 tableNameList, Table:alias 转为 alias, TableName-key[] 转为 tableNameKeyList 等小驼峰格式。 | 1 查隐私信息:
[{"tag":"Privacy","Privacy":{"id":82001}}](http://apijson.cn/api?url=http%3A%2F%2Fapijson.cn%3A8080%2Fgets&type=JSON&json={%22tag%22:%22Privacy%22,%22Privacy%22:{%22id%22:82001}})
2 使用第 1 版接口查隐私信息:
[{"version":1,"tag":"Privacy","Privacy":{"id":82001}}](http://apijson.cn/api?url=http%3A%2F%2Fapijson.cn%3A8080%2Fgets&type=JSON&json={%22version%22:1,%22tag%22:%22Privacy%22,%22Privacy%22:{%22id%22:82001}})
3 格式化朋友圈接口返回 JSON 中的 key:
[{
"format":true,
"[]":{
"page":0,
"count":3,
"Moment":{},
"User":{
"id@":"/Moment/userId"
},
"Comment[]":{
"count":3,
"Comment":{
"momentId@":"[]/Moment/id"
}
}
}
}](http://apijson.cn:8080/get/{"format":true,"[]":{"page":0,"count":3,"Moment":{},"User":{"id@":"%252FMoment%252FuserId"},"Comment[]":{"count":3,"Comment":{"momentId@":"[]%252FMoment%252Fid"}}}})
From 35bdfad47496604b410eaf82e0286f42faa4da46 Mon Sep 17 00:00:00 2001
From: aPing <34087052+yunjiao-source@users.noreply.github.com>
Date: 2025年7月29日 20:00:24 +0800
Subject: [PATCH 17/41] Update README.md
---
README.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index c4b0cb8b..bb148d48 100644
--- a/README.md
+++ b/README.md
@@ -743,7 +743,9 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[review_plan](https://gitee.com/PPXcodeTry/review_plan) 复习提醒Web版(Java技术练习项目)
[apijson-nutz](https://github.com/vincent109/apijson-nutz) APIJSON + Nutz 框架 + NutzBoot 的 Demo
-
+
+[apijson-spring-boot](https://gitee.com/yunjiao-source/apijson-spring-boot) Springboot3 for APIJSON
+
感谢热心的作者们的贡献,点 ⭐Star 支持下他们吧~
From 1abe851a19235cbffd97a1b521f49bee6feda6f6 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年7月29日 22:47:51 +0800
Subject: [PATCH 18/41] =?UTF-8?q?=E7=94=9F=E6=80=81=E9=A1=B9=E7=9B=AE?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E=20apijson-spring-boot=EF=BC=8C=E6=84=9F?=
=?UTF-8?q?=E8=B0=A2=20yunjiao-source=20=E7=9A=84=E8=B4=A1=E7=8C=AE=20#834?=
=?UTF-8?q?=EF=BC=9Ahttps://gitee.com/yunjiao-source/apijson-spring-boot?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
创作不易,为热心的作者右上角点亮 ⭐Star 收藏/支持下项目吧 ^_^
https://gitee.com/yunjiao-source/apijson-spring-boot
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index bb148d48..5c2ee155 100644
--- a/README.md
+++ b/README.md
@@ -744,7 +744,7 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[apijson-nutz](https://github.com/vincent109/apijson-nutz) APIJSON + Nutz 框架 + NutzBoot 的 Demo
-[apijson-spring-boot](https://gitee.com/yunjiao-source/apijson-spring-boot) Springboot3 for APIJSON
+[apijson-spring-boot](https://gitee.com/yunjiao-source/apijson-spring-boot) Springboot3 for APIJSON,用 YAML 简化代码配置
感谢热心的作者们的贡献,点 ⭐Star 支持下他们吧~
From d21e4003cdcc05118dbd77149de30b2ff57e3ec0 Mon Sep 17 00:00:00 2001
From: wz11wz
Date: Mon, 4 Aug 2025 11:20:24 +0800
Subject: [PATCH 19/41] =?UTF-8?q?fix:=20=E9=92=88=E5=AF=B9left=20join=20?=
=?UTF-8?q?=E4=BB=A5=E5=8F=8A=20right=20join=20outerConfig=20=E4=B8=8A?=
=?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=20AbstractSQLConfig=20gainWhereStri?=
=?UTF-8?q?ng=E3=80=82value=E6=B2=A1=E6=9C=89=E5=B8=A6=E4=B8=8A=EF=BC=8C?=
=?UTF-8?q?=E4=BF=AE=E5=A4=8Dconfig=20PreparedValueList?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
index f362b35f..71c36741 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
@@ -3756,6 +3756,9 @@ protected String concatJoinWhereString(String whereString) throws Exception {
+ " ( " + outerWhere + " ) "
)
+ " ) ";
+ newPvl.addAll(pvl);
+ newPvl.addAll(outerConfig.getPreparedValueList());
+
changed = true;
break;
From e0f7eeb2ce883d02681cb34e2a7967944814212e Mon Sep 17 00:00:00 2001
From: moxi
Date: Fri, 8 Aug 2025 14:31:20 +0800
Subject: [PATCH 20/41] =?UTF-8?q?fix:=20=E5=A2=9E=E5=8A=A0=20@key=20?=
=?UTF-8?q?=E4=BD=BF=E7=94=A8=E8=AF=B4=E6=98=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Document-English.md | 2 +-
Document.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Document-English.md b/Document-English.md
index 8d1fab8a..e9a013bb 100644
--- a/Document-English.md
+++ b/Document-English.md
@@ -324,7 +324,7 @@ Response:
Fuzzy matching | `"key$":"SQL search expressions"` => `"key$":["SQL search expressions"]`
Any SQL search expressions.Eg.%key%(include key), key%(start with key),%k%e%y%(include k, e, y). % means any characters. | ["name$":"%m%"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name$":"%2525m%2525"}}})
In SQL, it's
`name LIKE '%m%'`,
meaning that get User with ‘m’ in name.
Regular Expression| `"key~":"regular expression"` => `"key~":["regular expression"]`
It can be any regular expressions.Eg. ^[0-9]+$ ,*~ not case sensitive, advanced search is applicable.| ["name~":"^[0-9]+$"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name~":"^[0-9]%252B$"}}})
In SQL, it's
`name REGEXP '^[0-9]+$'`.
Get data in a range| `"key%":"start,end"` => `"key%":["start,end"]`
The data type of start and end can only be either Boolean, Number or String. Eg. "2017-01-01,2019年01月01日" ,["1,90000", "82001,100000"]. It's used for getting data from a specific time range. | ["date%":"2017-10-01,2018年10月01日"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"date%2525":"2017-10-01,2018年10月01日"}}})
In SQL, it's
`date BETWEEN '2017-10-01' AND '2018-10-01'`,
meaning to get User data that registered between 2017年10月01日 and 2018年10月01日.
- Make an alias | `"name:alias"`
this changes name to alias in returning results. It’s applicable to column, tableName, SQL Functions, etc. but only in GET, HEAD requests. | ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}})
In SQL, it's
`toId AS parentId`.
It'll return `parentId` instead of `toId`.
+ Make an alias | `"name:alias"`
this changes name to alias in returning results. It’s applicable to column, tableName, SQL Functions, etc. but only in GET, HEAD requests. | ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}})
In SQL, it's
`toId AS parentId`.
It'll return `parentId` instead of `toId`.
For @key format like "lc_wai6b3vk2:(lc_wai6b3vk)", it means renaming field lc_wai6b3vk2 to lc_wai6b3vk, commonly used for field renaming scenarios. Example:
{
"lc_sinan_ba074fbb": {
"lc_wai6b3vk": "11",
"lc_wai6b3vk2": "22",
"@combine": "lc_wai6b3vk \\| lc_wai6b3vk2",
"@key": "lc_wai6b3vk2:(lc_wai6b3vk)"
}
}
corresponds to SQL `(lc_wai6b3vk = '11' OR lc_wai6b3vk2 = '22')`, but the lc_wai6b3vk2 field will be renamed and displayed as lc_wai6b3vk in the returned result
Add / expand an item | `"key+":Object`
The type of Object is decided by *key*. Types can be Number, String, JSONArray. Froms are 82001,"apijson",["url0","url1"] respectively. It’s only applicable to PUT request.| "praiseUserIdList+":[82001]. In SQL, it's
`json_insert(praiseUserIdList,82001)`.
Add an *id* that praised the Moment.
Delete / decrease an item | `"Key-":Object`
It’s the contrary of "key+" | "balance-":100.00. In SQL, it's
`balance = balance - 100.00`,
meaning there's 100 less in balance.
Operations | &, \|, !
They're used in logic operations. It’s the same as AND, OR, NOT in SQL respectively.
By default, for the same key, it’s ‘\|’ (OR)operation among conditions; for different keys, the default operation among conditions is ‘&’(AND).
| 1 ["id&{}":">80000,<=90000"](http://apijson.cn:8080/head/{"user":{"id&{}":">80000,<=90000"}})
In SQL, it's
`id>80000 AND id<=90000`,
meaning *id* needs to be id>80000 & id<=90000
2 ["id\|{}":">90000,<=80000"](http://apijson.cn:8080/head/{"user":{"id\|{}":">90000,<=80000"}})
It's the same as "id{}":">90000,<=80000".
In SQL, it's
`id>80000 OR id<=90000`,
meaning that *id* needs to be id>90000 \| id<=80000
3 ["id!{}":[82001,38710]](http://apijson.cn:8080/head/{"User":{"id!{}":[82001,38710]}})
In SQL, it's
`id NOT IN(82001,38710)`,
meaning id needs to be ! (id=82001 \| id=38710).
diff --git a/Document.md b/Document.md
index 38adef50..e46883e0 100644
--- a/Document.md
+++ b/Document.md
@@ -415,7 +415,7 @@ DELETE:
删除数据 | base_url/delete/ | {
TableName:{< 模糊搜索 | `"key$":"SQL搜索表达式"` => `"key$":["SQL搜索表达式"]`,任意SQL搜索表达式字符串,如 %key%(包含key), key%(以key开始), %k%e%y%(包含字母k,e,y) 等,%表示任意字符 | ["name$":"%m%"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name$":"%2525m%2525"}}}),对应SQL是`name LIKE '%m%'`,查询name包含"m"的一个User数组
正则匹配 | "key~":"正则表达式" => "key~":["正则表达式"],任意正则表达式字符串,如 ^[0-9]+$ ,*~ 忽略大小写,可用于高级搜索 | ["name~":"^[0-9]+$"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name~":"^[0-9]%252B$"}}}),对应SQL是`name REGEXP '^[0-9]+$'`,查询name中字符全为数字的一个User数组
连续范围 | "key%":"start,end" => "key%":["start,end"],其中 start 和 end 都只能为 Boolean, Number, String 中的一种,如 "2017-01-01,2019年01月01日" ,["1,90000", "82001,100000"] ,可用于连续范围内的筛选 | ["date%":"2017-10-01,2018年10月01日"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"date%2525":"2017-10-01,2018年10月01日"}}}),对应SQL是`date BETWEEN '2017-10-01' AND '2018-10-01'`,查询在2017年10月01日和2018年10月01日期间注册的用户的一个User数组
- 新建别名 | "name:alias",name映射为alias,用alias替代name。可用于 column,Table,SQL函数 等。只用于GET类型、HEAD类型的请求 | ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}}),对应SQL是`toId AS parentId`,将查询的字段toId变为parentId返回
+ 新建别名 | "name:alias",name映射为alias,用alias替代name。可用于 column,Table,SQL函数 等。只用于GET类型、HEAD类型的请求 | ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}}),对应SQL是`toId AS parentId`,将查询的字段toId变为parentId返回
对于@key格式,如 "lc_wai6b3vk2:(lc_wai6b3vk)",表示将字段 lc_wai6b3vk2 重命名为 lc_wai6b3vk,常用于字段重命名场景。例如:
{
"lc_sinan_ba074fbb": {
"lc_wai6b3vk": "11",
"lc_wai6b3vk2": "22",
"@combine": "lc_wai6b3vk \\| lc_wai6b3vk2",
"@key": "lc_wai6b3vk2:(lc_wai6b3vk)"
}
}
对应SQL是`(lc_wai6b3vk = '11' OR lc_wai6b3vk2 = '22')`,但返回结果中 lc_wai6b3vk2 字段会被重命名显示为 lc_wai6b3vk
增加 或 扩展 | "key+":Object,Object的类型由key指定,且类型为Number,String,JSONArray中的一种。如 82001,"apijson",["url0","url1"] 等。只用于PUT请求 | "praiseUserIdList+":[82001],对应SQL是`json_insert(praiseUserIdList,82001)`,添加一个点赞用户id,即这个用户点了赞
减少 或 去除 | "key-":Object,与"key+"相反 | "balance-":100.00,对应SQL是`balance = balance - 100.00`,余额减少100.00,即花费了100元
比较运算 |>, <,>=, <= 比较运算符,用于
1 提供 "id{}":"<=90000" 这种条件范围的简化写法
2 实现子查询相关比较运算
不支持 "key=":Object 和 "key!=":Object 这两种写法,直接用更简单的 "key":Object 和 "key!":Object 替代。 | 1 ["id<=":90000](http://apijson.cn:8080/get/{"[]":{"user":{"id<=":90000}}}),对应sql是`id<=90000`,查询符合id<=90000的一个user数组
2 ["id>@":{
"from":"Comment",
"Comment":{
"@column":"min(userId)"
}
}](http://apijson.cn:8080/get/{"User":{"id>@":{"from":"Comment","Comment":{"@column":"min(userId)"}}}})
WHERE id>(SELECT min(userId) FROM Comment)
From 5ea9139a428022490658fa0cf607b35e22a97497 Mon Sep 17 00:00:00 2001
From: TommyLemon
Date: Sat, 9 Aug 2025 01:35:29 +0800
Subject: [PATCH 21/41] =?UTF-8?q?=E5=BC=95=E7=94=A8=E8=B5=8B=E5=80=BC?=
=?UTF-8?q?=EF=BC=9A=E6=96=B0=E5=A2=9E=E6=94=AF=E6=8C=81=20User-id[]/2=20?=
=?UTF-8?q?=E4=BB=8E=E6=95=B0=E7=BB=84=20User-id[]=20=E4=B8=AD=20get(2)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
APIJSONORM/src/main/java/apijson/JSON.java | 14 ++++
.../main/java/apijson/orm/AbstractParser.java | 68 +++++++------------
2 files changed, 39 insertions(+), 43 deletions(-)
diff --git a/APIJSONORM/src/main/java/apijson/JSON.java b/APIJSONORM/src/main/java/apijson/JSON.java
index 61557985..0a14e042 100755
--- a/APIJSONORM/src/main/java/apijson/JSON.java
+++ b/APIJSONORM/src/main/java/apijson/JSON.java
@@ -674,4 +674,18 @@ public static String getString(Map map, String key) {
return value.toString();
}
+
+ public static Object getFromObjOrArr(Object parent, String k) {
+ if (parent instanceof Map, ?>) {
+ return ((Map) parent).get(k);
+ }
+
+ if (parent instanceof List>) {
+ int j = Integer.valueOf(k);
+ return ((List>) parent).get(j);
+ }
+
+ return null;
+ }
+
}
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
index 43d4c316..cd0b2c7b 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
@@ -39,7 +39,7 @@
public abstract class AbstractParser, L extends List>
implements Parser {
protected static final String TAG = "AbstractParser";
-
+
/**
* JSON 对象、数组对应的数据源、版本、角色、method等
*/
@@ -706,7 +706,7 @@ public M parseCorrectRequest(RequestMethod method, String tag, int version, Stri
return batchVerify(method, tag, version, name, request, maxUpdateCount, creator);
}
-
+
/**自动根据 tag 是否为 TableKey 及是否被包含在 object 内来决定是否包装一层,改为 { tag: object, "tag": tag }
* @param object
* @param tag
@@ -1902,24 +1902,32 @@ else if (join != null){
* @param pathKeys
* @return
*/
- public static V getValue(Map parent, String[] pathKeys) {
- if (parent == null || pathKeys == null || pathKeys.length <= 0) { + public static V getValue(Object parent, String[] pathKeys) {
+ int len = parent == null || pathKeys == null ? 0 : pathKeys.length;
+ if (len <= 0) { Log.w(TAG, "getChild parent == null || pathKeys == null || pathKeys.length <= 0>> return parent;");
return (V) parent;
}
- //逐层到达child的直接容器JSONObject parent
- int last = pathKeys.length - 1;
- for (int i = 0; i < last; i++) {//一步一步到达指定位置 - if (parent == null) {//不存在或路径错误(中间的key对应value不是JSONObject) + // 逐层到达child的直接容器JSONObject parent + Object v = parent; + for (int i = 0; i < len; i++) { // 一步一步到达指定位置 + if (v == null) { // 不存在或路径错误(中间的key对应value不是JSONObject) break; } String k = getDecodedKey(pathKeys[i]); - parent = JSON.get(parent, k); + try { + v = getFromObjOrArr(v, k); + } catch (Throwable e) { + if (IS_PRINT_BIG_LOG) { + e.printStackTrace(); + } + v = null; + } } - return parent == null ? null : (V) parent.get(getDecodedKey(pathKeys[last])); + return (V) v; } @@ -2025,13 +2033,13 @@ public Object getValueByPath(String valuePath) { } //取出key被valuePath包含的result,再从里面获取key对应的value - Map parent = null;
+ Object parent = null;
String[] keys = null;
for (Entry entry : queryResultMap.entrySet()){
String path = entry.getKey();
if (valuePath.startsWith(path + "/")) {
try {
- parent = (M) entry.getValue();
+ parent = entry.getValue();
} catch (Exception e) {
Log.e(TAG, "getValueByPath try { parent = (Map) queryResultMap.get(path); } catch { "
+ "\n parent not instanceof Map!");
@@ -2044,39 +2052,13 @@ public Object getValueByPath(String valuePath) {
}
}
- //逐层到达targetKey的直接容器JSONObject parent
- int last = keys == null ? -1 : keys.length - 1;
- if (last>= 1) {
- for (int i = 0; i < last; i++) {//一步一步到达指定位置parentPath - if (parent == null) {//不存在或路径错误(中间的key对应value不是JSONObject) - break; - } - - String k = getDecodedKey(keys[i]); - Object p = parent.get(k); - parent = p instanceof Map, ?> ? (Map) p : null;
- }
- }
-
- if (parent != null) {
- Log.i(TAG, "getValueByPath>> get from queryResultMap>> return parent.get(keys[keys.length - 1]);");
- target = last < 0 ? parent : parent.get(getDecodedKey(keys[last])); //值为null应该报错NotExistExeption,一般都是id关联,不可为null,否则可能绕过安全机制 - if (target != null) { - Log.i(TAG, "getValueByPath>> getValue>> return target = " + target);
- return target;
- }
+ target = getValue(parent, keys); // 逐层到达targetKey的直接容器JSONObject parent
+ if (target == null) { //从requestObject中取值
+ target = getValue(requestObject, StringUtil.splitPath(valuePath));
}
-
- //从requestObject中取值
- target = getValue(requestObject, StringUtil.splitPath(valuePath));
- if (target != null) {
- Log.i(TAG, "getValueByPath>> getValue>> return target = " + target);
- return target;
- }
-
- Log.i(TAG, "getValueByPath return null;");
- return null;
+ Log.i(TAG, "getValueByPath>> getValue>> return target = " + target);
+ return target;
}
/**解码 引用赋值 路径中的 key,支持把 URL encode 后的值,转为 decode 后的原始值,例如 %2Fuser%2Flist -> /user/list ; %7B%7D -> []
From dbe28f43e4c640ca114f4a663c612adcf2e474a6 Mon Sep 17 00:00:00 2001
From: TommyLemon
Date: Sat, 9 Aug 2025 01:49:38 +0800
Subject: [PATCH 22/41] =?UTF-8?q?=E5=BC=95=E7=94=A8=E8=B5=8B=E5=80=BC?=
=?UTF-8?q?=EF=BC=9A=E8=A7=A3=E5=86=B3=E4=BB=8E=E6=95=B0=E7=BB=84=E5=A4=96?=
=?UTF-8?q?=E9=83=A8=E5=BC=95=E7=94=A8=E8=AF=A5=E6=95=B0=E7=BB=84=E5=86=85?=
=?UTF-8?q?=E5=80=BC=E5=8F=AA=E8=83=BD=E6=8B=BF=E5=88=B0=E7=AC=AC=200=20?=
=?UTF-8?q?=E4=B8=AA(=E4=B8=94=E8=B7=AF=E5=BE=84=E4=B9=9F=E4=B8=8D?=
=?UTF-8?q?=E5=8F=8B=E5=A5=BD)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/java/apijson/orm/AbstractObjectParser.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java
index c546ae24..4d56499a 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java
@@ -1171,7 +1171,9 @@ else if (isArrayMainTable && position> 0) { // 数组主表使用专门的缓
// APP JOIN 副表时副表返回了这个字段 rawList = (List) result.remove(AbstractSQLExecutor.KEY_RAW_LIST);
String arrayPath = parentPath.substring(0, parentPath.lastIndexOf("[]") + 2);
- if (isSimpleArray == false) {
+ if (isSimpleArray) {
+ parser.putQueryResult(arrayPath, rawList); // 从数组外部引用该数组内值需要
+ } else {
long startTime = System.currentTimeMillis();
for (int i = 1; i < rawList.size(); i++) { // 从 1 开始,0 已经处理过 @@ -1196,7 +1198,7 @@ else if (isArrayMainTable && position> 0) { // 数组主表使用专门的缓
if (isSubquery == false && result != null) {
parser.putQueryResult(path, result); // 解决获取关联数据时requestObject里不存在需要的关联数据
- if (isSimpleArray && rawList != null) {
+ if (isSimpleArray) { // FIXME 改为从缓存获取,而不是 result 查
result.put(AbstractSQLExecutor.KEY_RAW_LIST, rawList);
}
}
From d61ecba9663dc28905e50bb5cc6bfaf167c5fa36 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: Sat, 9 Aug 2025 02:25:52 +0800
Subject: [PATCH 23/41] =?UTF-8?q?=E6=84=9F=E8=B0=A2=20moxixi527=20?=
=?UTF-8?q?=E8=B4=A1=E7=8C=AE=20#836=20=EF=BC=9A=E6=96=B0=E5=A2=9E=20?=
=?UTF-8?q?=E5=87=BD=E6=95=B0=E8=B0=83=E7=94=A8=E6=98=A0=E5=B0=84=20"@key"?=
=?UTF-8?q?:=20"fun:avg(id);keyA:(keyB)"=20=E7=9A=84=E5=8A=9F=E8=83=BD?=
=?UTF-8?q?=E7=AC=A6=E9=80=9A=E7=94=A8=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://github.com/Tencent/APIJSON/pull/836
---
Document.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Document.md b/Document.md
index e46883e0..49bd86a7 100644
--- a/Document.md
+++ b/Document.md
@@ -415,7 +415,7 @@ DELETE:
删除数据 | base_url/delete/ | {
TableName:{< 模糊搜索 | `"key$":"SQL搜索表达式"` => `"key$":["SQL搜索表达式"]`,任意SQL搜索表达式字符串,如 %key%(包含key), key%(以key开始), %k%e%y%(包含字母k,e,y) 等,%表示任意字符 | ["name$":"%m%"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name$":"%2525m%2525"}}}),对应SQL是`name LIKE '%m%'`,查询name包含"m"的一个User数组
正则匹配 | "key~":"正则表达式" => "key~":["正则表达式"],任意正则表达式字符串,如 ^[0-9]+$ ,*~ 忽略大小写,可用于高级搜索 | ["name~":"^[0-9]+$"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name~":"^[0-9]%252B$"}}}),对应SQL是`name REGEXP '^[0-9]+$'`,查询name中字符全为数字的一个User数组
连续范围 | "key%":"start,end" => "key%":["start,end"],其中 start 和 end 都只能为 Boolean, Number, String 中的一种,如 "2017-01-01,2019年01月01日" ,["1,90000", "82001,100000"] ,可用于连续范围内的筛选 | ["date%":"2017-10-01,2018年10月01日"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"date%2525":"2017-10-01,2018年10月01日"}}}),对应SQL是`date BETWEEN '2017-10-01' AND '2018-10-01'`,查询在2017年10月01日和2018年10月01日期间注册的用户的一个User数组
- 新建别名 | "name:alias",name映射为alias,用alias替代name。可用于 column,Table,SQL函数 等。只用于GET类型、HEAD类型的请求 | ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}}),对应SQL是`toId AS parentId`,将查询的字段toId变为parentId返回
对于@key格式,如 "lc_wai6b3vk2:(lc_wai6b3vk)",表示将字段 lc_wai6b3vk2 重命名为 lc_wai6b3vk,常用于字段重命名场景。例如:
{
"lc_sinan_ba074fbb": {
"lc_wai6b3vk": "11",
"lc_wai6b3vk2": "22",
"@combine": "lc_wai6b3vk \\| lc_wai6b3vk2",
"@key": "lc_wai6b3vk2:(lc_wai6b3vk)"
}
}
对应SQL是`(lc_wai6b3vk = '11' OR lc_wai6b3vk2 = '22')`,但返回结果中 lc_wai6b3vk2 字段会被重命名显示为 lc_wai6b3vk
+ 新建别名 | 1 "name:alias",name 映射为 alias,用 alias 替代 name。可用于 column,Table,SQL 函数 等。只用于 GET 类型、HEAD 类型的请求
2 函数调用映射
"@key": "fun:avg(id);keyA:(keyB)",
"fun>": 1,
"keyA": 1
其中 fun:fun(arg) 把 SQL 函数调用 fun(arg) 作为左侧表达式替代 fun,即 fun(arg)> 1;
keyA:(keyB) 表示将字段 keyA 重命名为 keyB,即实际 SQL 中为 keyB = 1,常用于重命名冲突的多条件同名字段。 | 1 ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}}),对应 SQL 是 `toId AS parentId`,将查询的字段 toId 变为 parentId 返回
2 ["@key": "len:length(content);mid:(momentId)",
"len<=": 10,
"mid": 12,
"momentId": 15,
"@combine": "(len<= \\| mid) & momentId"](http://apijson.cn/api?type=JSON&json={%22Comment%22:{%22@key%22:%22len%3Alength(content)%3Bmid%3A(momentId)%22,%22len%3C=%22:10,%22mid%22:12,%22momentId%22:15,%22@combine%22:%22(len%3C%3D%20%7C%20mid)%20%26%20momentId%22}})
对应 SQL 是 `(length(content) <= 10 OR momentId = 12) AND momentId = 15` 增加 或 扩展 | "key+":Object,Object的类型由key指定,且类型为Number,String,JSONArray中的一种。如 82001,"apijson",["url0","url1"] 等。只用于PUT请求 | "praiseUserIdList+":[82001],对应SQL是`json_insert(praiseUserIdList,82001)`,添加一个点赞用户id,即这个用户点了赞 减少 或 去除 | "key-":Object,与"key+"相反 | "balance-":100.00,对应SQL是`balance = balance - 100.00`,余额减少100.00,即花费了100元 比较运算 |>, <,>=, <= 比较运算符,用于
1 提供 "id{}":"<=90000" 这种条件范围的简化写法
2 实现子查询相关比较运算
不支持 "key=":Object 和 "key!=":Object 这两种写法,直接用更简单的 "key":Object 和 "key!":Object 替代。 | 1 ["id<=":90000](http://apijson.cn:8080/get/{"[]":{"user":{"id<=":90000}}}),对应sql是`id<=90000`,查询符合id<=90000的一个user数组
2 ["id>@":{
"from":"Comment",
"Comment":{
"@column":"min(userId)"
}
}](http://apijson.cn:8080/get/{"User":{"id>@":{"from":"Comment","Comment":{"@column":"min(userId)"}}}})
WHERE id>(SELECT min(userId) FROM Comment)
From 5310e83d01fc423d9f23965751c9e9b2b5480aba Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年8月10日 02:01:37 +0800
Subject: [PATCH 24/41] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 5c2ee155..7c9af160 100644
--- a/README.md
+++ b/README.md
@@ -704,7 +704,7 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[apijson-examples](https://gitee.com/drone/apijson-examples) APIJSON 的前端、业务后端、管理后端 Demo
-[apijson-ruoyi](https://gitee.com/yxiedd/apijson-ruoyi) APIJSON 和 RuoYi 框架整合,实现零代码生成页面模板接口,在线维护 APIJSON 数据库配置等
+[apijson-ruoyi](https://github.com/daodol/apijson-ruoyi) APIJSON 和 RuoYi 框架整合,实现零代码生成页面模板接口,在线维护 APIJSON 数据库配置等
[light4j](https://github.com/xlongwei/light4j) 整合 APIJSON 和微服务框架 light-4j 的 Demo,同时接入了 Redis
From d9c502299b45d91f3e83007cfc24f2df195c80cb Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年8月10日 02:28:54 +0800
Subject: [PATCH 25/41] Update CONTRIBUTING.md
---
CONTRIBUTING.md | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f9656e28..cb627154 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -25,7 +25,7 @@
- [403f](https://github.com/403f)
- [gujiachun](https://github.com/gujiachun)
- [gdjs2](https://github.com/gdjs2)(University of California, Riverside)
-- [Rkyzzy](https://github.com/Rkyzzy)(SUSTech, University of California, Berkeley)
+- [Rkyzzy](https://github.com/Rkyzzy)(理想汽车工程师, SUSTech, University of California, Berkeley)
- [kxlv2000](https://github.com/kxlv2000)(SUSTech)
- [caohao-go](https://github.com/caohao-go)(腾讯工程师,曾在华为、恒生担任C/C++开发工程师,在wps担任项目经理,在360担任技术专家)
- [Wscats](https://github.com/Wscats)(腾讯工程师、腾讯 AlloyTeam 成员、Tencent Creation Camp 成员、知名技术博主)
@@ -36,7 +36,7 @@
- [andream7](https://github.com/andream7)(微软工程师,还开源了 apijson-db2)
- [qiujunlin](https://github.com/qiujunlin)(字节跳动工程师,还开源了 APIJSONDemo)
- [HANXU2018](https://github.com/HANXU2018)(网易工程师,还开源了 APIJSON-DOC)
-- [hclown9804](https://github.com/hclown9804)
+- [hclown9804](https://github.com/hclown9804)(Datawhale)
- [chenyanlann](https://github.com/chenyanlann)(还开源了 APIJSONDemo_ClickHouse)
- [haolingzhang1](https://github.com/haolingzhang1)(腾讯工程师,还开源了 APIJson--demo)
- [jerrylususu](https://github.com/jerrylususu)(还开源了 apijson_todo_demo 和 apijson_role_extend)
@@ -57,7 +57,7 @@
- [aninZz](https://github.com/aninZz)
- [leomiaomiao](https://github.com/leomiaomiao)
- [YqxLzx](https://github.com/YqxLzx)
-- [hiteshbedre](https://github.com/hiteshbedre)
+- [hiteshbedre](https://github.com/hiteshbedre)(privado.ai 印裔工程师)
- [wahowaho](https://github.com/wahowaho)
- [jarrodquan](https://github.com/jarrodquan)
- [gemufeng](https://github.com/gemufeng)(上海麦市工程师)
@@ -71,6 +71,10 @@
- [calmcc](https://github.com/calmcc)
- [lindaifeng](https://github.com/lindaifeng)
- [DenineLu](https://github.com/DenineLu)(小红书工程师)
+- [wz11wz](https://github.com/wz11wz)
+- [GeXin97](https://github.com/GeXin97)
+- [yunjiao-source](https://github.com/yunjiao-source)(还开源了 [apijson-spring-boot](https://gitee.com/yunjiao-source/apijson-spring-boot))
+- [moxixi527](https://github.com/moxixi527)(热门技术博主)
#### 其中特别致谢:
cloudAndMonkey 提交的 11 个 Commits, 对 APIJSON 做出了 1,496 增加和 845 处删减(截止 2022年12月15日 日);
From e5c62c1959ae0b8c5915c2913d3bef6d09039ebe Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年8月10日 02:35:34 +0800
Subject: [PATCH 26/41] Update CONTRIBUTING.md
---
CONTRIBUTING.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index cb627154..f9fab294 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -33,7 +33,7 @@
- [JieJo](https://github.com/JieJo)
- [yeyuezhishou](https://github.com/yeyuezhishou)(圆通工程师)
- [kenlig](https://github.com/kenlig)(还开源了 apijsondocs)
-- [andream7](https://github.com/andream7)(微软工程师,还开源了 apijson-db2)
+- [andream7](https://github.com/andream7)(字节跳动、微软 工程师,还开源了 apijson-db2)
- [qiujunlin](https://github.com/qiujunlin)(字节跳动工程师,还开源了 APIJSONDemo)
- [HANXU2018](https://github.com/HANXU2018)(网易工程师,还开源了 APIJSON-DOC)
- [hclown9804](https://github.com/hclown9804)(Datawhale)
From 31e8d9316674a4c79d5bd849afbc874c9c69ec11 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年8月10日 02:38:42 +0800
Subject: [PATCH 27/41] =?UTF-8?q?=E7=94=9F=E6=80=81=E9=A1=B9=E7=9B=AE?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E=20CVAuto=20-=20=F0=9F=91=81=20=E9=9B=B6?=
=?UTF-8?q?=E4=BB=A3=E7=A0=81=E9=9B=B6=E6=A0=87=E6=B3=A8=20CV=20AI=20?=
=?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=8C=96=E6=B5=8B=E8=AF=95=E5=B9=B3=E5=8F=B0?=
=?UTF-8?q?=EF=BC=9Ahttps://github.com/TommyLemon/CVAuto?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
创作不易、坚持更难,右上角点亮 ⭐ Star 收藏/支持下本项目吧,谢谢 ^_^
---
README.md | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 7c9af160..99d0f727 100644
--- a/README.md
+++ b/README.md
@@ -652,13 +652,15 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[apijson-cassandra](https://github.com/APIJSON/apijson-cassandra) APIJSON 的 Cassandra NoSQL 数据库插件
-[APIAuto](https://github.com/TommyLemon/APIAuto) 敏捷开发最强大易用的接口工具,机器学习零代码测试、生成代码与静态检查、生成文档与光标悬浮注释
+[APIAuto](https://github.com/TommyLemon/APIAuto) ☔ 敏捷开发最强大易用的接口工具,零代码测试与 AI 问答、生成代码与静态检查、生成文档与光标悬浮注释,腾讯、SHEIN、传音 等使用
+
+[CVAuto](https://github.com/TommyLemon/CVAuto) 👁 零代码零标注 CV AI 自动化测试平台 🚀 免除大量人工画框和打标签等,直接快速测试 CV 计算机视觉 AI 图像识别算法
[UnitAuto](https://github.com/TommyLemon/UnitAuto) 最先进、最省事、ROI 最高的单元测试,机器学习 零代码、全方位、自动化 测试 方法/函数,用户包含腾讯、快手、某 500 强巨头等
-[SQLAuto](https://github.com/TommyLemon/SQLAuto) 智能零代码自动化测试 SQL 语句执行结果的数据库工具,一键批量生成参数组合、快速构造大量测试数据
+[SQLAuto](https://github.com/TommyLemon/SQLAuto) 智能零代码自动化测试 SQL 数据库工具,任意增删改查、任意 SQL 模板变量、一键批量生成参数组合、快速构造大量测试数据
-[UIGO](https://github.com/TommyLemon/UIGO) 📱 零代码快准稳 UI 智能录制回放平台 🚀 自动兼容任意宽高比分辨率屏幕、自动精准等待网络请求,录制回放快、准、稳!
+[UIGO](https://github.com/TommyLemon/UIGO) 📱 零代码快准稳 UI 智能录制回放平台 🚀 3 像素内自动精准定位,2 毫秒内自动精准等待,用户包含腾讯,微信团队邀请分享
[apijson-doc](https://github.com/vincentCheng/apijson-doc) APIJSON 官方文档,提供排版清晰、搜索方便的文档内容展示,包括设计规范、图文教程等
From a3bf644bf7fce9436464704d5f47aaa71f0dc4b2 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年8月28日 00:03:03 +0800
Subject: [PATCH 28/41] =?UTF-8?q?=E6=8E=A8=E8=8D=90=E6=96=87=E7=AB=A0?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E=20springboot=E6=95=B4=E5=90=88APIJSON?=
=?UTF-8?q?=E2=80=94=E2=80=94=E9=9B=B6=E4=BB=A3=E7=A0=81=E4=B8=87=E8=83=BD?=
=?UTF-8?q?=E9=80=9A=E7=94=A8=20API=EF=BC=88=E9=99=84=E6=BA=90=E7=A0=81?=
=?UTF-8?q?=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
感谢 程序员码龙 的热心贡献,点赞、收藏、转发 支持下文章作者吧 ^_^
https://blog.csdn.net/longzhutengyue/article/details/150579233
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index 99d0f727..4efda750 100644
--- a/README.md
+++ b/README.md
@@ -629,6 +629,8 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[APIJSON项目实战教程:零代码实现高效JSON接口开发](https://blog.csdn.net/gitblog_00682/article/details/148375065)
+[springboot整合APIJSON——零代码万能通用 API(附源码)](https://blog.csdn.net/longzhutengyue/article/details/150579233)
+
### 生态项目
[APIJSON-Demo](https://github.com/APIJSON/APIJSON-Demo) APIJSON 各种语言、各种框架 的 使用示例项目、上手文档、测试数据 SQL 文件 等
From edb0e6e83962edf883f42cdadc45b2b7d91b889d Mon Sep 17 00:00:00 2001
From: TommyLemon
Date: Wed, 3 Sep 2025 00:32:27 +0800
Subject: [PATCH 29/41] =?UTF-8?q?=E9=9D=9E=E5=BC=80=E6=94=BE=E8=AF=B7?=
=?UTF-8?q?=E6=B1=82=E4=B8=8D=E5=85=81=E8=AE=B8=E4=BC=A0=20@combine=20?=
=?UTF-8?q?=E5=92=8C=20@key?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/apijson/orm/AbstractVerifier.java | 31 +++++++++++++------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
index b10828ee..44b2d7f1 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
@@ -6,6 +6,8 @@
package apijson.orm;
import static apijson.JSON.*;
+import static apijson.JSONMap.KEY_COMBINE;
+import static apijson.JSONMap.KEY_KEY;
import static apijson.RequestMethod.DELETE;
import static apijson.RequestMethod.GET;
import static apijson.RequestMethod.GETS;
@@ -219,7 +221,7 @@ public static HashMap getAccessMap(MethodAccess access)
@Override
public String getVisitorIdKey(SQLConfig config) {
- return config.getUserIdKey();
+ return config == null ? getUserIdKey(null, null, null, null) : config.getUserIdKey();
}
@Override
@@ -346,21 +348,23 @@ public void verifyAllowRole(SQLConfig config, String table, RequestMeth
* @throws Exception
* @see {@link JSONMap#KEY_ROLE}
*/
- public void verifyUseRole(SQLConfig config, String table, RequestMethod method, String role) throws Exception {
+ public void verifyUseRole(@NotNull SQLConfig config, String table, RequestMethod method, String role) throws Exception {
Log.d(TAG, "verifyUseRole table = " + table + "; method = " + method + "; role = " + role);
+ Objects.requireNonNull(config);
//验证角色,假定真实强制匹配<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - String visitorIdKey = getVisitorIdKey(config); if (table == null) { - table = config == null ? null : config.getTable(); + table = config.getTable(); } if (method == null) { - method = config == null ? GET : config.getMethod(); + method = config.getMethod(); } if (role == null) { - role = config == null ? UNKNOWN : config.getRole(); + role = config.getRole(); } + String visitorIdKey = getVisitorIdKey(config); + Object requestId; switch (role) { case LOGIN://verifyRole通过就行 @@ -1087,14 +1091,23 @@ public static , L extends List> M parse
// 判断不允许传的key<<<<<<<<<<<<<<<<<<<<<<<<< for (String rk : rkset) { + if (rk == null) { // 无效的key + real.remove(rk); + continue; + } + if (refuseSet.contains(rk)) { // 不允许的字段 throw new IllegalArgumentException(method + "请求," + name + " 里面不允许传 " + rk + " 等" + StringUtil.get(refuseSet) + "内的任何字段!"); } - if (rk == null) { // 无效的key - real.remove(rk); - continue; + if (KEY_COMBINE.equals(rk)) { + throw new UnsupportedOperationException(method + " 请求," + rk + " 不合法!" + + "非开放请求不允许传 " + KEY_COMBINE + ":value !"); + } + if (KEY_KEY.equals(rk)) { + throw new UnsupportedOperationException(method + " 请求," + rk + " 不合法!" + + "非开放请求不允许传 " + KEY_KEY + ":value !"); } Object rv = real.get(rk); From 5139e81a8385c12d7e68bdc3c3c3ec03a5b4fc3d Mon Sep 17 00:00:00 2001 From: TommyLemon <1184482681@qq.com>
Date: Wed, 3 Sep 2025 00:36:31 +0800
Subject: [PATCH 30/41] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=94=AF=E6=8C=81?=
=?UTF-8?q?=E5=88=86=E5=BA=93=E5=88=86=E8=A1=A8=E4=B8=AD=E9=97=B4=E4=BB=B6?=
=?UTF-8?q?=20ShardingSphere=20=E7=9A=84=E8=AF=B4=E6=98=8E=EF=BC=9Ahttps:/?=
=?UTF-8?q?/github.com/Tencent/APIJSON=3Ftab=3Dreadme-ov-file#--apijson?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 4efda750..f727c773 100644
--- a/README.md
+++ b/README.md
@@ -66,6 +66,7 @@ This source code is licensed under the Apache License Version 2.0
+
From 0d235f3ba41de331d8f33889c7a29a0c62753378 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=97=A0=E7=A5=9EV?=
<72117341+wu-sv@users.noreply.github.com>
Date: 2025年9月16日 09:24:12 +0800
Subject: [PATCH 31/41] =?UTF-8?q?=E4=BF=AE=E5=A4=8DgetConnectionKey?=
=?UTF-8?q?=E6=96=B9=E6=B3=95=E8=B0=83=E7=94=A8=E5=8F=82=E6=95=B0=E5=90=8D?=
=?UTF-8?q?=E7=A7=B0=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://gitee.com/Tencent/APIJSON/pulls/10
---
APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
index 4d6d28c0..797ac3de 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
@@ -1315,7 +1315,7 @@ public Connection getConnection(@NotNull SQLConfig config) throws Excep
}
public String getConnectionKey(@NotNull SQLConfig config) {
- return getConnectionKey(config.getNamespace(), config.getCatalog(), config.getDatasource(), config.getDatabase());
+ return getConnectionKey(config.getDatabase(), config.getDatasource(), config.getNamespace(), config.getCatalog());
}
public String getConnectionKey(String database, String datasource, String namespace, String catalog) {
return database + "-" + datasource + "-" + namespace + "-" + catalog;
@@ -1541,3 +1541,4 @@ public int executeUpdate(@NotNull SQLConfig config, String sql) throws
}
+
From 0a7f858c0f6304ee2f8b0bbdf55fdf6445622910 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年9月28日 23:19:10 +0800
Subject: [PATCH 32/41] =?UTF-8?q?=E5=B7=A5=E7=A8=8B=E8=BD=BB=E9=87=8F?=
=?UTF-8?q?=E5=B0=8F=E5=B7=A7=20(=E6=97=A0=E7=AC=AC=E4=B8=89=E6=96=B9?=
=?UTF-8?q?=E4=BE=9D=E8=B5=96=EF=BC=8CJar=20=E4=BB=85=20263KB=EF=BC=8CJava?=
=?UTF-8?q?=20=E6=96=87=E4=BB=B6=E4=BB=85=2068=20=E4=B8=AA=E5=85=B1=201486?=
=?UTF-8?q?4=20=E8=A1=8C=E4=BB=A3=E7=A0=81=EF=BC=8C=E4=BE=8B=E5=A6=82=20AP?=
=?UTF-8?q?IJSONORM=208.1.0)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://github.com/Tencent/APIJSON?tab=readme-ov-file#%E4%B8%BA%E4%BB%80%E4%B9%88%E9%80%89%E6%8B%A9-apijson
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index f727c773..ddd56c25 100644
--- a/README.md
+++ b/README.md
@@ -192,7 +192,7 @@ https://github.com/Tencent/APIJSON/wiki
* **解决十大痛点** (可帮前后端开发大幅提振开发效率、强力杜绝联调扯皮、巧妙规避文档缺陷、非常节省流量带宽)
* **开发提速很大** (CRUD 零代码热更新全自动,APIJSONBoot 对比 SSM、SSH 等保守估计可提速 20 倍以上)
* **腾讯官方开源** (使用 GitHub、Gitee、工蜂 等平台的官方账号开源,微信公众号、腾讯云+社区 等官方公告)
-* **社区影响力大** (GitHub 17K+ Star 在 400W Java 项目排名前 100,远超 FLAG, BAT 等国内外绝大部分开源项目)
+* **社区影响力大** (GitHub 18K+ Star 在 400W Java 项目排名前 100,远超 FLAG, BAT 等国内外绝大部分开源项目)
* **各项荣誉成就** (腾讯内外 5 个奖项、腾讯开源前五、腾讯后端 Star 第一、Trending 日周月榜大满贯 等)
* **多样用户案例** (腾讯内有互娱、音乐、微信、云与智慧,外部有华为、华能、百度、快手、中兴、圆通、传音等)
* **适用场景广泛** (社交聊天、阅读资讯、影音娱乐、办公学习 等各种 App、网站、小程序、公众号 等非金融类项目)
@@ -203,7 +203,7 @@ https://github.com/Tencent/APIJSON/wiki
* **灵活定制业务** (在后端编写 远程函数,可以拿到 session、version、当前 JSON 对象 等,然后自定义处理)
* **高质可靠代码** (代码严谨规范,蚂蚁集团源伞 Pinpoint 代码扫描分析报告平均每行代码 Bug 率低至 0.15%)
* **兼容各种项目** (协议不限 HTTP,与其它库无冲突,对各类 Web 框架集成友好且提供 SpringBoot, JFinal 的示例)
-* **工程轻量小巧** (仅依赖 fastjson,Jar 仅 280KB,Java 文件仅 59 个共 13719 行代码,例如 APIJSONORM 4.3.1)
+* **工程轻量小巧** (无第三方依赖,Jar 仅 263KB,Java 文件仅 68 个共 14864 行代码,例如 APIJSONORM 8.1.0)
* **多年持续迭代** (自 2016 年起已连续维护 8 年多,70+ 贡献者、100+ 发版、3000+ 提交,不断更新迭代中...)
**按照一般互联网中小型项目情况可得出以下对比表格:**
From bd6e17fdbdfd6726f59233b7474aa0604d1acc46 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: Thu, 9 Oct 2025 21:18:37 +0800
Subject: [PATCH 33/41] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20APIJSON=20=E7=9A=84?=
=?UTF-8?q?=20jackson=20=E6=8F=92=E4=BB=B6=EF=BC=8C=E7=AE=80=E5=8C=96?=
=?UTF-8?q?=E4=BD=BF=E7=94=A8=EF=BC=9Ahttps://github.com/APIJSON/apijson-j?=
=?UTF-8?q?ackson?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
创作不易,右上角点 ⭐Star 来支持/收藏下吧,谢谢 ^_^
---
README.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index ddd56c25..c42cdcad 100644
--- a/README.md
+++ b/README.md
@@ -643,10 +643,12 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[apijson-column](https://github.com/APIJSON/apijson-column) APIJSON 的字段插件,支持 字段名映射 和 !key 反选字段
-[apijson-gson](https://github.com/APIJSON/apijson-gson) APIJSON 的 gson 插件,简化使用
+[apijson-jackson](https://github.com/APIJSON/apijson-jackson) APIJSON 的 jackson 插件,简化使用
[apijson-fastjson2](https://github.com/APIJSON/apijson-fastjson2) APIJSON 的 fastjson2 插件,简化使用
+[apijson-gson](https://github.com/APIJSON/apijson-gson) APIJSON 的 gson 插件,简化使用
+
[apijson-milvus](https://github.com/APIJSON/apijson-milvus) APIJSON 的 Milvus AI 向量数据库插件
[apijson-influxdb](https://github.com/APIJSON/apijson-influxdb) APIJSON 的 InfluxDB 物联网时序数据库插件
From 7b43721aa6cd1171698c2e713406769046086f42 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年10月27日 11:12:35 +0800
Subject: [PATCH 34/41] =?UTF-8?q?=E7=94=9F=E6=80=81=E6=96=B0=E5=A2=9E=20AP?=
=?UTF-8?q?IJSON=20=E7=9A=84=20Rust=20=E7=89=88=EF=BC=8C=E4=B8=80=E4=B8=AA?=
=?UTF-8?q?=E4=BC=98=E9=9B=85=E3=80=81=E9=AB=98=E6=80=A7=E8=83=BD=E7=9A=84?=
=?UTF-8?q?=20Rust=20=E5=A4=9A=E6=95=B0=E6=8D=AE=E6=BA=90=E7=AE=A1?=
=?UTF-8?q?=E7=90=86=E7=B3=BB=E7=BB=9F=EF=BC=8C=E6=94=AF=E6=8C=81=20MySQL?=
=?UTF-8?q?=20=E5=92=8C=20PostgreSQL?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
创作不易,右上角点亮 ⭐ Star 收藏/支持下吧,谢谢 ^_^
https://gitee.com/digithub/panda-base
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index c42cdcad..281462b9 100644
--- a/README.md
+++ b/README.md
@@ -689,6 +689,8 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[uliweb-apijson](https://github.com/zhangchunlin/uliweb-apijson) Python 版 APIJSON,支持 MySQL, PostgreSQL, SQL Server, Oracle, SQLite 等
+[panda-base](https://gitee.com/digithub/panda-base) APIJSON 的 Rust 版,一个优雅、高性能的 Rust 多数据源管理系统,支持 MySQL 和 PostgreSQL
+
[APIJSONParser](https://github.com/Zerounary/APIJSONParser) 第三方 APIJSON 解析器,将 JSON 动态解析成 SQL
[FfApiJson](https://gitee.com/own_3_0/ff-api-json) 用 JSON 格式直接生成 SQL,借鉴 APIJSON 支持多数据源
From 115794ca212bbd62d48537d2bf2aaa557c0cb726 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年11月15日 16:57:03 +0800
Subject: [PATCH 35/41] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=94=AF=E6=8C=81=20Da?=
=?UTF-8?q?taBend-=E5=B8=A6=20AI=20=E7=9A=84=E4=BA=91=E5=8E=9F=E7=94=9F?=
=?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=B9=96=E4=BB=93(Snowflake=20=E5=BC=80?=
=?UTF-8?q?=E6=BA=90=E6=9B=BF=E4=BB=A3)=20=E7=9A=84=E8=AF=B4=E6=98=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://github.com/APIJSON/APIJSON-Demo/blob/master/APIJSON-Java-Server/APIJSONBoot-MultiDataSource
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 281462b9..e3793602 100644
--- a/README.md
+++ b/README.md
@@ -50,6 +50,7 @@ This source code is licensed under the Apache License Version 2.0
+
From af347bca178da94f6605244be98790ab966a9ea3 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年11月29日 19:15:47 +0800
Subject: [PATCH 36/41] =?UTF-8?q?=E7=99=BB=E8=AE=B0=E6=96=87=E7=AB=A0=20[A?=
=?UTF-8?q?PIJSON=EF=BC=9A=E9=87=8D=E6=96=B0=E5=AE=9A=E4=B9=89=E5=90=8E?=
=?UTF-8?q?=E7=AB=AF=E5=BC=80=E5=8F=91=E4=BD=93=E9=AA=8C=E7=9A=84=E9=9B=B6?=
=?UTF-8?q?=E4=BB=A3=E7=A0=81ORM=E6=A1=86=E6=9E=B6](https://blog.csdn.net/?=
=?UTF-8?q?gitblog=5F01177/article/details/155216163)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
感谢文章作者的贡献,大家 点赞、收藏、转发 支持热心的 TA 吧〜
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index e3793602..caadbc9f 100644
--- a/README.md
+++ b/README.md
@@ -633,6 +633,8 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[springboot整合APIJSON——零代码万能通用 API(附源码)](https://blog.csdn.net/longzhutengyue/article/details/150579233)
+[APIJSON:重新定义后端开发体验的零代码ORM框架](https://blog.csdn.net/gitblog_01177/article/details/155216163)
+
### 生态项目
[APIJSON-Demo](https://github.com/APIJSON/APIJSON-Demo) APIJSON 各种语言、各种框架 的 使用示例项目、上手文档、测试数据 SQL 文件 等
From 78c77a4f3e47e44a50aeb10ea88312562f586473 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: Sun, 7 Dec 2025 19:54:39 +0800
Subject: [PATCH 37/41] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E7=89=88=E6=9C=AC?=
=?UTF-8?q?=E4=B8=BA=208.1.0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
APIJSONORM/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/APIJSONORM/pom.xml b/APIJSONORM/pom.xml
index bd340fa5..13c5d0bf 100644
--- a/APIJSONORM/pom.xml
+++ b/APIJSONORM/pom.xml
@@ -5,7 +5,7 @@
com.github.Tencent
APIJSON
- 8.0.2
+ 8.1.0
jar
APIJSONORM
From 200be8ffb6e714e8526a9b85b7ef1a3309f7a958 Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2025年12月20日 23:21:19 +0800
Subject: [PATCH 38/41] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=96=87=E7=AB=A0=20AP?=
=?UTF-8?q?I=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90=E8=BF=99=E4=B9=88?=
=?UTF-8?q?=E7=88=BD=EF=BC=9F=E5=AE=9E=E6=B5=8B=E8=85=BE=E8=AE=AFAPIJSON?=
=?UTF-8?q?=EF=BC=8C=E9=9B=B6=E4=BB=A3=E7=A0=81=E5=B0=B1=E8=83=BD=E7=8E=A9?=
=?UTF-8?q?=E8=BD=AC=E5=90=8E=E7=AB=AF=E6=8E=A5=E5=8F=A3=EF=BC=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
感谢 诗远治愈馆 的贡献,点赞、收藏、转发支持下热心的文章作者吧 ^_^
https://mp.weixin.qq.com/s/DmMIGHHcZ783KobGecMxGg
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index caadbc9f..db0f1044 100644
--- a/README.md
+++ b/README.md
@@ -635,6 +635,8 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[APIJSON:重新定义后端开发体验的零代码ORM框架](https://blog.csdn.net/gitblog_01177/article/details/155216163)
+[API自动生成这么爽?实测腾讯APIJSON,零代码就能玩转后端接口!](https://mp.weixin.qq.com/s/DmMIGHHcZ783KobGecMxGg)
+
### 生态项目
[APIJSON-Demo](https://github.com/APIJSON/APIJSON-Demo) APIJSON 各种语言、各种框架 的 使用示例项目、上手文档、测试数据 SQL 文件 等
From 54f7da08899ff4933fc3c8bf32e2aec9c0469550 Mon Sep 17 00:00:00 2001
From: TommyLemon
Date: Fri, 2 Jan 2026 22:27:26 +0800
Subject: [PATCH 39/41] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=85=B3=E9=94=AE?=
=?UTF-8?q?=E8=AF=8D=20@string=20=E6=8A=8A=E5=AD=97=E6=AE=B5=E8=BD=AC?=
=?UTF-8?q?=E4=B8=BA=20String=20=E8=BE=93=E5=85=A5=EF=BC=9BKEY=5FDEFULT=20?=
=?UTF-8?q?=E9=87=8D=E5=91=BD=E5=90=8D=E4=B8=BA=20KEY=5FDEFAULT=EF=BC=9B?=
=?UTF-8?q?=E5=8D=87=E7=BA=A7=E7=89=88=E6=9C=AC=E4=B8=BA=208.1.3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
APIJSONORM/pom.xml | 2 +-
APIJSONORM/src/main/java/apijson/JSONMap.java | 89 ++++++++++++-------
.../src/main/java/apijson/JSONResponse.java | 2 +-
APIJSONORM/src/main/java/apijson/Log.java | 2 +-
.../apijson/orm/AbstractObjectParser.java | 20 ++++-
.../java/apijson/orm/AbstractVerifier.java | 41 +++++----
6 files changed, 100 insertions(+), 56 deletions(-)
diff --git a/APIJSONORM/pom.xml b/APIJSONORM/pom.xml
index 13c5d0bf..8b36d0da 100644
--- a/APIJSONORM/pom.xml
+++ b/APIJSONORM/pom.xml
@@ -5,7 +5,7 @@
com.github.Tencent
APIJSON
- 8.1.0
+ 8.1.3
jar
APIJSONORM
diff --git a/APIJSONORM/src/main/java/apijson/JSONMap.java b/APIJSONORM/src/main/java/apijson/JSONMap.java
index 29d88f75..3b93d69d 100755
--- a/APIJSONORM/src/main/java/apijson/JSONMap.java
+++ b/APIJSONORM/src/main/java/apijson/JSONMap.java
@@ -109,19 +109,32 @@ public static boolean isTableArray(String key) {
public static String KEY_USER_ID = "userId";
public static String KEY_USER_ID_IN = KEY_USER_ID + "{}";
+ default String getIdKey() {
+ return KEY_ID;
+ }
+ default String getIdInKey() {
+ return KEY_ID_IN;
+ }
+ default String getUserIdKey() {
+ return KEY_USER_ID;
+ }
+ default String getUserIdInKey() {
+ return KEY_USER_ID_IN;
+ }
+
/**set "id":id in Table layer
* @param id
* @return
*/
default JSONMap setId(Long id) {
- return puts(KEY_ID, id);
+ return puts(getIdKey(), id);
}
/**set "id{}":[] in Table layer
* @param list
* @return
*/
default JSONMap setIdIn(List list) {
- return puts(KEY_ID_IN, list);
+ return puts(getIdInKey(), list);
}
/**set "userId":userId in Table layer
@@ -129,14 +142,14 @@ default JSONMap setIdIn(List list) {
* @return
*/
default JSONMap setUserId(Long id) {
- return puts(KEY_USER_ID, id);
+ return puts(getUserIdKey(), id);
}
/**set "userId{}":[] in Table layer
* @param list
* @return
*/
default JSONMap setUserIdIn(List list) {
- return puts(KEY_USER_ID_IN, list);
+ return puts(getUserIdInKey(), list);
}
@@ -150,36 +163,37 @@ default JSONMap setUserIdIn(List list) {
//@key关键字都放这个类 <<<<<<<<<<<<<<<<<<<<<< - String KEY_TRY = "@try"; //尝试,忽略异常 - String KEY_CATCH = "@catch"; //TODO 捕捉到异常后,处理方式 null-不处理;DEFAULT-返回默认值;ORIGIN-返回请求里的原始值 - String KEY_DROP = "@drop"; //丢弃,不返回,TODO 应该通过 fastjson 的 ignore 之类的机制来处理,避免导致下面的对象也不返回 - // String KEY_KEEP = "@keep"; //一定会返回,为 null 或 空对象时,会使用默认值(非空),解决其它对象因为不关联的第一个对为空导致也不返回 - String KEY_DEFULT = "@default"; //TODO 自定义默认值 { "@default":true },@default 可完全替代 @keep - String KEY_NULL = "@null"; //值为 null 的键值对 "@null":"tag,pictureList",允许 is NULL 条件判断, SET tag = NULL 修改值为 NULL 等 - String KEY_CAST = "@cast"; //类型转换 cast(date AS DATE) - - String KEY_ROLE = "@role"; //角色,拥有对某些数据的某些操作的权限 - String KEY_DATABASE = "@database"; //数据库类型,默认为MySQL - String KEY_DATASOURCE = "@datasource"; //数据源 - String KEY_NAMESPACE = "@namespace"; //命名空间,Table 在非默认 namespace 内时需要声明 - String KEY_CATALOG = "@catalog"; //目录,Table 在非默认 catalog 内时需要声明 - String KEY_SCHEMA = "@schema"; //数据库,Table 在非默认 schema 内时需要声明 - String KEY_EXPLAIN = "@explain"; //分析 true/false - String KEY_CACHE = "@cache"; //缓存 RAM/ROM/ALL - String KEY_COLUMN = "@column"; //查询的Table字段或SQL函数 - String KEY_FROM = "@from"; //FROM语句 - String KEY_COMBINE = "@combine"; //条件组合,每个条件key前面可以放&,|,!逻辑关系 "id!{},&sex,!name&$" - String KEY_GROUP = "@group"; //分组方式 - String KEY_HAVING = "@having"; //聚合函数条件,一般和@group一起用 - String KEY_HAVING_AND = "@having&"; //聚合函数条件,一般和@group一起用 - String KEY_SAMPLE = "@sample"; //取样方式 - String KEY_LATEST = "@latest"; //最近方式 - String KEY_PARTITION = "@partition"; //分区方式 - String KEY_FILL = "@fill"; //填充方式 - String KEY_ORDER = "@order"; //排序方式 + String KEY_TRY = "@try"; // 尝试,忽略异常 + String KEY_CATCH = "@catch"; // TODO 捕捉到异常后,处理方式 null-不处理;DEFAULT-返回默认值;ORIGIN-返回请求里的原始值 + String KEY_DROP = "@drop"; // 丢弃,不返回,TODO 应该通过 fastjson 的 ignore 之类的机制来处理,避免导致下面的对象也不返回 + // String KEY_KEEP = "@keep"; // 一定会返回,为 null 或 空对象时,会使用默认值(非空),解决其它对象因为不关联的第一个对为空导致也不返回 + String KEY_DEFAULT = "@default"; // TODO 自定义默认值 { "@default":true },@default 可完全替代 @keep + String KEY_NULL = "@null"; // 值为 null 的键值对 "@null":"tag,pictureList",允许 is NULL 条件判断, SET tag = NULL 修改值为 NULL 等 + String KEY_CAST = "@cast"; // 类型转换 cast(date AS DATE) + + String KEY_ROLE = "@role"; // 角色,拥有对某些数据的某些操作的权限 + String KEY_DATABASE = "@database"; // 数据库类型,默认为MySQL + String KEY_DATASOURCE = "@datasource"; // 数据源 + String KEY_NAMESPACE = "@namespace"; // 命名空间,Table 在非默认 namespace 内时需要声明 + String KEY_CATALOG = "@catalog"; // 目录,Table 在非默认 catalog 内时需要声明 + String KEY_SCHEMA = "@schema"; // 数据库,Table 在非默认 schema 内时需要声明 + String KEY_EXPLAIN = "@explain"; // 分析 true/false + String KEY_CACHE = "@cache"; // 缓存 RAM/ROM/ALL + String KEY_COLUMN = "@column"; // 查询的 Table 字段或 SQL 函数 + String KEY_FROM = "@from"; // FROM语句 + String KEY_COMBINE = "@combine"; // 条件组合,每个条件 key 前面可以放 &,|,! 逻辑关系 "id!{},&sex,!name&$" + String KEY_GROUP = "@group"; // 分组方式 + String KEY_HAVING = "@having"; // 聚合函数条件,一般和 @group 一起用 + String KEY_HAVING_AND = "@having&"; // 聚合函数条件,一般和 @group 一起用 + String KEY_SAMPLE = "@sample"; // 取样方式 + String KEY_LATEST = "@latest"; // 最近方式 + String KEY_PARTITION = "@partition"; // 分区方式 + String KEY_FILL = "@fill"; // 填充方式 + String KEY_ORDER = "@order"; // 排序方式 String KEY_KEY = "@key"; // key 映射,year:left(date,4);name_tag:(name,tag) String KEY_RAW = "@raw"; // 自定义原始 SQL 片段 - String KEY_JSON = "@json"; //SQL Server 把字段转为 JSON 输出 + String KEY_JSON = "@json"; // 把字段转为 JSON 输出 + String KEY_STRING = "@string"; // 把字段转为 String 输入 String KEY_METHOD = "@method"; // json 对象配置操作方法 String KEY_GET = "@get"; // json 对象配置操作方法 String KEY_GETS = "@gets"; // json 对象配置操作方法 @@ -214,6 +228,7 @@ default JSONMap setUserIdIn(List list) {
KEY_KEY,
KEY_RAW,
KEY_JSON,
+ KEY_STRING,
KEY_METHOD,
KEY_GET,
KEY_GETS,
@@ -255,7 +270,7 @@ default JSONMap setDrop(Boolean drop) {
* @return this
*/
default JSONMap setDefault(Boolean hasDefault) {
- return puts(KEY_DEFULT, hasDefault);
+ return puts(KEY_DEFAULT, hasDefault);
}
@@ -525,6 +540,14 @@ default JSONMap setJson(String keys) {
return puts(KEY_JSON, keys);
}
+ /**set keys to cast to string
+ * @param keys "key0,key1,key2..."
+ * @return
+ */
+ default JSONMap setString(String keys) {
+ return puts(KEY_STRING, keys);
+ }
+
//JSONObject内关键词 key>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
diff --git a/APIJSONORM/src/main/java/apijson/JSONResponse.java b/APIJSONORM/src/main/java/apijson/JSONResponse.java
index c39aa1ac..7527adff 100755
--- a/APIJSONORM/src/main/java/apijson/JSONResponse.java
+++ b/APIJSONORM/src/main/java/apijson/JSONResponse.java
@@ -119,7 +119,7 @@ public static String getMsg(Map response) {
*/
default long getId() {
try {
- return JSON.getLongValue(this, KEY_ID);
+ return JSON.getLongValue(this, getIdKey());
} catch (Exception e) {
//empty
}
diff --git a/APIJSONORM/src/main/java/apijson/Log.java b/APIJSONORM/src/main/java/apijson/Log.java
index ba1a03bd..9cbacd0a 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 = "8.0.2";
+ public static final String VERSION = "8.1.3";
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 4d56499a..0e6aaa78 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java
@@ -61,6 +61,7 @@ public AbstractObjectParser setParser(Parser parser) {
* TODO Parser内要不因为 非 TYPE_ITEM_CHILD_0 的Table 为空导致后续中断。
*/
protected final boolean drop;
+ private List stringKeyList;
/**for single object
*/
@@ -103,7 +104,12 @@ public AbstractObjectParser(@NotNull M request, String parentPath, SQLConfig parse(String name, boolean isReuse) throws
// hasOtherKeyNotFun = true;
// }
- if (startsWithAt || key.endsWith("@") || (key.endsWith("") && value instanceof Map, ?>)) {
+ if (stringKeyList != null && stringKeyList.contains(key)) {
+ // 统一格式 String val = value == null || value instanceof String ? (String) value : JSON.toJSONString(value);
+ if (onParse(key, JSON.toJSONString(value)) == false) {
+ invalidate();
+ }
+ }
+ else if (startsWithAt || key.endsWith("@") || (key.endsWith("") && value instanceof Map, ?>)) {
if (onParse(key, value) == false) {
invalidate();
}
@@ -1227,7 +1239,9 @@ public void recycle() {
if (drop) {
request.put(KEY_DROP, drop);
}
-
+ if (stringKeyList != null) { // 避免被全局关键词覆盖 && ! stringKeyList.isEmpty()) {
+ request.put(KEY_STRING, StringUtil.get(stringKeyList.toArray()));
+ }
method = null;
parentPath = null;
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
index 44b2d7f1..55eeff40 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
@@ -6,8 +6,7 @@
package apijson.orm;
import static apijson.JSON.*;
-import static apijson.JSONMap.KEY_COMBINE;
-import static apijson.JSONMap.KEY_KEY;
+import static apijson.JSONMap.*;
import static apijson.RequestMethod.DELETE;
import static apijson.RequestMethod.GET;
import static apijson.RequestMethod.GETS;
@@ -923,6 +922,16 @@ public static , L extends List> M parse
return null;
}
+ Object _if = target.get(IF.name());
+ boolean ifIsStr = _if instanceof String && StringUtil.isNotEmpty(_if, true);
+ M ifObj = ifIsStr == false && _if instanceof Map,?> ? (M) _if : null;
+// : (_if instanceof String ? new apijson.JSONMap((String) _if, "" /* "throw new Error('')" */ ) : null);
+ if (ifObj == null && _if != null && ifIsStr == false) {
+// if (_if instanceof List>) {
+// }
+ throw new IllegalArgumentException(name + ": { " + IF.name() + ": value } 中 value 类型错误!只允许 String, JSONRequest!");
+ }
+
// 获取配置<<<<<<<<<<<<<<<<<<<<<<<<<<<< M type = JSON.get(target, TYPE.name()); M verify = JSON.get(target, VERIFY.name()); @@ -936,21 +945,8 @@ public static , L extends List> M parse
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);
- M ifObj = ifIsStr == false && _if instanceof Map,?> ? (M) _if : null;
-// : (_if instanceof String ? new apijson.JSONMap((String) _if, "" /* "throw new Error('')" */ ) : null);
- if (ifObj == null && _if != null && ifIsStr == false) {
-// if (_if instanceof List>) {
-// }
- throw new IllegalArgumentException(name + ": { " + IF.name() + ": value } 中 value 类型错误!只允许 String, JSONRequest!");
- }
-
// Object code = target.get(CODE.name());
- String allowPartialUpdateFail = StringUtil.get(getString(target, ALLOW_PARTIAL_UPDATE_FAIL.name()));
-
-
// 移除字段<<<<<<<<<<<<<<<<<<< String[] removes = StringUtil.split(remove); if (removes != null && removes.length> 0) {
@@ -976,6 +972,8 @@ public static , L extends List> M parse
}
// 判断必要字段是否都有>>>>>>>>>>>>>>>>>>>
+ String[] sks = StringUtil.split(getString(real, KEY_STRING));
+ List stringKeyList = sks == null || sks.length <= 0 ? null : Arrays.asList(sks); Set objKeySet = new HashSet(); // 不能用tableKeySet,仅判断 Table:{} 会导致 key:{ Table:{} } 绕过判断
@@ -991,6 +989,10 @@ public static , L extends List> M parse
}
Object tvalue = entry.getValue();
Object rvalue = real.get(key);
+ if (rvalue != null && stringKeyList != null && stringKeyList.contains(key)) {
+ rvalue = JSON.toJSONString(rvalue);
+ }
+
if (callback.onParse(key, tvalue, rvalue) == false) {
continue;
}
@@ -1091,8 +1093,8 @@ public static , L extends List> M parse
// 判断不允许传的key<<<<<<<<<<<<<<<<<<<<<<<<< for (String rk : rkset) { - if (rk == null) { // 无效的key - real.remove(rk); + if (rk == null || KEY_STRING.equals(rk)) { + // ConcurrentModificationException real.remove(rk); continue; } @@ -1111,6 +1113,9 @@ public static , L extends List> M parse
}
Object rv = real.get(rk);
+ if (rv != null && stringKeyList != null && stringKeyList.contains(rk)) {
+ rv = JSON.toJSONString(rv);
+ }
// 不允许传远程函数,只能后端配置
if (rk.endsWith("()") && rv instanceof String) {
@@ -1192,6 +1197,7 @@ public static , L extends List> M parse
// 校验重复>>>>>>>>>>>>>>>>>>>
// 校验并配置允许批量增删改部分失败<<<<<<<<<<<<<<<<<<< + String allowPartialUpdateFail = StringUtil.get(getString(target, ALLOW_PARTIAL_UPDATE_FAIL.name())); String[] partialFails = StringUtil.split(allowPartialUpdateFail); if (partialFails != null && partialFails.length> 0) {
for (String key : partialFails) {
@@ -1300,6 +1306,7 @@ public static , L extends List> M parse
}
}
}
+
Log.i(TAG, "parse return real = " + JSON.toJSONString(real));
return real;
}
From abcf2974ade386599670180d44931194bf8a7deb Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: Fri, 2 Jan 2026 22:57:49 +0800
Subject: [PATCH 40/41] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20Rust=20=E7=89=88=20A?=
=?UTF-8?q?PIJSON=20-=20=E4=B8=80=E4=B8=AA=E4=BC=98=E9=9B=85=E3=80=81?=
=?UTF-8?q?=E9=AB=98=E6=80=A7=E8=83=BD=E7=9A=84=E5=A4=9A=E6=95=B0=E6=8D=AE?=
=?UTF-8?q?=E6=BA=90=E7=AE=A1=E7=90=86=E7=B3=BB=E7=BB=9F=EF=BC=8C=E6=94=AF?=
=?UTF-8?q?=E6=8C=81=20MySQL,=20PostgreSQL=20=E7=9A=84=E7=BB=9F=E4=B8=80?=
=?UTF-8?q?=E7=AE=A1=E7=90=86=E5=92=8C=E6=93=8D=E4=BD=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
创作不易,右上角点亮 ⭐️ Star 支持下热心的作者吧 ^_^
---
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index db0f1044..46d3ecda 100644
--- a/README.md
+++ b/README.md
@@ -60,6 +60,7 @@ This source code is licensed under the Apache License Version 2.0
+
@@ -694,7 +695,7 @@ Issue/问卷 一般解答顺序:贡献者> 帮助他人的用户> 提供任
[uliweb-apijson](https://github.com/zhangchunlin/uliweb-apijson) Python 版 APIJSON,支持 MySQL, PostgreSQL, SQL Server, Oracle, SQLite 等
-[panda-base](https://gitee.com/digithub/panda-base) APIJSON 的 Rust 版,一个优雅、高性能的 Rust 多数据源管理系统,支持 MySQL 和 PostgreSQL
+[apijson-rust](https://gitee.com/APIJSON/panda-base) APIJSON 的 Rust 版,一个优雅、高性能的 Rust 多数据源管理系统,支持 MySQL 和 PostgreSQL
[APIJSONParser](https://github.com/Zerounary/APIJSONParser) 第三方 APIJSON 解析器,将 JSON 动态解析成 SQL
From 906e7961f7995ead0c981104c37586367f053a6d Mon Sep 17 00:00:00 2001
From: TommyLemon <1184482681@qq.com>
Date: 2026年1月19日 01:04:46 +0800
Subject: [PATCH 41/41] =?UTF-8?q?Java=EF=BC=9A=E5=88=A0=E9=99=A4=E5=A4=9A?=
=?UTF-8?q?=E4=BD=99=E7=9A=84=20application.properties?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
APIJSONORM/src/main/resources/application.properties | 0
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100755 APIJSONORM/src/main/resources/application.properties
diff --git a/APIJSONORM/src/main/resources/application.properties b/APIJSONORM/src/main/resources/application.properties
deleted file mode 100755
index e69de29b..00000000