MyBatis 精确查询逗号分隔字符串

MyBatis实战:如何精确查询逗号分隔字符串中的目标值?

在日常开发中,我们经常会遇到这样的场景:数据库某个字段存储的是逗号分隔的字符串(比如 "44,4401""4401,44"),需要精确查询包含某个独立值(比如 "44")的记录。

如果直接用 LIKE '%44%',很容易误匹配到 "4401""144" 这类包含 "44" 但并非目标值的情况。今天就来分享一种在 MyBatis 中高效解决这个问题的方案。

问题场景再现

假设数据库表 t_code 中有一个字段 codes,存储的值可能是:

  • "44,4401"(44 和 4401 两个值)
  • "4401,44"(4401 和 44 两个值)
  • "44"(单独的 44)
  • "4401"(不含 44,仅 4401)

现在需要查询所有 codes包含独立的 "44" 的记录,预期结果是前三种情况,而 "4401" 不应被匹配。

为什么普通 LIKE 不行?

如果直接写:

sql 复制代码
SELECT * FROM t_code WHERE codes LIKE '%44%'

此时 "4401" 会被误匹配(因为字符串中包含 "44"),不符合「精确查询独立值」的需求。

核心解决方案:用逗号"包裹"目标值

关键思路是:让目标值和字段中的每个子项都处于相同的"逗号包围"状态,再进行匹配。

具体操作:

  1. 给数据库字段 codes 前后各拼接一个逗号,变成 ",原字符串,"(比如 "44,4401" 变成 ",44,4401,");
  2. 给目标值前后也各拼接一个逗号,变成 ",目标值,"(比如 "44" 变成 ",44,");
  3. LIKE 判断拼接后的字段是否包含拼接后的目标值。

这样就能确保只匹配独立的子项,不会误判包含目标值的其他字符串。

MyBatis 代码实现

1. Mapper.xml 编写 SQL

在 Mapper.xml 中,通过 CONCAT 函数完成拼接,SQL 如下:

xml 复制代码
<select id="selectByTargetCode" resultType="com.example.entity.CodeEntity">
    SELECT * FROM t_code
    WHERE 
        -- 字段前后加逗号,目标值前后加逗号,确保精确匹配独立项
        CONCAT(',', codes, ',') LIKE CONCAT('%,', #{targetCode}, ',%')
</select>
  • CONCAT(',', codes, ','):给字段值前后加逗号(处理边界情况,比如值在开头或结尾);
  • CONCAT('%,', #{targetCode}, ',%'):给目标值前后加逗号,并用 % 匹配任意位置。

2. Mapper 接口定义

对应的 Mapper 接口需要接收目标值参数:

java 复制代码
public interface CodeMapper {
    /**
     * 精确查询包含目标值的记录
     * @param targetCode 目标值(如"44")
     * @return 匹配的记录列表
     */
    List<CodeEntity> selectByTargetCode(@Param("targetCode") String targetCode);
}

3. 效果验证

数据库 codes 拼接后的值 目标值"44"拼接后 是否匹配 结果是否符合预期
"44,4401" ",44,4401," ",44," 符合
"4401,44" ",4401,44," ",44," 符合
"44" ",44," ",44," 符合
"4401" ",4401," ",44," 符合

方案优势

  1. 精确性:彻底避免误匹配(如"4401"不会被当作"44"查询出来);
  2. 通用性 :适用于任何数据库(CONCATLIKE 是 SQL 标准函数);
  3. 简洁性:无需复杂逻辑,一行 SQL 即可解决问题;
  4. 兼容性:无论目标值在字符串的开头、中间还是结尾,都能正确匹配。

注意事项

  • 如果字段可能为 NULL,建议先处理空值(比如 CONCAT(',', IFNULL(codes, ''), ','));
  • 若数据量极大,这种方式可能影响查询性能(因为 CONCAT 会使索引失效),此时建议考虑拆分字段为关联表(更符合数据库设计规范)。

总结

当需要在逗号分隔的字符串中精确查询独立值时,通过「前后拼接逗号 + LIKE 匹配」的方式,能简单高效地解决问题。这种方案在 MyBatis 中只需几行代码即可实现,兼容性和精确性都能得到保证。

相关推荐
heze0914 分钟前
sqli-labs-Less-16自动化注入方法
mysql·网络安全·自动化
程序员侠客行31 分钟前
Mybatis插件原理及分页插件
java·后端·架构·mybatis
开开心心就好32 分钟前
内存清理工具点击清理,自动间隔自启
linux·运维·服务器·安全·硬件架构·材料工程·1024程序员节
小冷coding9 小时前
【MySQL】MySQL 插入一条数据的完整流程(InnoDB 引擎)
数据库·mysql
周杰伦的稻香12 小时前
MySQL中常见的慢查询与优化
android·数据库·mysql
·云扬·14 小时前
MySQL 常见存储引擎详解及面试高频考点
数据库·mysql·面试
何以不说话15 小时前
mysql 的主从复制
运维·数据库·学习·mysql
橘子1316 小时前
MySQL库的操作(二)
数据库·mysql·oracle
·云扬·17 小时前
MySQL各版本核心特性演进与主流分支深度解析
数据库·sql·mysql
田超凡18 小时前
深入理解MySQL_6 Temporary临时表
mysql·java-ee