Spring JPA Repository查询含单引号字符串无结果的解决方法
这个问题我之前也碰到过,本质是单引号在SQL语法里的特殊作用导致的解析错误——直接传入"O'Reilly"时,生成的SQL会变成SELECT * FROM users WHERE name = 'O'Reilly',数据库会把第一个单引号后的O当作字符串,后面的Reilly'就成了语法错误,自然查不到数据。下面给你几个可行的解决办法:
方法1:用Spring Data JPA的参数绑定(最推荐)
Spring Data JPA本身就支持自动处理参数的转义,只要你正确使用参数绑定,不管是方法名派生查询还是@Query注解都可以:
如果你的Repository方法是这样定义的:
public interface UserRepository extends JpaRepository<User, Long> { User findFirstByName(String name); }
那直接调用userRepository.findFirstByName("O'Reilly")就应该能查到数据——Spring会自动把单引号转成SQL要求的两个单引号,生成正确的查询语句SELECT * FROM users WHERE name = 'O''Reilly'。
要是你用了@Query注解,一定要用参数占位符而不是手动拼接字符串:
@Query("SELECT u FROM User u WHERE u.name = :name") User findFirstByName(@Param("name") String name);
这种方式完全不需要你操心转义,Spring会帮你搞定。
方法2:手动转义单引号(仅特殊场景用)
如果因为某些限制不能用参数绑定,那可以手动把字符串里的单引号替换成两个单引号:
String escapedName = "O'Reilly".replace("'", "''"); User user = userRepository.findFirstByName(escapedName);
不过这种方式不推荐,一来容易漏处理其他特殊字符,二来维护起来麻烦,能不用就不用。
方法3:先排查数据库数据本身的问题
顺便确认下Postgres里的users表中,O'Reilly这条数据是不是真的存的是O'Reilly——有没有可能输入时多了空格、或者单引号是全角的?你可以直接在数据库里执行这条SQL测试:
SELECT * FROM users WHERE name = 'O''Reilly';
如果这条SQL能查到数据,那问题肯定出在代码的参数处理上,回到方法1就能解决。
Spring 1.5.6虽然是比较老的版本,但参数绑定的核心功能是完善的,优先用方法1就没问题啦!
内容的提问来源于stack exchange,提问作者Joseph Mtinangi

