Repository navigation
一个json(事务)同时支持新增、修改、删除、查询、别名 #468
Copy link
Copy link
Open
Labels
Enhancement 增强增强功能、提高性能等增强功能、提高性能等
Description
版本5.2.0
1、业务表-插入不同表1:1、1:n、n:n
2、业务表-修改不同表1:1、1:n、n:n
3、业务表-批量删除不同表
实现流程:
1、继承APIJSONParser
2、重载 parseCorrectRequest方法
User__User 通过__分割, tag 和 structure的类名
新增, tag和 structure的类名一样, 更多示例请参见postman



该方法,是参数校验入口

特定tag,则走分支流程


修改引用关系

postman测试示例:
业务表-插入不同表1:1-源码实现
{
"User__User":{
"username":"test2",
"password": "123456",
"state": 1
},
"User_address__User_address":
{
"user_id@": "User/id",
"addr": "ddd",
"count": 1
},
"tag": "Batch_Tag_UserWithUser_addressList"
}业务表-插入不同表1:n-源码实现
{
"User__User":{
"username":"test1",
"password": "123456",
"state": 1
},
"User_address[]__User_address[]": [
{
"user_id@": "User/id",
"addr": "ddd",
"count": 1
},
{
"user_id@": "User/id",
"addr": "ddd1",
"count": 2
}
],
"tag": "Batch_Tag_UserWithUser_addressList"
}业务表-插入不同表n:n-源码实现
{
"User[]__User[]":[
{
"username":"test3",
"password": "123456",
"state": 1
},
{
"username":"test4",
"password": "123456",
"state": 1
}
],
"User_address[]__User_address[]": [
{
"user_id": "94593122-403a-4eb2-a6f0-182ed3da7764",
"addr": "ddd",
"count": 1
},
{
"user_id": "94593122-403a-4eb2-a6f0-182ed3da7764",
"addr": "ddd1",
"count": 2
}
],
"tag": "Batch_Tag_UserWithUser_addressList"
}业务表-批量修改不同表1:n-源码实现
{
"User__User":{
"id": "94593122-403a-4eb2-a6f0-182ed3da7764",
"username":"test1-1",
"password": "111111",
"state": 1
},
"User_address[]__User_address[]": [
{
"id": "e8bb9e79-9bbe-49d2-9542-77792368bece",
"user_id@": "User/id",
"addr": "addr-01",
"count": 1
},
{
"id": "4dfee57f-6953-4371-865f-22b6e1957fee",
"user_id@": "User/id",
"addr": "addr-11",
"count": 1
}
],
"tag": "Batch_Tag_UserWithUser_addressList"
}业务表-批量修改不同表n:n-源码实现
{
"User[]__User[]":[
{
"id": "f60e829a-1181-4331-ac1e-f5faf64e3a8c",
"username":"test-3",
"password": "123456-1",
"state": 1
},
{
"id": "ca86a2e0-d504-4772-b06a-1a8c9e2b12c9",
"username":"test-4",
"password": "123456-1",
"state": 1
}
],
"User_address[]__User_address[]": [
{
"id": "faf8a605-66a3-4ce1-b774-c499b86a4984",
"user_id": "94593122-403a-4eb2-a6f0-182ed3da7764",
"addr": "ddd-1",
"count": 1
},
{
"id": "ac88ce16-6cdf-41a3-b382-c78452c5a850",
"user_id": "94593122-403a-4eb2-a6f0-182ed3da7764",
"addr": "ddd-2",
"count": 2
}
],
"tag": "Batch_Tag_UserWithUser_addressList"
}业务表-批量删除不同表-源码实现
{
"User[]__User":{
"id{}": ["8e44c04a-6e90-4dfe-b021-3436453c55dd", "94593122-403a-4eb2-a6f0-182ed3da7764","ca86a2e0-d504-4772-b06a-1a8c9e2b12c9"]
},
"User_address[]__User_address": {
"id{}": ["1ed2dda1-5800-4b69-b128-7771dd79046f", "e8bb9e79-9bbe-49d2-9542-77792368bece","4dfee57f-6953-4371-865f-22b6e1957fee","faf8a605-66a3-4ce1-b774-c499b86a4984"]
},
"tag": "Batch_Tag_UserWithUser_addressList"
}后续我再研究一下
1、支持不同的操作类型,比如 GET、POST、DELETE, 在一个json里面, 才能保证事物
2、function函数 执行语句, 加入事物
框架能支持数组, 把数组拆解为一条一条语句执行, 只要把相关引用 传递进 function应该能搞定,空了研究一下,哈哈
Reacted by TommyLemon, FS.IO and Alleyq
Metadata
Metadata
Assignees
Labels
Enhancement 增强增强功能、提高性能等增强功能、提高性能等
Activity
TommyLemon commentedon Nov 10, 2022
赞,感谢分享~
TommyLemon commentedon Nov 10, 2022
把增删改查不同操作放在一个请求 JSON 中,需要额外字段来标记,例如可以是
或者这样更好一些,可以提前知道那些片段属于哪种操作,方便解析,性能也更好:
对于没有显式声明操作方法的,直接用 URL(/get, /post 等) 对应的默认操作方法
cloudAndMonkey commentedon Nov 11, 2022
@TommyLemon >
临时变量 是以表名为维度
"@post": "Moment,Comment[]", 解决不了同时操作一张表
比如
sys_permission 菜单表
新增一条记录, 要修改父菜单的is_leaf(是否叶子节点:1:是 0:不是)
流程要处理几个地方(还没有细化):
1、校验
2、语句执行
语句执行的地方要能区分一张表不同的 请求操作类型
cloudAndMonkey commentedon Nov 11, 2022
还有一种方法, 通过request structure 字段来支持,通过json格式匹配
1、校验
{
"post":
[
{"Table_order_list_test": {"MUST":"aa,dd","UPDATE": {"@ROLE": "OWNER,ADMIN","pwdEncrypt-()": "pwdEncrypt(id,password)"}, "REFUSE": "id"}},
{"User[]": {"User[]": [{"MUST":"username,password","REFUSE": "id"}], "UPDATE": {"@ROLE": "OWNER,ADMIN"}}}
]
"put":
[
{"Table_order_list_test": {"MUST":"aa,dd","UPDATE": {"@ROLE": "OWNER,ADMIN","pwdEncrypt-()": "pwdEncrypt(id,password)"}, "REFUSE": "id"}},
{"User[]": {"User[]": [{"MUST":"username,password","REFUSE": "id"}], "UPDATE": {"@ROLE": "OWNER,ADMIN"}}}
]
}
2、语句执行
将 @post、@get 如何打到对象上面跟着语句走
cloudAndMonkey commentedon Nov 11, 2022
目前我能想到比较简单的方式:
key: tag-table-post
语句执行
再想办法将 @post、@get 如何打到对象上面跟着语句走
TommyLemon commentedon Nov 11, 2022
对同一张表可以用别名来区分不同记录,例如:
{ "User": { //TODO 其它字段 }, "User:owner": { "@role": "OWNER", //TODO 其它字段 }, "User:count": { "@column": "count(1)", //TODO 其它字段 } }具体见 通用文档 > 3.设计规范 > 3.2 功能符 > 新建别名
https://github.com/Tencent/APIJSON/blob/master/Document.md#3.2
cloudAndMonkey commentedon Nov 11, 2022
@TommyLemon >
"name:alias",name映射为alias,用alias替代name。可用于 column,Table,SQL函数 等。
只用于GET类型、HEAD类型的请求post请求, 没办法传递 别名呀
{
"User:aa":{
"username":"test",
"password": "233223",
"state": 1
},
"tag": "User"
}
{"User:aa":{"username":"test","password":"233223","state":1},"format":true}
java.lang.UnsupportedOperationException: POST请求,请在 内传 User:{} !
TommyLemon commentedon Nov 13, 2022
以前没有这样的需求,现在可以新增支持。
”POST请求,请在 内传 User:{} !“
这个报错是因为 Request 表 structure 中配置的就是 "User":{} 而不是 "User:aa":{}
cloudAndMonkey commentedon Nov 14, 2022
嗯嗯,功能我基本调通了,一些细节我还要调整一下,比如 第一条语句 查询 如果没有结果,将会直接返回 等等
cloudAndMonkey commentedon Nov 15, 2022
cloudAndMonkey commentedon Nov 16, 2022
@TommyLemon

一个json 支持新增(单条、批量)、修改(单条、批量)、删除、查询、别名
实现代码如下:
1、重载 APIJSONParser 实现 parseCorrectRequest
2、注释tag校验
3、FormParser
实现单条、批量校验逻辑
`/**
* 相同对象,通过别名区分
* @PARAM method
* @PARAM tag
* @PARAM version
* @PARAM name
* @PARAM request
* @PARAM maxUpdateCount
* @PARAM creator
* @return
* @throws Exception
*/
private JSONObject batchVerify(RequestMethod method, String tag, int version, String name,
@NotNull JSONObject request, int maxUpdateCount, SQLCreator creator) throws Exception {
JSONObject jsonObject = new JSONObject(true);
String _tag = null;
if (request.keySet() == null || request.keySet().size() == 0) {
throw new IllegalArgumentException("json对象格式不正确 !,例如 "User": {}");
}
for (String key : request.keySet()) {
// key重复直接抛错
if (jsonObject.containsKey(key)) {
throw new IllegalArgumentException("json对象名重复,请添加操作类型区分!,例如 method__tag__structureKey, 或者: tag__structureKey");
}
4、修改 AbstractParser



示例:
sql层级最多5层
// 新增、修改、删除
// 执行sql语句条数不能超过5条
{
"User:aa":{
"@method": "POST",
"username":"test1",
"password": "123456",
"state": 1
},
"User_address[]": [
{
"@method": "POST",
"user_id@": "User:aa/id",
"addr": "ddd",
"count": 1
},
{
"@method": "POST",
"user_id@": "User:aa/id",
"addr": "ddd1",
"count": 2
}
],
"User_address:modifUA":
{
"@method": "PUT",
"id": "1c051f08-4671-4fef-8ae3-64fc8b45047d",
"user_id@": "User:aa/id",
"addr": "addr-01",
"count": 1
},
"User:delUser":{
"@method": "DELETE",
"id{}": ["1d42c09c-0780-4762-8100-a718d7c8a83b", "a1d51e2a-797c-4b3f-afc4-45befcd775ed"]
},
"@Explain": true
}
// 新增、修改、删除、查询
// get请求会导致事物无法提交(看需要是否支持)
// get请求最好放到前置函数里面操作,通过前置函数来回填需要新增、修改的参数
{
"User:aa":{
"@method": "POST",
"username":"test1",
"password": "123456",
"state": 1
},
"User_address[]": [
{
"@method": "POST",
"user_id@": "User:aa/id",
"addr": "ddd",
"count": 1
},
{
"@method": "POST",
"user_id@": "User:aa/id",
"addr": "ddd1",
"count": 2
}
],
"sql@": {
"@method": "GET",
"with": true,
"from": "User",
"User": {
"@column": "id",
"id{}": ["834df81e-cf8b-40a5-9638-c62fb00e8db4"]
}
},
"User_address:sUA[]": {
"@method": "GET",
"User_address": {
"user_id{}@": "sql"
},
"page": 0,
"count": 10,
"query": 2
},
"total@": "/User_address:sUA[]/total",
"@Explain": true
}
多条查询:
{
"sql@": {
"@method": "GET",
"with": true,
"from": "User",
"User": {
"@column": "id",
"id{}": ["64c09bdc-927a-411b-843f-ff3f72b5d5be"]
}
},
"User_address:ua[]": {
"@method": "GET",
"User_address": {
"user_id{}@": "sql"
},
"page": 0,
"count": 10,
"query": 2
},
"total@": "/User_address:ua[]/total",
"sql1@": {
"@method": "GET",
"with": true,
"from": "User",
"User": {
"@column": "id",
"id{}": ["64c09bdc-927a-411b-843f-ff3f72b5d5be"]
}
},
"User_address:ua1[]": {
"@method": "GET",
"User_address": {
"user_id{}@": "sql1"
},
"page": 0,
"count": 10,
"query": 2
},
"total1@": "/User_address:ua1[]/total",
"@Explain": true
}
TommyLemon commentedon Nov 16, 2022
赞,感谢分享~
TommyLemon commentedon Nov 16, 2022
可以最外层新增传参
"transaction": true
来指定有事务,这个全局关键词目前未支持,需要自己实现下。
然后重写 Parser 中
setAutoCommit
begin
commit
rollback
等事务相关方法。
另外建议 @method 值用全大写,例如 "@method": "GET",保持统一的常量/关键词命名风格,也方便复用 enum RequestMethod,例如
RequestMethod.GET.name().equals(method)
或者
RequestMethod.valueOf(method)
cloudAndMonkey commentedon Nov 17, 2022
好的,谢谢
cloudAndMonkey commentedon Nov 17, 2022
@TommyLemon

json第一次执行,会设置 AbstractSQLExecutor transactionIsolation , GET = 0 , 其他= 4
json解析每一条语句执行,只会改变自己的 transactionIsolation


所以只需要在 AbstractParser onCommit 这里改变判断条件即可:
以前是 get请求直接返回,不执行 commit
测试示例: 查询、新增
{ "sql@": { "@method": "GET", "with": true, "from": "User", "User": { "@column": "id", "id{}": ["c692d9d1-2e23-4055-99fb-66461bda33c3"] } }, "User_address:uad[]": { "@method": "GET", "User_address": { "user_id{}@": "sql" }, "page": 0, "count": 10, "query": 2 }, "total@": "/User_address:uad[]/total", "User:aa":{ "@method": "POST", "username":"test1", "password": "123456", "state": 1 }, "User_address:uad1[]": [ { "@method": "POST", "user_id@": "User:aa/id", "addr": "ddd", "count": 1 }, { "@method": "POST", "user_id@": "User:aa/id", "addr": "ddd1", "count": 2 } ], "@explain": true }执行结果: 事务生效, 数据入库正常

60 remaining items
TommyLemon commentedon Apr 12, 2023
@wahowaho
是个新引入的 bug
#512
这里不应该只 requestItem.put(_key, obj),丢了 "Request":{} 对象导致 objectVerify 抛异常,
应该把原始请求的所有键值对 put 进去,可以 requestItem.putAll(原来的 request 对象)。
可以改下源码试试,如果可以麻烦提 PR 贡献下代码哦,开源要大家一起参与贡献才会更美好~
https://github.com/Tencent/APIJSON/blob/master/CONTRIBUTING.md
cloudAndMonkey commentedon Apr 13, 2023
我来看看
cloudAndMonkey commentedon Apr 13, 2023
为啥每个 JSONObject 进行解析, 一方面是为了解决别名
TommyLemon commentedon Apr 13, 2023
@cloudAndMonkey
别名不用提前解析,同一层没有重复表名的话建议不用别名.
如果有别名,也可以直接在 Request 表 structure 字段里配置:
cloudAndMonkey commentedon Apr 13, 2023
那我测一下, crud 和其他方法都统一这么做
TommyLemon commentedon Apr 13, 2023
@cloudAndMonkey
刚刚 @wahowaho 提了个修复的 PR:
#545
cloudAndMonkey commentedon Apr 13, 2023
嗯嗯, 看到了, 需要删除tag 、JSONObject 别名判断的代码 , 今天晚上我好好梳理一下
cloudAndMonkey commentedon Apr 13, 2023
@TommyLemon

无别名
有别名

差不多改好了, 我拉通测一下,需要覆盖各种场景, 把 function 事物一起完善,再提交
比如: Comment:[] 支持别名等
最近有点忙, 不好意思😄
cloudAndMonkey commentedon Apr 17, 2023
@TommyLemon
代码已经提交

把 \ 去掉了, 代码在报错新增全能增删改查接口,可同时进行 增、删、改、查 多种操作,感谢 cloudAndMonkey 贡献 CRUD 功能
TommyLemon commentedon Sep 2, 2023
完善同一个请求内多种不同操作的关键词,新增支持
等简化写法
eccf252
ivanvolt-labs commentedon Sep 19, 2023
求助两位大佬,请问主键非id情况下需要单另外配置什么信息,目前主键为xxx_id,增删改均报错Unknown column 'id' in 'field list'
cloudAndMonkey commentedon Sep 20, 2023
@15207126400
zc0707 commentedon Apr 9, 2025
请求CURD方法参数:{
"@post": ["MobilizeTaskInfo[]"],
"MobilizeTaskInfo": {
"id{}": ["09a7a740-1935-469a-ab76-ea1ee1f94ddc"]
},
"@delete": ["MobilizeTaskInfo"],
"MobilizeTaskInfo[]": [{
"leading_unit_name": "市交通局",
"serial_number": "GD2025-064",
"task_content": "提前勘察部队过境路线,确保道路具备安全通行条件",
"issue_time": "2025-04-09 15:51:06",
"predict_end_time": "2025年3月31日上午10:00前完成",
"status": 1
}]
}
报错:服务器内部错误:getColumnString 不支持 CRUD 等 [GET,GETS,HEAD,HEADS,POST] 外的ReuqestMethod!
版本号:6.3.0
TommyLemon commentedon Apr 11, 2025
#809 (comment)