You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring JPA中ESCAPE关键字不识别启动报错问题排查

解决Spring Boot中@Query模糊查询的%转义与ESCAPE关键字异常问题

问题分析

启动时抛出antlr.NoViableAltException、提示unexpected token: ESCAPE,是因为Spring Data JPA的JPQL解析器不支持当前的ESCAPE用法;而之前%被转义导致无匹配结果,是因为参数中的%被当作普通字符串处理,没有作为模糊查询的通配符生效。另外你对ESCAPE的功能理解有误——它不是用来阻止%转义的,而是用来匹配字面量的%或_的。

解决方案

方案1:固定前后模糊匹配(服务层无需传%)

如果需求是固定的前后通配符查询,直接在JPQL里用CONCAT拼接%,避免参数带%导致转义:

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
    @Query("SELECT p FROM Post p WHERE p.title LIKE CONCAT('%', :keyword, '%')")
    List<Post> findByTitleContaining(@Param("keyword") String keyword);
}

调用时只需传入关键词(比如"test"),JPQL会自动拼接前后%,此时SQL输出的%是静态部分,不会被转义,能正常作为通配符使用。

方案2:灵活传入通配符(支持自定义%、_位置)

如果需要服务层自由控制通配符位置(比如传"test%"或"%test"),可以用以下两种方式:

方式A:使用原生SQL

直接写原生SQL,绕过JPQL的参数转义逻辑:

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
    @Query(value = "SELECT * FROM post WHERE title LIKE ?1", nativeQuery = true)
    List<Post> findByTitleLike(String keyword);
}

调用时直接传入带通配符的参数(比如"%test%"),原生SQL会直接识别参数中的%作为通配符。

方式B:JPQL中使用SpEL表达式

利用Spring Data JPA的SpEL支持,直接将参数作为原始字符串传入JPQL:

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
    @Query("SELECT p FROM Post p WHERE p.title LIKE :#{#keyword}")
    List<Post> findByTitleLike(@Param("keyword") String keyword);
}

这种方式会跳过JPQL对参数的转义处理,参数中的%会直接作为通配符生效。

正确使用ESCAPE的场景

ESCAPE是用来处理**需要匹配字面量%或_**的场景,比如要查询标题中包含"5%"的内容:

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
    @Query("SELECT p FROM Post p WHERE p.title LIKE :keyword ESCAPE '\\'")
    List<Post> findByTitleWithPercent(@Param("keyword") String keyword);
}

调用时传入参数"%5\%%"——这里的\是指定的转义字符,告诉JPA第二个%是字面量,不是通配符。

内容的提问来源于stack exchange,提问作者Baba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 23:42:35