Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

前端传参驼峰命名转为蛇形命名的衍生问题 #615

Open
QingShan512 opened this issue Sep 22, 2023 · 16 comments
Open

前端传参驼峰命名转为蛇形命名的衍生问题 #615

QingShan512 opened this issue Sep 22, 2023 · 16 comments

Comments

@QingShan512
Copy link

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

@QingShan512
Copy link
Author

我测了一下,原因是DevDeviceInstance中的product_id被转了驼峰命名,所以DevProduct中的id未关联到转驼峰后的productId字段

@QingShan512 QingShan512 changed the title 前端传参驼峰命名转为蛇形命名[Bug] 前端传参驼峰命名转为蛇形命名 衍生问题 Sep 22, 2023
@QingShan512 QingShan512 changed the title 前端传参驼峰命名转为蛇形命名 衍生问题 前端传参驼峰命名转为蛇形命名的衍生问题 Sep 22, 2023
@TommyLemon
Copy link
Collaborator

还没发布的版本,已经支持驼峰和蛇形命名转换功能,可以改 maven 依赖为依赖最新源码,或者等新发版
2b0d612

@QingShan512
Copy link
Author

用的是最新版代码,后台返回数据蛇形转驼峰没有问题。前端传驼峰,自动转蛇形部分不转换

@QingShan512
Copy link
Author

QingShan512 commented Sep 25, 2023

JSONResponse.IS_FORMAT_UNDERLINE = true;
SqlConfig加了getSQLKey

@QingShan512
Copy link
Author

参数:
{
"[]": {
"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 setColumn(List 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@未自动转蛇形

@QingShan512
Copy link
Author

我看了。里面的方案只能解决单表查询。表关联里的字段没有转换处理

@QingShan512
Copy link
Author

全局下划线驼峰互转:

  1. 重写APIJSONSQLConfig.getSQLKey,APIJSONSQLConfig.setColumn,APIJSONSQLConfig.onGetJoinString(格式化Join里的Key)
  2. 重写APIJSONSQLExecutor.getKey
    最终实现了一个相对理想的结果,就是不太确定这种方式有没有隐患

@TommyLemon
Copy link
Collaborator

可以跑下 APIAuto 上的测试用例
http://apijson.cn/api

@csx-bill
Copy link
Contributor

还没发布的版本,已经支持驼峰和蛇形命名转换功能,可以改 maven 依赖为依赖最新源码,或者等新发版 2b0d612

需要等6.2.1版本才可以实现驼峰吗

@TommyLemon
Copy link
Collaborator

TommyLemon commented Nov 25, 2023

还没发布的版本,已经支持驼峰和蛇形命名转换功能,可以改 maven 依赖为依赖最新源码,或者等新发版 2b0d612

需要等6.2.1版本才可以实现驼峰吗

@csx-bill
对,也可能不叫 6.2.1

@cmcxn
Copy link

cmcxn commented Dec 22, 2023

2b0d612

新增驼峰与蛇形命名互转方法以及 JSONResponse.IS_FORMAT_UNDERLINE 等配置

能否给个使用说明 比如说APIJSONBoot例子项目怎么用?
@TommyLemon 谢谢

@TommyLemon
Copy link
Collaborator

TommyLemon commented Dec 23, 2023

@cmcxn DemoSQLConfig 重写 getSQLKey 和 getSQLTable 把驼峰转为蛇形,DemoSQLExecutor 重写 getKey 把蛇形转为驼峰
#655

@zxcwindy
Copy link
Contributor

zxcwindy commented Aug 2, 2024

全局下划线驼峰互转:

  1. 重写APIJSONSQLConfig.getSQLKey,APIJSONSQLConfig.setColumn,APIJSONSQLConfig.onGetJoinString(格式化Join里的Key)
  2. 重写APIJSONSQLExecutor.getKey
    最终实现了一个相对理想的结果,就是不太确定这种方式有没有隐患

@SangSpace APIJSONSQLConfig.onGetJoinString这一步你如何实现的呢,我格式化了key和targetKey,但是会触发一个问题,当关联的两个表有相同的字段时,会发起1+n条sql请求(错误的期望),如果是用下划线关联则只会发1条sql(正确的预期)。

下面是异常的样例:
yichang

这个是正常的样例:
zhengchang

@TommyLemon
Copy link
Collaborator

TommyLemon commented Aug 2, 2024

@zxcwindy
AbstractSQLConfig 拼接 JOIN ON 中 on.getKey() 和 on.getTargetKey() 都要经过 getKey 处理,例如替换成 getKey(on.getKey())
image
image

image

另外 on.getTargetTable() 也顺便替换成 getSQLTableWithAlias(on.getTargetTable(), on.getTargetAlias()),解决表名用的可能不是数据库真实表名,getSQLTableWithAlias 需要参考 getSQLTable 写一个
return StringUtil.isEmpty(alias) ? table : table + '-' + alias // 避免 alias 别名和其它 表名/字段名 重名,尤其是表自己 JOIN 自己时很需要

#743
image
image

改好后提交 PR 贡献下代码,谢谢,开源要大家一起参与贡献才会更美好~
image

提 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

@zxcwindy
Copy link
Contributor

zxcwindy commented Aug 5, 2024

尝试了下,没有办法直接用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进行转换的话,是不会出现的,而且出现了也没啥意义。
这个问题如何解决呢?

@QingShan512
Copy link
Author

全局下划线驼峰互转:

  1. 重写APIJSONSQLConfig.getSQLKey,APIJSONSQLConfig.setColumn,APIJSONSQLConfig.onGetJoinString(格式化Join里的Key)
  2. 重写APIJSONSQLExecutor.getKey
    最终实现了一个相对理想的结果,就是不太确定这种方式有没有隐患

@SangSpace APIJSONSQLConfig.onGetJoinString这一步你如何实现的呢,我格式化了key和targetKey,但是会触发一个问题,当关联的两个表有相同的字段时,会发起1+n条sql请求(错误的期望),如果是用下划线关联则只会发1条sql(正确的预期)。

下面是异常的样例: yichang

这个是正常的样例: zhengchang

我目前没遇到这个,所以还没处理这种情况

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants