使用 JPA 原生查询在 jsonb(JSON 数组)列中查询

Posted

技术标签:

【中文标题】使用 JPA 原生查询在 jsonb(JSON 数组)列中查询【英文标题】:Query in jsonb (JSON array) column with JPA native query 【发布时间】:2021-06-05 12:35:49 【问题描述】:

我正在使用 JPA,其中一个实体包含 user_details (jsonb) 列。

下面是我要查询的user_detailsjson数组数据。

[
    "user": "test1",
    "email": "test1@gmail.com"
,

    "user": "test2",
    "email": "test2@gmail.com"
]

postgres 客户端中,下面的查询运行良好。

SELECT * FROM table1 WHERE "user_details" @> '["email": "test1@gmail.com"]';

在@Repository 中我想通过本机查询实现相同的电子邮件值(test1@gmail.com)将是动态的。这是我的代码:

1. @Query(value ="select * from table1 WHERE user_details @> '[\"email\": :email]'", nativeQuery = true)
List<Entity> findByEmail(@Param("email") String email);

错误: json 类型的输入语法无效

详细信息:预期的 JSON 值,但找到“:”。

其中:JSON 数据,第 1 行:["email": :...

2. @Query(value ="select * from table1 WHERE user_details @> '[\"email\": ?1]'", nativeQuery = true)
List<Entity> findByEmail(String email);

错误: json 类型的输入语法无效

详细信息:令牌“?”无效。

其中:JSON 数据,第 1 行:["email": ?...

3. @Query(value ="select * from table1 WHERE user_details @> :param", nativeQuery = true)
List<Entity> findByEmail(@Param("param") String param); (i.e. param= "'[ \"email\" : \"test1@gmail.com\"]'")

错误: 运算符不存在:jsonb @> 字符变化

提示:没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换。

已编辑:

4. @Query(nativeQuery = true, value = "select * from table1 where jsonb_contains(user_details , :param )") (i.e. param= "'[ \"email\" : \"test1@gmail.com\"]'")
List<Entity> findByEmail(@Param("param") String email);

错误: 函数 jsonb_contains(jsonb, character varying) 不存在 提示:没有函数匹配给定的名称和参数类型。你可能 需要添加显式类型转换。

5. @Query(nativeQuery = true, value = "select * from table1 where user_details @> jsonb_build_object('email', :param )")
List<Entity> findByEmail(@Param("param") String email);

NO ERROR,但没有给出结果。

6. @Query(nativeQuery = true, value = "select * from table1 where user_details ->>'email' = :param")
List<Entity> findByEmail(@Param("param") String email);

NO ERROR,但没有给出结果。

7. @Query(nativeQuery = true, value = "select * from table1 WHERE jsonb_extract_path_text(user_details , 'email') = :param")
List<Entity> findByEmail(@Param("param") String email);

NO ERROR,但没有给出结果。

这些原生查询没有给我预期的结果。

请帮助我处理本机查询,我可以在其中将参数与查询绑定。 提前致谢。

【问题讨论】:

这个***.com/a/42906278/12854146可以帮助你吗? @tremendous7 感谢您的参考,但提供的解决方案不起作用。我已经更新了我尝试讨论的查询的描述(例如:4、5、6、7)。他们都没有工作。 您能确认 param/email 参数中没有错字吗?您能否报告一些没有结果且没有错误的查询的日志? @tremendous7 不,我已经交叉验证 param/email 参数中没有错字。查找以下日志,其中没有找到没有错误的结果。 5. Hibernate: select * from table1 where user_details @> jsonb_build_object('email', ? ) 6. Hibernate: SELECT * FROM table1 WHERE user_details ->>'email' = ? 7. 检测到线程不足或时钟跳跃(管家增量=25m34s579ms804µs400ns)。 Hibernate: select * from table1 WHERE jsonb_extract_path_text(user_details, 'email') = ? 【参考方案1】:

在调用这个函数之前,先创建一个jsonarray:

JSONObject obj = new JSONObject();
obj.put("email", email);
JSONArray a = new JSONArray();
a.add(0, obj);

通过传递jsonArray字符串调用函数

findByEmail(a.toJSONString());

您的查询应该是:

@Query(nativeQuery = true, value = "select * from table1 where user_details @> cast(:param as jsonb)")
List<Entity> findByEmail(@Param("param") String email);

【讨论】:

以上是关于使用 JPA 原生查询在 jsonb(JSON 数组)列中查询的主要内容,如果未能解决你的问题,请参考以下文章

jsonb字段上的Spring-Data-JPA本机查询

如何使用spring data jpa查询jsonb列?

如何根据postgres的jsonb列的where条件(无本机查询)使用jpa在spring boot中选择数据?

JPA 和 JSON 运算符本机更新查询

如何在 JPA 中编写动态 sql 查询以从 jsonb 列中查询数据?

如何在 JPA 中使用 Postgres JSONB 数据类型?