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 中只需几行代码即可实现,兼容性和精确性都能得到保证。

相关推荐
身如柳絮随风扬4 小时前
MySQL核心知识
数据库·mysql
551只玄猫5 小时前
【数据库原理 实验报告1】创建和管理数据库
数据库·sql·学习·mysql·课程设计·实验报告·数据库原理
q5431470875 小时前
MySQL SQL100道基础练习题
数据库·mysql
zhoupenghui1686 小时前
mysql 中如果条件where中有or,则要求or两边的字段都必须有索引,否则不能用到索引, 为什么?
数据库·mysql·索引
eggwyw7 小时前
完美解决phpstudy安装后mysql无法启动
数据库·mysql
java修仙传7 小时前
MySQL 事务隔离级别详解
数据库·mysql·oracle
Irissgwe7 小时前
MySQL存储过程和触发器专题
数据库·mysql·oracle
givemeacar10 小时前
Spring Boot中集成MyBatis操作数据库详细教程
数据库·spring boot·mybatis
skiy10 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
创世宇图10 小时前
Alibaba Cloud Linux 安装生产环境-mysql
linux·mysql