使用@Query注解执行查询时出现PSQLException: syntax error at or near "$1"问题
解决PSQLException: syntax error at or near "$1"问题
你的核心问题是把参数直接当成了完整SQL语句,而Spring Data JPA的@Query原生查询中,参数是用来填充SQL模板的占位符,不是直接替换整个查询语句。
错误原因
你当前的写法QUERY = "?1"会让PostgreSQL尝试执行参数值作为完整SQL,但参数本身(比如WHERE id=1)并不是合法的完整SQL语句,自然会触发语法错误。不管用?1还是$1,本质问题都没解决。
正确处理方式
根据你的filter用途分两种场景:
场景1:filter是WHERE子句的条件片段
如果filter是类似id > 10 AND status = 'ACTIVE'的条件,需要把基础SQL模板写完整,将参数作为条件部分传入:
// 替换成你的实际表名 String QUERY = "SELECT * FROM custom_data WHERE ?1"; @Query(value = QUERY, nativeQuery = true) List<CustomData> findAllByFilters(String filter);
⚠️ 注意:这种写法会把参数当成字符串处理,PostgreSQL不会解析为SQL条件,实际执行时会报错。更安全的方式是用动态查询API避免SQL注入:
比如用Spring Data JPA的Specification:
// Repository接口继承JpaSpecificationExecutor public interface CustomDataRepository extends JpaRepository<CustomData, Long>, JpaSpecificationExecutor<CustomData> {} // 业务层构建动态条件 public List<CustomData> findWithDynamicFilters() { Specification<CustomData> spec = (root, query, cb) -> { List<Predicate> predicates = new ArrayList<>(); predicates.add(cb.greaterThan(root.get("id"), 10)); predicates.add(cb.equal(root.get("status"), "ACTIVE")); return cb.and(predicates.toArray(new Predicate[0])); }; return customDataRepository.findAll(spec); }
场景2:filter是完整的SQL查询语句
如果filter是完整的SQL(比如SELECT * FROM custom_data WHERE id=1),不能用@Query的占位符,直接用EntityManager执行:
@Autowired EntityManager em; public List<CustomData> findAllByFilters(String filter) { Query query = em.createNativeQuery(filter, CustomData.class); return query.getResultList(); }
关键提醒
直接传递字符串参数拼接SQL会有严重的SQL注入风险,生产环境优先使用Specification、Querydsl等安全的动态查询方式,避免直接传入SQL片段。
内容的提问来源于stack exchange,提问作者Caroline
相关产品推荐
相关产品推荐

