如何使用CriteriaBuilder在自定义jsonb查询中排除指定JSON字段
实现方案
这个需求可以实现,核心是通过CriteriaBuilder提供的function()方法调用数据库原生的JSON操作函数,以下以你给出语法对应的PostgreSQL为例,其他数据库只需替换对应函数即可。
实现步骤
1. 基础查询初始化
首先构造Criteria查询的基础组件:
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); // 按需调整返回值类型,JSON结果可直接用String接收,也可对应数据库JSON类型调整 CriteriaQuery<String> query = cb.createQuery(String.class); Root<Table1Entity> root = query.from(Table1Entity.class);
2. 构造WHERE过滤条件
对应SQL中field_with_json->>a = 'someValue'的匹配逻辑:
// a字段匹配条件 Predicate aEqual = cb.equal( cb.function("jsonb_extract_path_text", String.class, root.get("fieldWithJson"), // 实体类对应table1.field_with_json的属性名 cb.literal("a") ), "someValue" ); // b字段匹配条件 Predicate bEqual = cb.equal( cb.function("jsonb_extract_path_text", String.class, root.get("fieldWithJson"), cb.literal("b") ), "someValue" ); query.where(aEqual, bEqual);
3. 实现JSON删键逻辑
对应SQL中field_with_json -c -d的删除指定键逻辑,有两种写法可选:
写法1:调用jsonb_remove函数(PostgreSQL 12+支持)
Expression<String> resultJson = cb.function( "jsonb_remove", String.class, root.get("fieldWithJson"), cb.literal(new String[]{"c", "d"}) // 要删除的键组成的数组 );
写法2:链式调用运算符(兼容旧版本PostgreSQL)
Expression<String> resultJson = cb.function("-", String.class, cb.function("-", String.class, root.get("fieldWithJson"), cb.literal("c") ), cb.literal("d") );
4. 执行查询
query.select(resultJson); List<String> queryResult = entityManager.createQuery(query).getResultList();
其他数据库适配说明
- MySQL:对应删除JSON键的函数为
JSON_REMOVE,参数的键路径需要写为$.c、$.d格式,替换函数名和参数即可。 - Oracle:对应函数为
JSON_REMOVE,用法和MySQL类似,路径格式一致。 - 注意实体类中JSON字段的类型要和函数返回值匹配,避免出现类型转换异常。
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

