前端传参驼峰命名转为蛇形命名的衍生问题
APIJSON Version/APIJSON 版本号
6.2.0
Database Type & Version/数据库类型及版本号
mysql8
Environment/环境信息
- JDK/基础库:1.8
- OS/系统:windows
APIAuto Screenshots/APIAuto 请求与结果完整截屏
静态检查无问题
Current Behavior/问题描述
开启了前端传参驼峰命名转为蛇形命名之后,关联表数据未匹配到。前端传参@column中不能写驼峰,表关联join中不能写驼峰。
请求参数:
{
"[]": {
"query": 2,
"page": 0,
"count": 10,
"DevDeviceInstance": {
"@column": "id,name,product_id"
},
"DevProduct": {
"@column": "id,name",
"id@": "/DevDeviceInstance/product_id"
},
"join": "</DevProduct/id@"
},
"total@": "/[]/total",
"info@": "/[]/info"
}
返回结果:
{
"[]": [
{
"DevDeviceInstance": {
"id": 500,
"name": "测试设备",
"productId": 1694773415864
}
},
{
"DevDeviceInstance": {
"id": 501,
"name": "测试设备10",
"productId": 1685845210247561218
}
}
],
"total": 2,
"info": {
"total": 2,
"count": 10,
"page": 0,
"max": 0,
"more": false,
"first": true,
"last": true
},
"ok": true,
"code": 200,
"msg": "success",
"debug:info|help": " \n提 bug 请发请求和响应的【完整截屏】,没图的自行解决! \n开发者有限的时间和精力主要放在【维护项目源码和文档】上! \n【描述不详细】 或 【文档/常见问题 已有答案】 的问题可能会被忽略!! \n【态度 不文明/不友善】的可能会被踢出群,问题也可能不予解答!!! \n\n **环境信息** \n系统: Windows 10 10.0 \n数据库: DEFAULT_DATABASE = MYSQL \nJDK: 1.8.0_261 amd64 \nAPIJSON: 6.2.1 \n \n【常见问题】:https://github.com/Tencent/APIJSON/issues/36 \n【通用文档】:https://github.com/Tencent/APIJSON/blob/master/Document.md \n【视频教程】:https://search.bilibili.com/all?keyword=APIJSON\n 【警告】:[Reference]: []/0/DevProduct/id@: []/0/DevDeviceInstance/product_id 引用赋值获取路径对应的值为 null!请检查路径是否错误!; ",
"time": 1695371196089,
"sql:generate|cache|execute|maxExecute": "2|0|2|200",
"depth:count|max": "3|5",
"time:start|duration|end|parse|sql": "1695371195868|221|1695371196089|19|202"
}
Expected Behavior/期望结果
前端统一使用驼峰命名规范,数据库统一使用下划线命名规范。后台服务可以统一把所有字段做两个命名规范的转换。希望大佬可以给个方向,我可以自行调整下
Any additional comments?/其它补充说明?
No response
我测了一下,原因是DevDeviceInstance中的product_id被转了驼峰命名,所以DevProduct中的id未关联到转驼峰后的productId字段
还没发布的版本,已经支持驼峰和蛇形命名转换功能,可以改 maven 依赖为依赖最新源码,或者等新发版 https://github.com/Tencent/APIJSON/commit/2b0d612770d95a218aebe113e4f9aaa54aac63be
用的是最新版代码,后台返回数据蛇形转驼峰没有问题。前端传驼峰,自动转蛇形部分不转换
JSONResponse.IS_FORMAT_UNDERLINE = true; SqlConfig加了getSQLKey
参数: { "[]": { "query": 2, "page": 0, "count": 10, "DevProduct": {}, "DevDeviceInstance": { "@column": "productId;count(1):count", "@group": "productId", "productId@": "/DevProduct/id" }, "join": "</DevDeviceInstance/productId@" }, "total@": "/[]/total", "info@": "/[]/info" }
APIJSONSQLConfig: @Override public AbstractSQLConfig<Long> setColumn(List<String> column) { if (column == null) { return super.setColumn(null); } column = ColumnUtil.compatInputColumn(column, getTable(), getMethod()); for (int i = 0; i < column.size(); i++) { if (column.get(i).contains(":")) { continue; } column.set(i, JSONRequest.recoverUnderline(column.get(i), false)); } return super.setColumn(column); }
如上,重写了SqlConfig的setColumn之后,还剩下表关联配置里的productId@未自动转蛇形
我看了。里面的方案只能解决单表查询。表关联里的字段没有转换处理
全局下划线驼峰互转:
- 重写APIJSONSQLConfig.getSQLKey,APIJSONSQLConfig.setColumn,APIJSONSQLConfig.onGetJoinString(格式化Join里的Key)
- 重写APIJSONSQLExecutor.getKey 最终实现了一个相对理想的结果,就是不太确定这种方式有没有隐患
可以跑下 APIAuto 上的测试用例 http://apijson.cn/api
还没发布的版本,已经支持驼峰和蛇形命名转换功能,可以改 maven 依赖为依赖最新源码,或者等新发版 2b0d612
需要等6.2.1版本才可以实现驼峰吗
@csx-bill 对,也可能不叫 6.2.1
https://github.com/Tencent/APIJSON/commit/2b0d612770d95a218aebe113e4f9aaa54aac63be
新增驼峰与蛇形命名互转方法以及 JSONResponse.IS_FORMAT_UNDERLINE 等配置
能否给个使用说明 比如说APIJSONBoot例子项目怎么用? @TommyLemon 谢谢
@cmcxn DemoSQLConfig 重写 getSQLKey 和 getSQLTable 把驼峰转为蛇形,DemoSQLExecutor 重写 getKey 把蛇形转为驼峰 https://github.com/Tencent/APIJSON/issues/655
全局下划线驼峰互转:
- 重写APIJSONSQLConfig.getSQLKey,APIJSONSQLConfig.setColumn,APIJSONSQLConfig.onGetJoinString(格式化Join里的Key)
- 重写APIJSONSQLExecutor.getKey 最终实现了一个相对理想的结果,就是不太确定这种方式有没有隐患
@SangSpace APIJSONSQLConfig.onGetJoinString这一步你如何实现的呢,我格式化了key和targetKey,但是会触发一个问题,当关联的两个表有相同的字段时,会发起1+n条sql请求(错误的期望),如果是用下划线关联则只会发1条sql(正确的预期)。
下面是异常的样例:
这个是正常的样例:
@zxcwindy
AbstractSQLConfig 拼接 JOIN ON 中 on.getKey() 和 on.getTargetKey() 都要经过 getKey 处理,例如替换成 getKey(on.getKey())
另外 on.getTargetTable() 也顺便替换成 getSQLTableWithAlias(on.getTargetTable(), on.getTargetAlias()),解决表名用的可能不是数据库真实表名,getSQLTableWithAlias 需要参考 getSQLTable 写一个 return StringUtil.isEmpty(alias) ? table : table + '-' + alias // 避免 alias 别名和其它 表名/字段名 重名,尤其是表自己 JOIN 自己时很需要
https://github.com/Tencent/APIJSON/issues/743
改好后提交 PR 贡献下代码,谢谢,开源要大家一起参与贡献才会更美好~

