90% 的人 MyBatis 模糊查询都写错了!你中招了吗?



大家好,我是小米,一枚31岁的技术小太阳,从业多年,见惯了代码里那些"表面无害,实则藏雷"的小细节。今天就给大家分享一个很多人在 MyBatis 模糊查询 中会踩的坑,也是我上周面试候选人时提问的一道经典问题。

故事,从一个"奇怪"的Bug说起

前不久我们团队在做商品管理后台系统改造,有个老同事灰常熟练地提交了一个 PR,功能是"模糊搜索商品名称"。需求很简单,比如输入"手机",就能匹配"苹果手机""小米手机""华为手机壳"这种。

很快,他写完代码,提测上线。我心里想着,这种 CRUD 小功能还能出啥岔子?结果当天晚上就接到了 QA 的反馈电话:

"小米,奇怪了,'手机'两个字搜不到'小米手机',你帮忙看下?"

我心里咯噔一下,立马连夜打开了代码。

看似没毛病的代码,却查不出来?

点开 mapper.xml,一行熟悉的 SQL 出现在眼前:

你是不是也觉得没毛病?我当年刚学 MyBatis 时也会这么写。但问题就出在这个 '%#{name}%' 上。你以为这会拼成 '%手机%',实际上拼成了什么呢?

我们打印了真实的 SQL 日志,一看------直接傻眼了:

问号代表的是预编译参数,结果数据库收到的命令是:

它根本不是你想象的 name LIKE '%手机%'。怪不得查不出来!

MyBatis 模糊查询的正确写法

有两种正确方式,我总结给你

方式一:用 CONCAT 拼接

这种方式等价于 SQL 中的:

优点:占位符保持预编译优势,不容易被 SQL 注入,性能更安全。

方式二:Java 代码中拼接 %,传入参数

比如在 Service 或 Controller 层这么写:

然后传给 mapper:

这种方式也能成功模糊查询,但缺点是:你在 Java 层拼接了字符串,如果多个字段都要模糊匹配,拼接过程容易出错,还可能有注入风险。

所以到底选哪种方式更推荐?

我个人强烈建议:使用第一种 CONCAT 拼接的方式

不仅写法清晰、安全,而且在后期调试 SQL 时更容易定位问题。不信你问问 DBA 们,哪个更好维护?他们一定告诉你,SQL 的参数尽量保持预编译形式。

进阶拓展:MyBatis Plus 怎么搞?

我知道你肯定在用 MyBatis Plus,那我们再说说用 MP 的方式怎么写模糊查询。

方法一:使用 like 条件构造器

MyBatis Plus 会自动帮你拼成:

就是这么贴心!

方法二:使用 Lambda 表达式(更优雅)

不仅 IDE 自动补全字段名,不怕写错,而且性能更佳,更利于代码重构。

踩坑合集:这些写法别再用了!

下面是一些常见错误示例,小米帮你挨个拆雷:

面试官视角:我为什么喜欢问这个问题?

这个问题看似简单,其实能体现很多候选人是否"脚踏实地做过项目"。我最常听到的回答是:

"啊,我都是 copy 之前的写法,还真没注意过原理......"

但如果一个候选人告诉我:

"我知道不能直接用 %#{name}%,我一般用 CONCAT,或者在 Java 里拼接 %,不过我更推荐在 SQL 层处理。"

那我心里直接给他加 20 分!

小结:一口气掌握模糊查询的正确姿势

总结一下:

  • 不推荐: '%#{param}%'
  • 推荐一: LIKE CONCAT('%', #{param}, '%')
  • 推荐二: Java 拼接 %param% 再传参
  • 更推荐: MyBatis Plus 的 .like() 和 .lambdaQuery()
  • 注意 SQL 注入、防止错误转义

聊点题外话:写业务代码也能体现技术深度

很多人觉得做业务代码没技术含量,其实不是的,像模糊查询这种小细节背后就隐藏着对预编译、安全性、SQL 执行效率的理解。

一个优秀的工程师,不在于能不能写出"很炫的算法",而在于能不能把每一个 "简单"的功能做到极致

END

如果你也曾因为模糊查询写错被批评、被查 Bug 查到秃头,不要自责,踩坑是成长最快的方式!

这篇文章,如果对你有帮助,欢迎点个 "在看""转发给你的队友" ------别让他也踩坑啦~

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号"软件求生",获取更多技术干货!

咱们下期见!

相关推荐
磊叔的技术博客13 分钟前
LLM 系列(四):神奇的魔法数 27
后端·llm
星沁城18 分钟前
149. 直线上最多的点数
java·算法·leetcode
_一条咸鱼_1 小时前
Android Gson基础数据类型转换逻辑(6)
android·面试·gson
前端付豪1 小时前
美团 Flink 实时路况计算平台全链路架构揭秘
前端·后端·架构
MikeWe1 小时前
理解深度学习框架计算图的动态图与静态图:机制、实现与应用
后端
sincere_iu1 小时前
#前端重铸之路 Day7 🔥🔥🔥🔥🔥🔥🔥🔥
前端·面试
Android洋芋1 小时前
从零到一构建企业级TTS工具:实战指南与优化策略
后端
chanalbert1 小时前
AI大模型提示词工程研究报告:长度与效果的辩证分析
前端·后端·ai编程
Android洋芋1 小时前
深度解析Android音频焦点处理与实战开发:从无声问题到企业级解决方案
后端
_一条咸鱼_1 小时前
Android Runtime并发标记与三色标记法实现原理(55)
android·面试·android jetpack