Spring JPA原生查询中转义下划线实现精确匹配的方法
解决Spring JPA中LIKE查询下划线转义问题
你当前的问题出在JPQL的LIKE查询里:_是默认的通配符,会匹配任意单个字符,所以搜索John_X时会同时命中John_X和John-X(_匹配了-)。另外你的子查询存在笔误:upper(an.name) = upper(a.name)中的a是未定义别名,必须修正为e.name,否则会触发语法错误。
解决方案
1. 核心思路
通过ESCAPE关键字指定转义符,将参数中的_替换为转义后的\_,让LIKE把下划线当作普通字符匹配,同时修正子查询的别名错误。
2. 修正后的DAO层代码
@RestResource(path = "findLatestEmployeeByNameExactMatch", rel = "findLatestEmployeeByNameExactMatch") @Query(value = "select e from Employee e " + " WHERE :name IS NULL OR upper(e.name) LIKE upper(:nameEscaped) ESCAPE '\\' " + " AND e.latestProject = (select MAX(an.latestProject) from Employee an where upper(an.name) = upper(e.name))") Employee findEmployeeByName(@Param("name") String name, @Param("nameEscaped") String nameEscaped);
3. 调用时处理参数
在调用该方法前,手动将传入的name中的_替换为\_:
// 处理参数,转义下划线 String escapedName = name != null ? name.replace("_", "\\_") : null; // 调用查询方法 Employee targetEmployee = employeeRepository.findEmployeeByName(name, escapedName);
可选:原生SQL实现(如果偏好原生语法)
如果更习惯用原生SQL,逻辑一致,注意适配数据库的转义规则(多数数据库支持\作为转义符):
@Query(value = "SELECT * FROM employee e " + " WHERE :name IS NULL OR UPPER(e.name) LIKE UPPER(:nameEscaped) ESCAPE '\\' " + " AND e.latest_project = (SELECT MAX(an.latest_project) FROM employee an WHERE UPPER(an.name) = UPPER(e.name))", nativeQuery = true) Employee findEmployeeByNameNative(@Param("name") String name, @Param("nameEscaped") String nameEscaped);
验证效果
当传入John_X时,转义后的参数为John\_X,LIKE会精确匹配下划线字符,最终只会返回John_X 124这条记录,不会再命中John-X的数据。
内容的提问来源于stack exchange,提问作者user09
相关产品推荐
相关产品推荐