提 PR 贡献代码的步骤可参考: https://github.com/Tencent/APIJSON/blob/master/CONTRIBUTING.md#%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%80%E5%AE%9A%E8%A6%81%E8%B4%A1%E7%8C%AE%E4%BB%A3%E7%A0%81
尝试了下,没有办法直接用getKey(on.getKey())的方式替换,因为getKey()获取到是类似"User.user_id"的格式,在join的相关代码中,“quote + jt + quote”这段代码会再加一个别名,导致sql拼接成"User.User.user_id的形式,我在AbstractSQLConfig中添加了一个formatJoinKey的方法来包装,formatJoinKey(on.getKey())的形式,在子类里面可以自定义格式改写。
但以上也还是只解决sql的问题,并没有解决额外发送sql 的问题,不知道是哪里触发了。 正常来说,只生成下面这一条SQL即可
2024-08-05 11:47:38.760: AbstractSQLExecutor.DEBUG:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
已生成 1 条 SQL
execute startTime = 1722829658760
database = ; schema = ; sql =
SELECT `User`.`user_id`, `TeamUser`.* FROM `user` AS `User`
INNER JOIN `team_user` AS `TeamUser` ON `TeamUser`.`user_id` = `User`.`user_id`
WHERE ( ( ( (`TeamUser`.`team_id` = 'admin') ) ) ) LIMIT 10
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
但是改了join的key之后,会额外再执行一条如下的SQL:
2024-08-05 11:47:38.767: AbstractSQLExecutor.DEBUG:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
已生成 2 条 SQL
execute startTime = 1722829658767
database = ; schema = ; sql =
SELECT * FROM `team_user` WHERE ( (`user_id` = '2c91808483d5a09e0183d5a4d5b20000') AND (`team_id` = 'admin') ) LIMIT 1
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
这个SQL如果不做join的key进行转换的话,是不会出现的,而且出现了也没啥意义。 这个问题如何解决呢?
全局下划线驼峰互转:
- 重写APIJSONSQLConfig.getSQLKey,APIJSONSQLConfig.setColumn,APIJSONSQLConfig.onGetJoinString(格式化Join里的Key)
- 重写APIJSONSQLExecutor.getKey 最终实现了一个相对理想的结果,就是不太确定这种方式有没有隐患
@SangSpace APIJSONSQLConfig.onGetJoinString这一步你如何实现的呢,我格式化了key和targetKey,但是会触发一个问题,当关联的两个表有相同的字段时,会发起1+n条sql请求(错误的期望),如果是用下划线关联则只会发1条sql(正确的预期)。
下面是异常的样例:
这个是正常的样例:
我目前没遇到这个,所以还没处理这种情况

