Open cloudAndMonkey opened 1 year ago
@TommyLemon 1、独立定义一个url method, 通过解析不同method执行不同流程 和已有method区分开,避免歧义 对,这样更好,enum RequestMethod.java 新增 CRUD 这个枚举值,对应 URL 为 /crud,对于前端没传参 transaction: true 时自动放入 transaction: true。
场景: method= crud 1、传递 "@transaction": true 2、不传 这里实现方案要考虑几个点: 1、在校验模块, 遍历json每个对象、数组的 method, 就知道是否需要开启事物 但是 为了后面 函数调用支持事物, 这个方式有局限性 2、对应 URL 为 /crud,对于前端没传参 transaction: true 时自动放入 transaction: true 3、将不同method功能区分开 现在json执行是通用解析,需不需要控制, 只能调用crud 方法,才能支持增删改查等操作. 其他method, 除了函数、子查询,就只能和 url method保持一致的操作
1、在校验模块, 遍历json每个对象、数组的 method, 就知道是否需要开启事物
扫描所有字段来识别是否有 transaction 代价太大了。 没有 transaction: true,那就不做全局事务处理,局部有 增删改 就局部处理事务。 如果业务需求必须整体有事务,那就通过 Request 表配置规则来强制 PUT transaction: true。
非 CRUD 方法,都只能和 URL method 完全一致,避免意料之外的安全风险。 如果传了 method 相关键值对("@delete":"Comment" 等),直接抛异常 "不支持在 GET 中 DELETE !"
话说现有使用方式 "@delete":["Comment"] 麻烦了点,前端传参应该尽可能简化,除非有兼容等严重问题或实现代价太大,APIJSON 所有 key 不支持逗号 , 分号 ; 斜杠 / 反斜杠 \,所以 "@delete":"Comment[],Moment" 并不会有兼容问题。 可以用 StringUtil.split 分割逗号,内部处理了整体空值、局部空值等。
@TommyLemon 1、扫描所有字段来识别是否有 transaction 代价太大了。 要考虑数组的情况, 不可行. 我当时就是不想全部解析, 只通过key及@变量 2、事物这块 那就通过 Request 表配置规则来强制 PUT transaction: true。 不需要, 每条执行语句都知道它的method 我先测一下 3、 "@delete":["Comment"] 我来改一下, 当时采用数组, 是想到后台直接jsonArray转换方便 4、非 CRUD 方法,都只能和 URL method 完全一致,避免意料之外的安全风险。 如果传了 method 相关键值对("@delete":"Comment" 等),直接抛异常 "不支持在 GET 中 DELETE !"
为了支持跨数据源的事务,需要在 AbstractParser 新增一个
// Map<数据源标识, SQLExecutor 实例>
Map<String, SQLExecutor> datasourceSQLExecutorMap
数据源标识同 AbstractSQLExecutor.connectionMap 的 key https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java#L1135-L1156
AbstractParser.getSQLExecutor 根据 数据源标识 get 到非 null 就返回,没有才 createSQLExecutor 然后 put 进 map 再返回; https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java#L344-L349
Parser.begin 时只对当前的 SQLExecutor 调用 begin。
Parser.rollback 时统一遍历 datasourceSQLExecutorMap 的所有 SQLExecutor 来 rollback; Parser.commit 时统一遍历 datasourceSQLExecutorMap 的所有 SQLExecutor 来 commit; Parser.close 时统一遍历 datasourceSQLExecutorMap 的所有 SQLExecutor 来 close;
1、在校验模块, 遍历json每个对象、数组的 method, 就知道是否需要开启事物
扫描所有字段来识别是否有 transaction 代价太大了。 没有 transaction: true,那就不做全局事务处理,局部有 增删改 就局部处理事务。 如果业务需求必须整体有事务,那就通过 Request 表配置规则来强制 PUT transaction: true。
非 CRUD 方法,都只能和 URL method 完全一致,避免意料之外的安全风险。 如果传了 method 相关键值对("@delete":"Comment" 等),直接抛异常 "不支持在 GET 中 DELETE !"
话说现有使用方式 "@delete":["Comment"] 麻烦了点,前端传参应该尽可能简化,除非有兼容等严重问题或实现代价太大,APIJSON 所有 key 不支持逗号 , 分号 ; 斜杠 / 反斜杠 \,所以 "@delete":"Comment[],Moment" 并不会有兼容问题。 可以用 StringUtil.split 分割逗号,内部处理了整体空值、局部空值等。
@TommyLemon 1、全局事物这块 没有 transaction: true,那就不做全局事务处理,局部有 增删改 就局部处理事务。 不好意思, 这里我没有理解你的意思. 说说我的理解哈 json配置 datasource, 是知道哪些操作共享一个 datasource. 同一个数据源, 多个 PUT、DELETE、POST 使用同一个Connection. 也就是说, 只要一个 connection, 存在 PUT、DELETE、POST,就开启全局事物? 不好意思, 还是你更优的解决方案,我没有get到? commit 提交事物: 是在多个 操作( PUT、DELETE、POST ) 执行完, 才调用:
如果不是全局事务,那就只有当执行 增/删/改 时开启,执行完马上 commit,碰到下一个 增/删/改 再开启和 commit。 如果是全局事务,则一开始就开启,执行完整个请求再 commit。
@TommyLemon 这几点我已经搞好了 1、url method crud支持
1) 对象内 "@method" 2) "@post","@put","@delete" 3) 对于没有显式声明操作方法的,直接用 URL(/get, /post 等) 对应的默认操作方法 第三点不适用了,url method =crud,必须显示定义操作方法 throw new IllegalArgumentException("url crud方法,必须定义 " + key + " 对应的method, 例如: @post: \"xxx,xxx[]\" 或者 对象内 @method=\"POST\" !");
2、非 CRUD 方法,都只能和 URL method 完全一致,避免意料之外的安全风险。 如果传了 method 相关键值对("@delete":"Comment" 等),直接抛异常 "不支持在 GET 中 DELETE !" http://xxx/put
{
"@post": "User:aa",
"User:aa":{
"username":"test-3",
"password": "233223",
"state": 1
},
"tag": "User",
"@explain": true
}
3、非crud 支持函数、sql@ 子查询调用. 4、修改 "@get": 数组 改为 字符串
{
"@post": "User:aa,User_address[]",
"User:aa":{
"username":"test1",
"password": "123456",
"state": 1
},
"User_address[]": [
{
"user_id@": "User:aa/id",
"addr": "ddd",
"count": 1
},
{
"user_id@": "User:aa/id",
"addr": "ddd1",
"count": 2
}
],
"@delete": "User:delUser,User_address:delUserAddress",
"User:delUser":{
"id{}": ["b6d7c307-cb82-4780-8361-2509973d88de", "c63d7bd8-cbb8-41f8-9ee0-713f0d30474b","cadeca84-2901-4850-aa36-6672d9d34299"]
},
"User_address:delUserAddress": {
"id{}": ["887edfe9-0206-415d-96de-325d97e248cb", "24eb9e05-d3ef-4661-8d22-c063643f61cd"]
},
"@explain": true
}
@TommyLemon 还有一个功能需要支持, put, 能够按照 name="xxx" 来修改.例如 update xxx set xxx ="" wehre name = "xxx" 目前非id put修改,只能通过ref引用做为条件进行修改,例如: // 非id修改
{
"sql@": {
"@method": "GET",
"with": true,
"from": "User",
"User": {
"@column": "username",
"username": "非id-update-test-0"
}
},
"User": {
"@state": 1,
"password": "123456",
"username{}@": "sql"
},
"explan": true
}
WITH `sql` AS (SELECT `username` FROM `housekeeping`.`User` WHERE ( (`username` = '非id-update-test-0') ) )
UPDATE `housekeeping`.`User` SET `password` = '123456_1669605075502' WHERE ( (`username` IN ( SELECT * FROM `sql`) ) )
你看这么改行不? 对象内的临时变量 @xxx 作为条件, 例如 :
"User": {
"@state": 1,
"password": "123456"
}
update user set password = "123456" where state = 1;
@TommyLemon 这几点我已经搞好了 1、url method crud支持
解析顺序
- 对象内 "@method"
- "@post","@put","@delete"
- 对于没有显式声明操作方法的,直接用 URL(/get, /post 等) 对应的默认操作方法 第三点不适用了,url method =crud,必须显示定义操作方法 throw new IllegalArgumentException("url crud方法,必须定义 " + key + " 对应的method, 例如: @post: "xxx,xxx[]" 或者 对象内 @method="POST" !");
2、非 CRUD 方法,都只能和 URL method 完全一致,避免意料之外的安全风险。 如果传了 method 相关键值对("@delete":"Comment" 等),直接抛异常 "不支持在 GET 中 DELETE !" http://xxx/put { "@post": "User:aa", "User:aa":{ "username":"test-3", "password": "233223", "state": 1 }, "tag": "User", "@Explain": true } 3、非crud 支持函数、sql@ 子查询调用. 4、修改 "@get": 数组 改为 字符串 { "@post": "User:aa,User_address[]", "User:aa":{ "username":"test1", "password": "123456", "state": 1 }, "User_address[]": [ { "user_id@": "User:aa/id", "addr": "ddd", "count": 1 }, { "user_id@": "User:aa/id", "addr": "ddd1", "count": 2 } ], "@delete": "User:delUser,User_address:delUserAddress", "User:delUser":{ "id{}": ["b6d7c307-cb82-4780-8361-2509973d88de", "c63d7bd8-cbb8-41f8-9ee0-713f0d30474b","cadeca84-2901-4850-aa36-6672d9d34299"] }, "User_address:delUserAddress": { "id{}": ["887edfe9-0206-415d-96de-325d97e248cb", "24eb9e05-d3ef-4661-8d22-c063643f61cd"] }, "@Explain": true }
CRUD 方法,没有声明就用 GET。 @method 看起来已经没有必要了,可以考虑去掉。
WITH `sql` AS (SELECT `username` FROM `housekeeping`.`User` WHERE ( (`username` = '非id-update-test-0') ) )
@state 会被认为是自定义关键词,与现有语法冲突,不合适。 目前可以用 "@combine":"state" 指定 "state": 1 是条件。 https://github.com/Tencent/APIJSON/blob/master/Document.md#3.2
https://github.com/Tencent/APIJSON/issues/277 https://github.com/Tencent/APIJSON/issues/425
WITH `sql` AS (SELECT `username` FROM `housekeeping`.`User` WHERE ( (`username` = '非id-update-test-0') ) )
@State 会被认为是自定义关键词,与现有语法冲突,不合适。 目前可以用 "@combine":"state" 指定 "state": 1 是条件。 https://github.com/Tencent/APIJSON/blob/master/Document.md#3.2
277 #425
嗯嗯,不好意思, 应该先查文档 测了一下,没问题, 转换为了regexp_like 正则匹配
{
"User": {
"state~": "1",
"password": "123456",
"username~": "test4",
"@combine": "state~ & username~"
},
"explan": true
}
UPDATE `housekeeping`.`User` SET `password` = '123456_1669608632896' WHERE ( regexp_like(`state`, '1', 'c') ) AND ( regexp_like(`username`, 'test4', 'c') )
CRUD 方法,没有声明就用 GET。 @method 看起来已经没有必要了,可以考虑去掉。
@TommyLemon CRUD 方法,没有声明就用 GET。 会出现吞并 json执行语句, 返回200的情况. 不方便排错. 框架是"正确"执行, 但是 对于用户来说, 就是一种"错觉" 这也是我很想避免的情况 比如: http://xxx/crud
{
"User:aa":{
"username":"test1",
"password": "123456",
"state": 1
},
"User_address[]": [
{
"user_id@": "User:aa/id",
"addr": "ddd",
"count": 1
},
{
"user_id@": "User:aa/id",
"addr": "ddd1",
"count": 2
}
],
"@put": "User_address:modifUA",
"User_address:modifUA":
{
"id": "5e2d528c-106a-4f14-90b2-f27b5943e3e1",
"user_id@": "User:aa/id",
"addr": "addr-01",
"count": 1
},
"@explain": true
}
"username~": "test4",
带有查询条件功能符的话,不用声明在 @combine 内,也会作为条件
json 不用传递 @method, 代码我已经调整 我也做了head 子查询sql@的兼容,避免子查询别转化为 count执行 错误语句:
WITH `sql` AS (SELECT count(*) FROM `housekeeping`.`Sys_user_role` WHERE ( (`user_id` = '4732209c-5785-4827-b532-5092f154fd94') ) ) \nSELECT * FROM `housekeeping`.`Sys_role` WHERE ( (`id` IN ( SELECT * FROM `sql`) ) ) LIMIT 1
正确语句:
WITH `sql` AS (SELECT `role_id` FROM `housekeeping`.`Sys_user_role` WHERE ( (`user_id` = '4732209c-5785-4827-b532-5092f154fd94') ) ) \nSELECT * FROM `housekeeping`.`Sys_role` WHERE ( (`id` IN ( SELECT * FROM `sql`) ) ) LIMIT 1
CRUD 方法,没有声明就用 GET。 @method 看起来已经没有必要了,可以考虑去掉。
@TommyLemon CRUD 方法,没有声明就用 GET。 会出现吞并 json执行语句, 返回200的情况. 不方便排错. 框架是"正确"执行, 但是 对于用户来说, 就是一种"错觉" 这也是我很想避免的情况 比如: http://xxx/crud
{ "User:aa":{ "username":"test1", "password": "123456", "state": 1 }, "User_address[]": [ { "user_id@": "User:aa/id", "addr": "ddd", "count": 1 }, { "user_id@": "User:aa/id", "addr": "ddd1", "count": 2 } ], "@put": "User_address:modifUA", "User_address:modifUA": { "id": "5e2d528c-106a-4f14-90b2-f27b5943e3e1", "user_id@": "User:aa/id", "addr": "addr-01", "count": 1 }, "@explain": true }
未显示声明 method,默认用 GET,至于参数被吞掉,没有实际执行,这是 bug,改掉就好了
CRUD 方法,没有声明就用 GET。 @method 看起来已经没有必要了,可以考虑去掉。
@TommyLemon CRUD 方法,没有声明就用 GET。 会出现吞并 json执行语句, 返回200的情况. 不方便排错. 框架是"正确"执行, 但是 对于用户来说, 就是一种"错觉" 这也是我很想避免的情况 比如: http://xxx/crud
{ "User:aa":{ "username":"test1", "password": "123456", "state": 1 }, "User_address[]": [ { "user_id@": "User:aa/id", "addr": "ddd", "count": 1 }, { "user_id@": "User:aa/id", "addr": "ddd1", "count": 2 } ], "@put": "User_address:modifUA", "User_address:modifUA": { "id": "5e2d528c-106a-4f14-90b2-f27b5943e3e1", "user_id@": "User:aa/id", "addr": "addr-01", "count": 1 }, "@explain": true }
未显示声明 method,默认用 GET,至于参数被吞掉,没有实际执行,这是 bug,改掉就好了 哈哈,那我来改掉. 不然我受不了. 用apijson这段时间,我最讨厌的就是json吞并问题
@TommyLemon 我分析了一下代码, 主要有两个点: 1、无法匹配执行流程, 将json语句原样添加到 sqlRequest 2、子查询出错 "user_id@": "User:aa/id", 如果 ref 找不到,语句将不会执行, json就会被吞掉 当开启 AbstractVerifier.IS_UPDATE_MUST_HAVE_ID_CONDITION = false; ref就是查询关键词了.
你看这里是 不管IS_UPDATE_MUST_HAVE_ID_CONDITION 的值,无法找到引用对象,就抛异常嘛? 我想起来了, 我当时为啥要整理 https://github.com/Tencent/APIJSON/issues/467 就是因为ref找不到, json被吞掉,不执行
累死我了, json支持事物、多条语句执行, http crud支持 很完善了 我去搞elasticSearch了 后面回过头再来搞 多数据源,以及控制每条语句connection
@TommyLemon 我分析了一下代码, 主要有两个点: 1、无法匹配执行流程, 将json语句原样添加到 sqlRequest 2、子查询出错 "user_id@": "User:aa/id", 如果 ref 找不到,语句将不会执行, json就会被吞掉 当开启 AbstractVerifier.IS_UPDATE_MUST_HAVE_ID_CONDITION = false; ref就是查询关键词了.
你看这里是 不管IS_UPDATE_MUST_HAVE_ID_CONDITION 的值,无法找到引用对象,就抛异常嘛? 我想起来了, 我当时为啥要整理 #467 就是因为ref找不到, json被吞掉,不执行
1.GET/GETS/HEAD/HEADS/DELETE 都不会处理 Table[]:[] ,这个没有对应的协议及功能,不用管,用户这么传,原样返回,这是他们用法问题。
2.引用赋值,如果关联的值查不到或者为 null,不能允许继续查询,因为这会导致范围扩大,不符合绝大部分需求,而且有严重的安全隐患,例如 GETS/HEADS/PUT/DELETE 的 id/userId 条件限制因为允许 null 而失效。这不是 bug,是功能特性,所以也不用管。
https://github.com/Tencent/APIJSON/issues/467#issuecomment-1328735827
累死我了, json支持事物、多条语句执行, http crud支持 很完善了 我去搞elasticSearch了 后面回过头再来搞 多数据源,以及控制每条语句connection
可以的
1.GET/GETS/HEAD/HEADS/DELETE 都不会处理 Table[]:[] ,这个没有对应的协议及功能,不用管,用户这么传,原样返回,这是他们用法问题。
2.引用赋值,如果关联的值查不到或者为 null,不能允许继续查询,因为这会导致范围扩大,不符合绝大部分需求,而且有严重的安全隐患,例如 GETS/HEADS/PUT/DELETE 的 id/userId 条件限制因为允许 null 而失效。这不是 bug,是功能特性,所以也不用管。 @TommyLemon 我知道这是用户使用的问题 吞掉执行语句, crud里面有/POST/PUT/DELETE语句 ,会提交成功的. 要考虑新手入门,练手阶段 吞掉执行语句, explain模式 返回结果要能让人家通过结果知道 为啥没有执行sql语句,是因为引用失败了
我看了apijson elasticSearch demo. 引入 elasticsearch-sql. json里面配置多数据源,我测一下
1.GET/GETS/HEAD/HEADS/DELETE 都不会处理 Table[]:[] ,这个没有对应的协议及功能,不用管,用户这么传,原样返回,这是他们用法问题。
2.引用赋值,如果关联的值查不到或者为 null,不能允许继续查询,因为这会导致范围扩大,不符合绝大部分需求,而且有严重的安全隐患,例如 GETS/HEADS/PUT/DELETE 的 id/userId 条件限制因为允许 null 而失效。这不是 bug,是功能特性,所以也不用管。 @TommyLemon 我知道这是用户使用的问题 吞掉执行语句, crud里面有/POST/PUT/DELETE语句 ,会提交成功的. 要考虑新手入门,练手阶段 吞掉执行语句, explain模式 返回结果要能让人家通过结果知道 为啥没有执行sql语句,是因为引用失败了
这个通过 APIAuto 来解决吧,新增一个提示。类似 "user": {} 这种小写字母开头的,不符合 APIJSON 表名规范,就会有提示。
@explain: true 也不返回,这个是 bug,可以在 AbstractObjectParser 中处理下 sqlResponse = null; 加上判断 isExplain 时 sqlResponse = new JSONObject(); put 进 @explain: { "msg": "引用赋值未获取到有效的关联值,返回空" }
@TommyLemon 我看了 官网X-Pack sql(收费)支持: https://www.elastic.co/guide/en/elasticsearch/reference/7.17/sql-getting-started.html 开源: https://github.com/NLPchina/elasticsearch-sql 如果apijson要支持elasticsearch sql,有几个点,需要解决: 1、新增、修改 它们都不支持新增、修改, 如果要支持新增修改, 通过如下语句执行: elasticsearch-sql 是通过: org.elasticsearch.client.transport.TransportClient 方式执行插入 删除: apijson需要按照数据源类型, 生成不同格式的新增/修改 sql语句, 删除,查询 还没有细测 2、查询 估计还是会有一部分兼容问题 目前还没有细测,查询是按照jdbc 语句来执行
@TommyLemon 我看了 官网X-Pack sql(收费)支持: https://www.elastic.co/guide/en/elasticsearch/reference/7.17/sql-getting-started.html 开源: https://github.com/NLPchina/elasticsearch-sql 如果apijson要支持elasticsearch sql,有几个点,需要解决: 1、新增、修改 它们都不支持新增、修改, 如果要支持新增修改, 通过如下语句执行: elasticsearch-sql 是通过: org.elasticsearch.client.transport.TransportClient 方式执行插入 删除: apijson需要按照数据源类型, 生成不同格式的新增/修改 sql语句, 删除,查询 还没有细测 2、查询 估计还是会有一部分兼容问题 目前还没有细测,查询是按照jdbc 语句来执行
1、Elasticsearch-SQL 不支持增删改的话,APIJSON 也先不急着支持,用户可以用 RESTful API 的方式自己实现。后续如果这方面需求的用户比较多再考虑。
/refresh 这种接口也让用户自己调用。APIJSON 暂时先主要支持最核心也最常用的查询功能。
2、截屏的代码没有用 APIJSON,可以用 APIJSON 再试试。
之前改 bug 等源码变更,可以先提交 PR 哦,有了 fork 项目,提 PR 只需要 Git 推送到 fork 项目,然后点 Contribute > Open Pull Request,例如
@TommyLemon 1、我这两天就提交,应该不用大改了,我明天再回归测试一下 2、用apijson使用elasticSearch 用户可以用 RESTful API 的方式自己实现. 需要我实现接口来新增、修改、删除? 目前apijson除了数据源支持elasticSearch, 执行方法方面如何集成? 比如: 多数据源, 其中一个数据源是 elasticSearch, 执行插入, apijson会生成sql语句,然后调用 执行方法?
@TommyLemon redis这块, 我今天看了一下. redis 也支持 sql语句方式来操作表,比如: https://github.com/RedBeardLab/rediSQL(不更新了), 改为收费版: https://zeesql.com/#pricing https://help.aliyun.com/document_detail/99960.html 我通过docker测试了一下: 支持redis表 新增、修改、删除、查询、分组、关联查询等 在某些维度统计,不需要走大数据分析的情况, 能解决elasticSearch无法关联查询的情况
2、用户直接调用 Elasticsearch 的官方 API(目前是 RESTful API)实现增删改、初始化、权限管理等,也可以用配套的管理界面或 CLI 等。
执行方法是指 SQL 函数?远程函数?还是存储过程?如果是前 2 者应该都没问题,至于存储过程看 Elasticsearch 是否支持。
这个第三方库倒是支持 SQL 语法比较全,不过 新增和修改 看文档还不支持,可以对比下官方的,看情况决定用哪个。 https://github.com/NLPchina/elasticsearch-sql#sql-features
@TommyLemon redis这块, 我今天看了一下. redis 也支持 sql语句方式来操作表,比如: https://github.com/RedBeardLab/rediSQL(不更新了), 改为收费版: https://zeesql.com/#pricing https://help.aliyun.com/document_detail/99960.html 我通过docker测试了一下: 支持redis表 新增、修改、删除、查询、分组、关联查询等 在某些维度统计,不需要走大数据分析的情况, 能解决elasticSearch无法关联查询的情况
赞,也可以通过 SQL 语法支持 APIJSON 对接 Redis 了。
2、用户直接调用 Elasticsearch 的官方 API(目前是 RESTful API)实现增删改、初始化、权限管理等,也可以用配套的管理界面或 CLI 等。
执行方法是指 SQL 函数?远程函数?还是存储过程?如果是前 2 者应该都没问题,至于存储过程看 Elasticsearch 是否支持。
这个第三方库倒是支持 SQL 语法比较全,不过 新增和修改 看文档还不支持,可以对比下官方的,看情况决定用哪个。 https://github.com/NLPchina/elasticsearch-sql#sql-features
新增、修改,只是不同的实现而已, 很简单的几行代码就搞定 1、只需要把sql语句转换或者 直接按照不同数据源生成执行语句. 2、 然后调用不同实现的connection、submit等方法 这块代码要动一下手脚, 要扩展维度
是的,只要和 SQL 语法差异不大,往往都容易对接
APIJSON 核心的 ORM 库不依赖具体的 JDBC 驱动哈,保持简洁,只在 SQL/类 SQL 语法上支持生成语句,如果有要必须引入某个数据源的 JDBC 用它们的 class 等特殊要求(例如 ElasticSearchDruidDataSourceFactory),对于 Elasticsearch, Redis 这种广泛使用的数据源可以放到 apijson-framework 集成,其它的通过新增 apijson-column/apijson-router 这样的插件来支持。 非必须的(一般都走标准通用的 JDBC 协议,不强制使用自定义的类),都是用户业务项目中自己依赖。
APIJSON 核心的 ORM 库不依赖具体的 JDBC 驱动哈,保持简洁,只在 SQL/类 SQL 语法上支持生成语句,如果有要必须引入某个数据源的 JDBC 用它们的 class 等特殊要求(例如 ElasticSearchDruidDataSourceFactory),Elasticsearch, Redis 这种广泛使用的数据源可以放到 apijson-framework 集成,其它的通过新增 apijson-column/apijson-router 这样的插件来支持。 非必须的(一般都走标准通用的 JDBC 协议,不强制使用自定义的类),都是用户业务项目中自己依赖。
嗯嗯
@TommyLemon 2、用户直接调用 Elasticsearch 的官方 API(目前是 RESTful API)实现增删改、初始化、权限管理等,也可以用配套的管理界面或 CLI 等。
执行方法是指 SQL 函数?远程函数?还是存储过程?如果是前 2 者应该都没问题,至于存储过程看 Elasticsearch 是否支持。
哈哈,我的思路还在深度集成上面, 明白你的意思了, 远程函数里面调用elasticSearch, 我测一下 人家有另外一种选择, 通过SpringContextUtils.getBean(elasticSearchXXX); 方式,直接操作elasticSearch了 如果仅仅是数据源的集成, 功能点上面没有办法和json贴合, 业务功能实现需要用户自己去实现. 并没有给用户减轻工作量呀
是的, 我来把深度集成这块理一下, 哈哈
@TommyLemon 2、用户直接调用 Elasticsearch 的官方 API(目前是 RESTful API)实现增删改、初始化、权限管理等,也可以用配套的管理界面或 CLI 等。
执行方法是指 SQL 函数?远程函数?还是存储过程?如果是前 2 者应该都没问题,至于存储过程看 Elasticsearch 是否支持。
哈哈,我的思路还在深度集成上面, 明白你的意思了, 远程函数里面调用elasticSearch, 我测一下 人家有另外一种选择, 通过SpringContextUtils.getBean(elasticSearchXXX); 方式,直接操作elasticSearch了 如果仅仅是数据源的集成, 功能点上面没有办法和json贴合, 业务功能实现需要用户自己去实现. 并没有给用户减轻工作量呀
大部分用户用 Elasticsearch 应该主要是为了海量文本高性能搜索,这个属于查询,所以先接入查询,可以满足这个核心需求。
@TommyLemon 2、用户直接调用 Elasticsearch 的官方 API(目前是 RESTful API)实现增删改、初始化、权限管理等,也可以用配套的管理界面或 CLI 等。 执行方法是指 SQL 函数?远程函数?还是存储过程?如果是前 2 者应该都没问题,至于存储过程看 Elasticsearch 是否支持。 哈哈,我的思路还在深度集成上面, 明白你的意思了, 远程函数里面调用elasticSearch, 我测一下 人家有另外一种选择, 通过SpringContextUtils.getBean(elasticSearchXXX); 方式,直接操作elasticSearch了 如果仅仅是数据源的集成, 功能点上面没有办法和json贴合, 业务功能实现需要用户自己去实现. 并没有给用户减轻工作量呀
大部分用户用 Elasticsearch 应该主要是为了海量文本高性能搜索,这个属于查询,所以先接入查询,可以满足这个核心需求。
一步一步来嘛 1、多数据源 2、@Transaction 事物粒度 3、elasticSearch/redis sql操作 4、不兼容部分,看咋处理
@TommyLemon UPDATE user set username = '222' where id = "fbe20363-85ee-4065-b4bb-ae90343a1a0c" and (SELECT count(*) from sys_user_role where user_id = "fbe20363-85ee-4065-b4bb-ae90343a1a0c") > 0 子查询 做为判断条件,和主表字段不挂钩这种情况, 需要支持吗? 除了原生sql, 请问还有其他方式吗?
@TommyLemon
用户业务项目中: DemoSQLExecutor extends APIJSONSQLExecutor getConnection 应该简化一下, 业务项目不关心connectionMap等信息 这里和业务项目约定好 key获取方式即可.比如通过: datasource 来获取连接 public Connection getConnection(xxxx) throws Exception { if (datasource != null ) { DataSource ds; switch (datasource) { case "HIKARICP": DataSource ds = SpringContextUtils.getBean(DataSource.class); return ds.getConnection(); } }
@TommyLemon 我梳理了一下 json解析执行完整流程: 为了支持跨数据源的事务,需要在 AbstractParser 新增一个 // Map<数据源标识, SQLExecutor 实例> Map<String, SQLExecutor> datasourceSQLExecutorMap 1、整个流程只会创建一个 SQLExecutor 2、创建SQLExecutor的时候,还没有创建 createSQLConfig 3、多数据源管理 和connection、rollback、commit、close挂钩 Parser.rollback 时统一遍历 datasourceSQLExecutorMap 的所有 SQLExecutor 来 rollback; Parser.commit 时统一遍历 datasourceSQLExecutorMap 的所有 SQLExecutor 来 commit; Parser.close 时统一遍历 datasourceSQLExecutorMap 的所有 SQLExecutor 来 close; 这种方式简单,先不细化
多数据源实现逻辑,我再想想,还没想清楚 1、子查询、crud中的查询是否新建一个connection和 增/删/改 独立出来 2、默认datasource 3、全局datasource 4、等等
@TommyLemon 2、用户直接调用 Elasticsearch 的官方 API(目前是 RESTful API)实现增删改、初始化、权限管理等,也可以用配套的管理界面或 CLI 等。 执行方法是指 SQL 函数?远程函数?还是存储过程?如果是前 2 者应该都没问题,至于存储过程看 Elasticsearch 是否支持。 哈哈,我的思路还在深度集成上面, 明白你的意思了, 远程函数里面调用elasticSearch, 我测一下 人家有另外一种选择, 通过SpringContextUtils.getBean(elasticSearchXXX); 方式,直接操作elasticSearch了 如果仅仅是数据源的集成, 功能点上面没有办法和json贴合, 业务功能实现需要用户自己去实现. 并没有给用户减轻工作量呀
大部分用户用 Elasticsearch 应该主要是为了海量文本高性能搜索,这个属于查询,所以先接入查询,可以满足这个核心需求。
对应一个主流的用法是,先从 Elasticsearch 查出 id 列表,然后再到 MySQL 等关系型数据库中 id IN 查完整数据
@TommyLemon UPDATE user set username = '222' where id = "fbe20363-85ee-4065-b4bb-ae90343a1a0c" and (SELECT count(*) from sys_user_role where user_id = "fbe20363-85ee-4065-b4bb-ae90343a1a0c") > 0 子查询 做为判断条件,和主表字段不挂钩这种情况, 需要支持吗? 除了原生sql, 请问还有其他方式吗?
用 EXISTS,或 @raw
@TommyLemon
用户业务项目中: DemoSQLExecutor extends APIJSONSQLExecutor getConnection 应该简化一下, 业务项目不关心connectionMap等信息 这里和业务项目约定好 key获取方式即可.比如通过: datasource 来获取连接 public Connection getConnection(xxxx) throws Exception { if (datasource != null ) { DataSource ds; switch (datasource) { case "HIKARICP": DataSource ds = SpringContextUtils.getBean(DataSource.class); return ds.getConnection(); } }
APIJSON 现有的所有库都没有依赖具体的 Web 框架,避免局限于只适用于 Spring。 SpringContextUtils 这种某个 Web 框架特有的类不能直接依赖。 这种适配连接池的代码,本来就只要写很少,而且还是初始化时写一次就行,不需要到处写,优化的意义不大。 尤其是确定只用一个连接池库,那就不需要 try catch 了。
@TommyLemon 2、用户直接调用 Elasticsearch 的官方 API(目前是 RESTful API)实现增删改、初始化、权限管理等,也可以用配套的管理界面或 CLI 等。 执行方法是指 SQL 函数?远程函数?还是存储过程?如果是前 2 者应该都没问题,至于存储过程看 Elasticsearch 是否支持。 哈哈,我的思路还在深度集成上面, 明白你的意思了, 远程函数里面调用elasticSearch, 我测一下 人家有另外一种选择, 通过SpringContextUtils.getBean(elasticSearchXXX); 方式,直接操作elasticSearch了 如果仅仅是数据源的集成, 功能点上面没有办法和json贴合, 业务功能实现需要用户自己去实现. 并没有给用户减轻工作量呀
大部分用户用 Elasticsearch 应该主要是为了海量文本高性能搜索,这个属于查询,所以先接入查询,可以满足这个核心需求。
到时候我测一下
@TommyLemon 用户业务项目中: DemoSQLExecutor extends APIJSONSQLExecutor getConnection 应该简化一下, 业务项目不关心connectionMap等信息 这里和业务项目约定好 key获取方式即可.比如通过: datasource 来获取连接 public Connection getConnection(xxxx) throws Exception { if (datasource != null ) { DataSource ds; switch (datasource) { case "HIKARICP": DataSource ds = SpringContextUtils.getBean(DataSource.class); return ds.getConnection(); } }
APIJSON 现有的所有库都没有依赖具体的 Web 框架,避免局限于只适用于 Spring。 SpringContextUtils 这种某个 Web 框架特有的类不能直接依赖。 这种适配连接池的代码,本来就只要写很少,而且还是初始化时写一次就行,不需要到处写,优化的意义不大。 尤其是确定只用一个连接池库,那就不需要 try catch 了。 @TommyLemon 哈哈, 可能我表述不当, 我想通过举例说明, connectionMap 可以不用在业务项目 getConnection暴露. 业务项目实现 getConnection, 只关心如何按照约定返回 connection. 为啥会提到这个点, 是因为目前要实现apijson不支持的功能,业务项目@Override某个方法进行修改,随着apijson版本变化,这也是维护成本
这个到可以封装下,例如一个方法 Connection getConnection(String key)
@TommyLemon 我梳理了一下 json解析执行完整流程: 为了支持跨数据源的事务,需要在 AbstractParser 新增一个 // Map<数据源标识, SQLExecutor 实例> Map<String, SQLExecutor> datasourceSQLExecutorMap 1、整个流程只会创建一个 SQLExecutor 2、创建SQLExecutor的时候,还没有创建 createSQLConfig 3、多数据源管理 和connection、rollback、commit、close挂钩 Parser.rollback 时统一遍历 datasourceSQLExecutorMap 的所有 SQLExecutor 来 rollback; Parser.commit 时统一遍历 datasourceSQLExecutorMap 的所有 SQLExecutor 来 commit; Parser.close 时统一遍历 datasourceSQLExecutorMap 的所有 SQLExecutor 来 close; 这种方式简单,先不细化
多数据源实现逻辑,我再想想,还没想清楚 1、子查询、crud中的查询是否新建一个connection和 增/删/改 独立出来 2、默认datasource 3、全局datasource 4、等等
应该只需要根据数据源分配,如果这样实现有什么问题不好搞,那就再把 method 拼接到 key 中。
@TommyLemon 嗯嗯,这一点我考虑到了,我再想想, 测一下, 再发给你看看, 我哪里没有考虑到的 目前 一个 SQLExecutor, 不需要改造, 合理的. 并且以后支持不同数据源, 也没有影响 如果你有啥想法随时跟我说,谢谢 只是有一点, 一定要轻量 connection, sql语句执行、会滚、提交. 要为以后 支持 redis、elasticSearch 非sql的操作做准备 apijson按照json配置,生成sql或者执行语句(还没想好), 插件或者业务系统自己去执行, apijson就和某个框架隔离开了
好的,多多交流~
Description
@TommyLemon 功能描述: 一个服务编排的伪码流程设计 将伪码转换为 apijson json、前置、后置函数、javascript、redis、elasticSearch等 并且能够mork每一步,执行中间流程,还能查询每个阶段执行的sql语句,及结果.
json格式:
1、独立定义一个url method, 通过解析不同method执行不同流程 和已有method区分开,避免歧义 2、最外层新增传参 "transaction": true 来指定开启事务 3、控制每条语句的数据源 4、完善 “@Explain" 如果没有执行计划,则返回sql语句. 能够在 reponse返回值中, 看到json中执行的每条sql,方便排错 5、@version支持 定义不同场景的 新增、修改、删除等执行规则. 请通过version版本区分 6、前置函数 1) 要能拿到其他数据源 2) 能拿到json执行过程中的数据 3) 拿到当前数据源(和外部json一个事物执行) 4) 从数据库/或其他数据源 查询获取对照关系 组装数据, 调用对应数据源的api方法执行即可 5) 前置函数,能调用其他函数 把一些计算, 执行,计算 等 放到一个函数进行整合 还没细化 7、支持mork 通过伪码,分解为不同 阶段 的json语句执行
测试点: 1、测试 一个json多条语句,后置函数啥时候执行 2、操作其他数据源, 事物是json执行完才会提交, 需要保证一致性 3、redis、elasticSearch、javascript、lua等功能测试