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

内容分享20小时前发布 Lotte-F
0 7 0

#我的宝藏兴趣#

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

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

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

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

“小米,奇怪了,‘手机’两个字搜不到‘小米手机’,你帮忙看下?”

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

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

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

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

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

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

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

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

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

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

MyBatis 模糊查询的正确写法

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

方式一:用 CONCAT 拼接

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

这种方式等价于 SQL 中的:

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

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

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

列如在 Service 或 Controller 层这么写:

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

然后传给 mapper:

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

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

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

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

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

进阶拓展:MyBatis Plus 怎么搞?

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

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

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

MyBatis Plus 会自动帮你拼成:

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

就是这么贴心!

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

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

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

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

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

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

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

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

“啊,我都是 copy 之前的写法,还真没注意过原理……”

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

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

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

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

总结一下:

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

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

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

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

END

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

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

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

咱们下期见!

© 版权声明

相关文章

7 条评论

  • 头像
    四夕木羊 投稿者

    推荐一这种写法 你觉得对吗

    无记录
    回复
  • 头像
    佳音是个大仙女 投稿者

    应该改为instr函数才是王道!速度又快又不用拼接!

    无记录
    回复
  • 头像
    教育的典范 读者

    instr

    无记录
    回复
  • 头像
    笔记簿杏豆 读者

    bind 语法没用过吗?

    无记录
    回复
  • 头像
    二次元时光机 投稿者

    自从用了querydsl后,就再也没用过mybatis了

    无记录
    回复
  • 头像
    辣鼻小象 读者

    这都写错?再说本地开发不做测试吗

    无记录
    回复
  • 头像
    读者

    这是硬水了一篇文章

    无记录
    回复