MyBatis排序踩坑记:为什么你的动态ORDER BY不生效?

mybatis 中对于 order by 动态排序的处理 首先字段名不知道,数量不确定,同时既要可以做到准确查询出结果,又要防止注入情况的发生,我是在网上没找到合适的解决方案。显然注入不了,因为这句sql 执行的结果是 查询 ctaname为 "Tom or 1=1" 这个字符的结果集,有就是有,没有就是没有。这样一种 or (或)的查询条件,显然 1=1 始终为真,则会查询出对应表中的所有数据,这不就是简单的注入情况了吗?比如最近有兄弟咨询,我需要动态的根据调用方法传递的比如 排序字段来进行排序(排序字段不知道,数量也不确定)。可以进行正常的排序。 阅读详情

MyBatis动态排序陷阱解析:从原理到实战的深度避坑指南

当你满怀信心地在MyBatis中实现了一个动态排序功能,测试时却发现数据依然杂乱无章——这种场景恐怕不少Java开发者都遇到过。动态排序作为数据展示的刚需功能,其实现过程中隐藏着MyBatis参数处理的深层机制,而盲目使用#{}和${}符号就像在代码里埋下了不定时炸弹。

1. 问题现象与初步诊断

上周在重构一个老项目时,我遇到了一个典型的动态排序失效案例。前端传入的排序字段和方向参数明明正确,但返回的数据始终按默认主键排序。查看日志发现SQL语句看似正常:

SELECT * FROM products WHERE category_id = ? ORDER BY ? ?

参数绑定显示为:

Parameters: 5(Integer), "price"(String), "DESC"(String)

但实际执行结果却完全没有按价格降序排列。这种"假成功"现象特别具有迷惑性——SQL语法正确执行,但业务效果不符合预期。

常见错误表象:

  • 日志显示排序参数已正确传入
  • 无任何SQL异常抛出
  • 返回数据保持无序或默认排序状态
  • 直接在数据库客户端执行生成的SQL同样无效

2. 核心问题解析:#{}与${}的本质区别

要彻底理解这个问题,需要深入MyBatis的参数处理机制。这两种占位符在预编译阶段有着完全不同的处理方式:

特性 #{} 预编译占位符 ${} 字符串替换
处理阶段 SQL预编译阶段 SQL解析阶段
安全性 防SQL注入 有注入风险
参数类型 自动类型转换 直接文本替换
适用场景 WHERE条件值 表名/字段名等SQL关键字
输出效果 生成带引号的参数值 原始文本插入

当我们在ORDER BY子句中使用#{}时:

ORDER BY #{fieldName} #{sortDirection}

实际生成的SQL会是:

ORDER BY 'p
面试时遇到order by注入我直接懵了 零基础学白帽黑客,搜公众号:白帽子左一。 阅读详情

相关推荐

【实力踩坑】ORDER BY 不生效

组内自定义了动态表头,支持表头字段的排序(表头字段列名是什么,排序查询传进来的就是什么),那列表查询的时候只好把 sql 写成一个嵌套子查询,在最后进行动态。看着没毛病哈,但是实际查询 order by 后面的字段就是不生效,我尝试了好几种方式就 TM 不生效,我很气啊,就这个小破玩意耽误了我好长时间,咋整呢?从安全性角度看,使用#{}不存在安全问题,而使用存在安全问题。会把字段值完全拼接在 SQL 中,也就是是啥就是啥,当然这种方式会有注入的风险,但是对此处的实际场景来说也没啥风险,果断换成。

一宿君 1929

Reeds-Shepp曲线公式推导及代码实现-第二部分(共三部分)

文章目录2. Reeds-Shepp求解2.1 L+S+L+L^+S^+L^+L+S+L+2.2 L+S+R+L^+S^+R^+L+S+R+2.3 L+R−L+L^+R^-L^+L+R−L+2.4 L+R−L−L^+R^-L^-L+R−L−2.5 L+R+L−L^+R^+L^-L+R+L−2.6 L+Rβ+Lβ−R−L^+R_{\beta}^+L_{\beta}^-R^-L+Rβ+​Lβ−​R−2.7 L+Rβ−Lβ−R+L^+R_{\beta}^-L_{\beta}^-R^+L+Rβ−​Lβ−​R+2.8

jianmo的博客 1212

Python 格点数据插值到站点 最邻近插值 双线性插值

python 气象数据格点数据插值到站点,最邻近插值法,双线性插值法

好记性不如烂笔头 8459

STC8H硬件IIC从机模式实战:手把手教你驱动OLED屏幕(附完整代码)

本文详细介绍了如何使用STC8H单片机的硬件IIC从机模式驱动SSD1306 OLED屏幕,包括硬件连接、寄存器配置、中断处理和实际应用中的优化技巧。通过完整的代码示例和实战经验分享,帮助开发者快速掌握I2C通信协议和OLED屏幕驱动技术,提升嵌入式开发效率。

weixin_33747129的博客 336

/lib//libclntsh.so: file format not recognized; treating as linker script

centos7.7+oracle19.3 建库过程报错:预检查都是通过的 /oracle/product/19.3.0/db_1/lib/libasmperl19.a -Wl,--no-whole-archive -lclntsh -lclntshcore -lasmclntsh19 -lhasgen19 -lskgxp19 -locr19 -lcell19 -lirc INFO: /usr/bin/ld:/home/app/oracle/product/19.3.0/db_1/li...

sqlora的专栏 9914

F5 GTM DNS 实战指南:智能DNS的监控与健康检查机制

本文深入解析F5 BIG-IP GTM智能DNS的核心机制,重点阐述其监控与探针两大功能如何协同工作。监控器负责深度检查服务器应用健康,确保服务可用性;探针则实时测量网络路径质量,实现基于延迟的智能流量调度。文章通过实战配置步骤,指导如何构建逻辑架构、建立iQuery通信、配置业务级健康检查及探针,从而构建高可用、高性能的全局负载均衡解决方案。

weixin_29240711的博客 469

西门子TP900精智系列触摸屏和三菱Q系列PLC以太网通信的组态步骤

西门子TP900精智系列触摸屏和三菱Q系列PLC以太网通信的组态步骤

Robot_PLC_HMI_Automation 6100

magic-api的鉴权机制配置 (附实战代码)

引入magic-api及相关数据库驱动依赖 配置yml文件和编辑器JS文件 实现登录鉴权逻辑,包括用户验证和Token处理 接口鉴权拦截器设计,确保接口访问安全性 文章提供了完整的代码示例,帮助开发者快速集成magic-api框架并实现权限控制功能。

码农研究僧的博客 227

Esp32蓝牙Hid调用方案 http执行设备、鼠标、键盘相关操作

本文主要介绍 Esp32 蓝牙 Hid 相关的多种操作方式,详细的设备、鼠标、键盘相关操作的 http 调用方法。下面是整理出的所有 http 调用方法和 rhino 引擎方式。本机调用的话直接使用http://localhost:8080 如果是局域网调用则使用软件里的地址 比如我的是http://192.168.1.5:8080。文件地址: https://www.123865.com/s/Qtm4jv-xyZbd?使用前需要一块烧录好的ESP32板子并在手机安装好embedded软件用于蓝牙通信。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 569

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

上一篇: 避开这些坑!用JavaScript给YOOC考试添加答案显示功能的正确姿势
下一篇: 自抗扰控制ADRC的5个工程陷阱:以一阶系统为例的避坑指南
lambda
博客等级 码龄23年 49粉丝 1303原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值