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

Spring Boot中如何执行PostgreSQL JSONB操作符的原生查询?

解决Spring Boot中PostgreSQL JSONB操作符与参数占位符冲突的问题

问题背景

我们有一个遗留数据库的jsonb类型列,可同时存储数组和JSON数据:

items
-------
["elem1","elem2"]

["elem3","elem4"]

{"elem31": ["src1", "src2", "src3"], "elem100": ["src5"]}

{"elem21": ["src1", "src2"]}

在psql控制台中可以用?(单元素匹配)和?|(多元素任一匹配)操作符查询,但在Spring Boot原生查询中直接使用这些操作符会和参数占位符?冲突,报错java.lang.IllegalArgumentException: Mixing of ? parameters and other forms like ?1 is not supported,转义??或\?也无效。

解决方案:使用PostgreSQL内置JSONB函数替代操作符

PostgreSQL为这些JSONB操作符提供了对应的内置函数,完全可以替代操作符功能,同时避免与Spring的参数占位符冲突:

1. 单元素匹配(替代?操作符)

使用jsonb_exists(jsonb_column, text)函数,对应原查询item ? 'elem21':

@Query("select * from tbl1 where jsonb_exists(item, :elem)", nativeQuery = true)
List<Object[]> findBySingleElement(@Param("elem") String element);

// 位置参数写法
@Query("select * from tbl1 where jsonb_exists(item, ?1)", nativeQuery = true)
List<Object[]> findBySingleElement(String element);

2. 多元素任一匹配(替代?|操作符)

使用jsonb_exists_any(jsonb_column, text[])函数,对应原查询item ?| '{elem21,elem1}':

@Query("select * from tbl1 where jsonb_exists_any(item, array(:elems))", nativeQuery = true)
List<Object[]> findByAnyElement(@Param("elems") String[] elements);

// 位置参数写法
@Query("select * from tbl1 where jsonb_exists_any(item, array(?1))", nativeQuery = true)
List<Object[]> findByAnyElement(String[] elements);

原理说明

Spring Data JPA会将SQL语句中的?识别为参数占位符,而PostgreSQL的?、?|是JSONB操作符,两者语法冲突导致报错。使用对应的内置函数后,SQL中不再出现作为操作符的?,彻底避免了冲突问题,同时功能完全等价于原操作符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:07:42