mybatis like(手把手讲解)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
在现代软件开发中,数据库查询是应用程序的核心功能之一。当开发者需要实现模糊搜索功能时,SQL的LIKE
语句便成为高频使用的工具。MyBatis作为Java领域最受欢迎的持久层框架,通过灵活的SQL映射能力,为开发者提供了多种实现LIKE
查询的方式。本文将从基础概念出发,结合实际案例,深入解析如何在MyBatis中高效、安全地使用LIKE
操作,并探讨其背后的实现逻辑与优化技巧。
什么是 MyBatis 的 LIKE
查询?
在数据库查询中,LIKE
是一个用于模糊匹配的关键字,允许通过通配符(如 %
和 _
)进行模式匹配。例如,SELECT * FROM user WHERE name LIKE '%Tom%'
可以匹配所有包含 "Tom" 的用户名。
在 MyBatis 中,LIKE
的实现方式与标准 SQL 类似,但需要结合框架的参数绑定和动态 SQL 功能。其核心优势在于:
- 参数化查询:通过
#{}
占位符避免 SQL 注入风险; - 动态 SQL 支持:利用
<if>
、<choose>
等标签灵活构建查询条件; - 性能优化:结合索引和分页策略提升查询效率。
MyBatis LIKE
查询的基础用法
单条件模糊查询
最简单的场景是单字段模糊查询。例如,根据用户输入的关键词搜索文章标题:
<!-- Mapper XML 文件 -->
<select id="selectByTitleLike" resultType="Article">
SELECT * FROM article
WHERE title LIKE CONCAT('%', #{keyword}, '%')
</select>
在 Java 代码中调用时,只需传递 keyword
参数即可:
List<Article> articles = mapper.selectByTitleLike("Java");
多条件组合查询
当需要同时匹配多个字段时,可以使用 <if>
标签动态拼接条件:
<select id="searchArticles" resultType="Article">
SELECT * FROM article
WHERE 1=1
<if test="title != null">
AND title LIKE CONCAT('%', #{title}, '%')
</if>
<if test="author != null">
AND author LIKE CONCAT('%', #{author}, '%')
</if>
</select>
此方式通过 WHERE 1=1
简化条件拼接,避免了因条件为空导致的语法错误。
特殊场景与进阶技巧
通配符的灵活使用
LIKE
的通配符 %
和 _
分别表示匹配任意长度字符和单个字符。例如:
LIKE 'J%'
:匹配以 "J" 开头的字符串;LIKE '_a%'
:匹配第二个字符为 "a" 的字符串。
在 MyBatis 中,若参数本身包含通配符,需注意转义问题。例如,搜索包含 %
的内容时,可通过 ESCAPE
关键字指定转义字符:
SELECT * FROM product
WHERE name LIKE #{pattern} ESCAPE '\\'
Java 调用时传递参数 \\%Java\\%
,即可匹配包含 %Java%
的字符串。
动态通配符位置
在某些场景下,用户可能需要自定义通配符的位置(如仅前缀或后缀匹配)。此时可通过 <choose>
标签实现条件判断:
<select id="searchUsers" resultType="User">
SELECT * FROM user
WHERE username LIKE
<choose>
<when test="prefixOnly">
CONCAT('#{keyword}', '%')
</when>
<when test="suffixOnly">
CONCAT('%', #{keyword})
</when>
<otherwise>
CONCAT('%', #{keyword}, '%')
</otherwise>
</choose>
</select>
此案例中,通过 prefixOnly
和 suffixOnly
参数控制通配符位置,增强了查询的灵活性。
性能优化与注意事项
索引失效问题
LIKE
查询若以 %
开头(如 %Tom
),会导致数据库无法使用索引,从而引发全表扫描。例如:
-- 索引失效
WHERE name LIKE '%Tom%'
-- 索引有效
WHERE name LIKE 'Tom%'
为解决此问题,可考虑以下方案:
- 倒排索引:针对全文搜索场景,使用数据库的全文索引功能(如 MySQL 的
FULLTEXT
); - 预处理字段:将关键字段存储为倒序字符串,利用前缀匹配;
- 分页优化:通过
LIMIT
分页减少单次查询数据量。
SQL 注入防护
MyBatis 通过参数化查询(#{}
)天然防范 SQL 注入,但需注意以下场景:
- 直接拼接字符串时,如
#{keyword} + '%'
,可能引入风险; - 正确方式是使用
CONCAT
或||
运算符,例如:WHERE title LIKE CONCAT('%', #{keyword}, '%')
实例:分页模糊查询
以下案例演示如何结合分页和动态 LIKE
查询:
<!-- Mapper XML -->
<select id="searchWithPage" resultType="Product">
SELECT * FROM product
WHERE name LIKE CONCAT('%', #{keyword}, '%')
LIMIT #{offset}, #{pageSize}
</select>
Java 代码中传递分页参数:
Map<String, Object> params = new HashMap<>();
params.put("keyword", "camera");
params.put("offset", 0);
params.put("pageSize", 10);
List<Product> products = mapper.searchWithPage(params);
MyBatis LIKE
的最佳实践
- 避免过度模糊查询:减少
%
的使用频率,优先通过精确条件缩小数据范围; - 分批处理大数据集:对于海量数据,采用分页或流式查询;
- 日志与监控:启用 MyBatis 的查询日志(
log4j
或mybatis-spring-boot-starter
),监控慢查询; - 缓存策略:对高频且低变化率的模糊查询,可结合二级缓存或 Redis 缓存结果。
常见问题与解决方案
问题 1:查询结果为空但预期有数据
- 原因:参数值包含特殊字符未转义,或数据库字段值包含空格;
- 解决:使用
ESCAPE
转义或在参数前后添加空格处理。
问题 2:查询性能下降
- 原因:
LIKE
条件导致索引失效,或返回数据量过大; - 解决:优化查询条件,添加覆盖索引或拆分查询逻辑。
结论
MyBatis 的 LIKE
查询功能是开发者实现模糊搜索的核心工具,其灵活性与安全性需通过合理的设计与优化来保障。通过本文的讲解,读者可以掌握从基础语法到复杂场景的实现方法,并结合性能优化策略,为实际项目提供高效可靠的解决方案。在后续学习中,建议进一步探索 MyBatis 的动态 SQL 特性,以及数据库索引优化的深度知识,以提升整体开发能力。
关键词布局示例(注:实际文章中关键词自然融入,无需标注):
- mybatis like
- mybatis like 查询
- mybatis like 通配符
- mybatis like 性能优化
- mybatis like 分页
- mybatis like 参数绑定