mysql 分页查询 失效_分页功能--buildSql生成的SQL语句不准确导致mysql存在隐式转换的字段查询失效...

我们mysql中有个status字段类型是enum,即字符串对象,在查询的时候如果传入int类型会触发mysql的隐私转换。(解决办法在TP各种入口将status字段值强制转换为string即可)

但是我们在使用TP6的时候发现使用框架不做强制转换竟然也能查询出来,但是打印出来的SQL语句直接去执行是查不到的:

d13d2fedcd94607ffaaae76cef29c5cd.png

35a943bcd434ed103c3dffbf06d2b2d9.png

带着好奇心看了think-orm的底层代码发现实际上打印出来的SQL并非真正执行的SQL,真正执行的是通过PDO的prepare以及bindValue,而bindValue中会指定字段对应类型, 这个类型TP6在逻辑里面就会去获取mysql对应表的字段(仅限单表)

53dab4b2c128fd63fc90c26338354522.png

ca23f0909077dcdd6c76da8235f19697.png

所以我们判断 TP的打印SQL日志方法【getLastsql()】是有问题的

原本以为不需要在所有入口做强制转换,TP底层就帮我们做了, 但我们发现列表做了分页后, 列表的数据和分页中的total统计结果不一致。

由于通过PDO的bindValue占坑的形式TP6是获取不到mysql最终执行的语句的,我们通过打开mysql打印log, 在真正打印出来的SQL发现 COUNT和select的语句中, COUNT查询竟然没有做转换

44c23db88b67548a5c7359139a11a1b1.png

通过追溯源码, 发现了问题点:

TP的分页count和select调用方式不同,而恰好count方法是使用buildSql生成SQL语句再去做查询,而我们上面说到getLastSql这个方法有问题, 查找代码发现buildSql()方法底层最终和getLastsql方法一样是调用了PDOConnection中的getRealSql()方法。这个方法是有问题的,生成出来的语句中隐式转换没有做对

d794e116c066b4f85ff00ba11d86ec44.png

2d39f6844f05f537ea8cb56db4847a92.png

当然按前面说的,我们通过入口传入的参数全部转为字符串可以解决,但是既然TP底层提供了这个自动转换功能,也希望能把count方法也改一下,不然列表查询是做了转换,但是count又没做转换,导致列表和count查找结果不一致。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值