【实力踩坑】ORDER BY 不生效

很简单的一个问题但还是值得记录一下。

组内自定义了动态表头,支持表头字段的排序(表头字段列名是什么,排序查询传进来的就是什么),那列表查询的时候只好把 sql 写成一个嵌套子查询,在最后进行动态 order by orderFiled 的形式,代码如下:

select *
    from (
           select t1.c1 as column1, t1.c2 as column2, t2.c3 as column3
           from demo_table t1
                  inner join demo_table t2 on t1.c1 = t2.c1
         ) t
    order by #{orderField} #{orderType}

orderField 的值如下:

  • column1
  • column2
  • column3

orderType 的值如下:

  • asc
  • desc

然后我就天真的传入字段进行排序了,因为 DEBUG 日志级别,控制台打印 SQL 日志如下:

==>  Preparing: select * from ( select t1.c1 as column1, t1.c2 as column2, t2.c3 as column3 from demo_table t1 inner join demo_table t2 on t1.c1 = t2.c1 ) t order by ? ? 
==> Parameters: column1(String), asc(String)

看着没毛病哈,但是实际查询 order by 后面的字段就是不生效,我尝试了好几种方式就 TM 不生效,我很气啊,就这个小破玩意耽误了我好长时间,咋整呢?

最后和小伙伴回去讨论,一语点醒梦中人,妈的是#{}的坑,还记得它的孪生兄弟${}不,先看下它俩的区别:

在MyBatis中,#{}和${}都是用来替换参数的,但它们的功能和用途存在一些差异。

  • #{}用于预处理,而KaTeX parse error: Expected 'EOF', got '#' at position 14: {}用于直接替换。这意味着#̲{}解析为JDBC预编译语句(…{}则仅仅是一个纯粹的字符串替换。

  • 在解析阶段,#{}会将String类型的数据自动加上引号,而其他数据类型不会;而${}解析之后是什么就是什么,不会当做字符串处理。

  • 从安全性角度看,使用#{}不存在安全问题,而使用存在安全问题。因为{}在动态SQL解析阶段会进行变量替换,可能会被注入恶意代码。

  • 在某些特殊场合下,如使用排序时ORDER BY filed,只能使用{},不能用#{}。这是因为#{}在解析之后会将String类型的数据自动加上引号,导致解析错误。

  • 综上所述,#{}和${}在功能、使用场景和安全性方面存在差异。在实际使用中,需要根据具体需求和场景选择合适的参数替换方式。

从这里应该能发现了吧,#{}是个占位符的形式,会把参数默认解析为一个字符串常量,而order by '字符串常量'是没有任何效果的,从而判定出就是它的坑,而使用${}会把字段值完全拼接在 SQL 中,也就是是啥就是啥,当然这种方式会有注入的风险,但是对此处的实际场景来说也没啥风险,果断换成${}再次查询生效了。

外日他 dei,就这个破玩意浪费了我好长时间,虽然很简单,但是第一次踩到,记录一下。

启发: 以后遇到解决不了的问题,不要死磕,找小伙伴一起讨论下,说不定哪句话就直接点醒你。

谨以此记录我这不健全的脑干,只好一步一个坑来的实在。

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
LambdaQueryWrapper是MyBatis-Plus框架提供的一个查询条件构造器,用于构建复杂的查询条件。在使用LambdaQueryWrapper时,groupby和orderby可以通过以下方式实现: 1. Group By(分组): 使用LambdaQueryWrapper的groupBy方法可以实现分组查询,示例代码如下: ```java LambdaQueryWrapper<Entity> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.groupBy(Entity::getFieldName); List<Entity> result = entityMapper.selectList(queryWrapper); ``` 这样就可以按照指定的字段进行分组查询。 2. Order By(排序): 使用LambdaQueryWrapper的orderBy方法可以实现排序查询,示例代码如下: ```java LambdaQueryWrapper<Entity> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.orderByAsc(Entity::getFieldName1, Entity::getFieldName2); List<Entity> result = entityMapper.selectList(queryWrapper); ``` 这样就可以按照指定的字段进行升序排序。如果需要降序排序,可以使用orderByDesc方法。 如果在使用LambdaQueryWrapper的groupBy和orderBy方法时不生效,可能有以下几个原因: 1. 字段名错误:请确保传入的字段名与数据库中的字段名一致,大小写也要注意。 2. 版本问题:请确保使用的MyBatis-Plus版本支持groupBy和orderBy方法。如果版本过低,可能不支持这些方法。 3. 其他条件冲突:请检查是否有其他条件限制了groupBy和orderBy的生效,例如where条件、limit等。 希望以上解答对您有帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一宿君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值