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

使用@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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:33:33