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 功能。其核心优势在于:

  1. 参数化查询:通过 #{} 占位符避免 SQL 注入风险;
  2. 动态 SQL 支持:利用 <if><choose> 等标签灵活构建查询条件;
  3. 性能优化:结合索引和分页策略提升查询效率。

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>  

此案例中,通过 prefixOnlysuffixOnly 参数控制通配符位置,增强了查询的灵活性。


性能优化与注意事项

索引失效问题

LIKE 查询若以 % 开头(如 %Tom),会导致数据库无法使用索引,从而引发全表扫描。例如:

-- 索引失效  
WHERE name LIKE '%Tom%'  

-- 索引有效  
WHERE name LIKE 'Tom%'  

为解决此问题,可考虑以下方案:

  1. 倒排索引:针对全文搜索场景,使用数据库的全文索引功能(如 MySQL 的 FULLTEXT);
  2. 预处理字段:将关键字段存储为倒序字符串,利用前缀匹配;
  3. 分页优化:通过 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 的最佳实践

  1. 避免过度模糊查询:减少 % 的使用频率,优先通过精确条件缩小数据范围;
  2. 分批处理大数据集:对于海量数据,采用分页或流式查询;
  3. 日志与监控:启用 MyBatis 的查询日志(log4jmybatis-spring-boot-starter),监控慢查询;
  4. 缓存策略:对高频且低变化率的模糊查询,可结合二级缓存或 Redis 缓存结果。

常见问题与解决方案

问题 1:查询结果为空但预期有数据

  • 原因:参数值包含特殊字符未转义,或数据库字段值包含空格;
  • 解决:使用 ESCAPE 转义或在参数前后添加空格处理。

问题 2:查询性能下降

  • 原因LIKE 条件导致索引失效,或返回数据量过大;
  • 解决:优化查询条件,添加覆盖索引或拆分查询逻辑。

结论

MyBatis 的 LIKE 查询功能是开发者实现模糊搜索的核心工具,其灵活性与安全性需通过合理的设计与优化来保障。通过本文的讲解,读者可以掌握从基础语法到复杂场景的实现方法,并结合性能优化策略,为实际项目提供高效可靠的解决方案。在后续学习中,建议进一步探索 MyBatis 的动态 SQL 特性,以及数据库索引优化的深度知识,以提升整体开发能力。


关键词布局示例(注:实际文章中关键词自然融入,无需标注):

  • mybatis like
  • mybatis like 查询
  • mybatis like 通配符
  • mybatis like 性能优化
  • mybatis like 分页
  • mybatis like 参数绑定

最新发布