如何在JPQL中使用LIKE实现子字符串模糊查询

本文介绍在hibernate jpql中正确实现子字符串模糊匹配的方法,解决因误用concat导致的语法错误问题,通过like配合concat构造动态通配符查询。

在使用Hibernate进行JPQL查询时,若需根据部分名称(子字符串)检索实体,常见误区是直接将SQL风格的CONCAT函数与条件逻辑混用,例如错误地写成 where campo concat('%', :param, '%')——这在JPQL中语法不合法,因为concat只是字符串函数,不能单独作为谓词使用。

正确做法是结合LIKE操作符与concat函数,显式构建含通配符的匹配模式。LIKE是JPQL标准支持的模糊匹配关键字,必须搭配%(任意长度字符)或_(单个字符)通配符使用。而concat('%', :nome, '%')的作用是动态生成形如 %hospital% 的模式字符串,供LIKE进行匹配。

修正后的代码如下:

public List pesquisar(String nome) {
    TypedQuery query = manager.createQuery(
        "FROM UnidadeDeSaude WHERE nomeDoEstabelecimento LIKE CONCAT('%', :nomeDoEstabelecimento, '%')", 
        UnidadeDeSaude.class
    );
    query.setParameter("nomeDoEstabelecimento", nome); // ✅ 不要额外加 '%'!
    return query.getResultList();
}

⚠️ 关键注意事项:

  • CONCAT在JPQL中是标准函数(JPA 2.0+),但大小写

    不敏感
    ,建议统一用大写以提高可读性;
  • 参数值(如nome)应直接传入原始字符串(如 "Santa"),切勿手动拼接 '%' ——通配符已由CONCAT在JPQL层面处理;
  • 若需忽略大小写匹配,可改用 LOWER(nomeDoEstabelecimento) LIKE LOWER(CONCAT('%', :nome, '%'));
  • 替代方案:使用@NamedQuery或Spring Data JPA的派生查询(如 findByNomeDoEstabelecimentoContaining(String nome)),更简洁且类型安全。

总结:JPQL中子字符串搜索的核心是 LIKE + CONCAT 组合,而非模仿原生SQL的语法结构。掌握这一模式,既能保证跨数据库兼容性,又能避免运行时QuerySyntaxException异常。