Spring Boot JPA:如何查询表中的 JSON 列

Posted

技术标签:

【中文标题】Spring Boot JPA:如何查询表中的 JSON 列【英文标题】:Spring Boot JPA: how do query a JSON column in a table 【发布时间】:2017-10-10 13:19:57 【问题描述】:

我有一张表casemessage 并有以下列。我正在尝试使用Spring Framework JPA 搜索/查询JSON 列..

    身份证 created_by created_utc from_id 留言 状态 case_id

这里的status 列存储JSON 字符串的列表。例如:

 1. ["user_id": 1, "status": "sent", "user_id": 2, "status": "delete"]
 2. ["user_id": 3, "status": "delete", "user_id": 2, "status": "sent","user_id": 1, "status": "received"]
 3. ["user_id": 1, "status": "received", "user_id": 2, "status": "sent"]
 4. ["user_id": 1, "status": "delete", "user_id": 3, "status": "sent"]

我正在尝试查询casemessage 表以获取user_id1status 不是delete 的所有行

使用mysql 查询,我能够查询表并返回预期结果。

这是我尝试过的查询:

 select * from casemessage  where case_Id=1 and id not in(select id from cwot.casemessage where json_contains(status, '"status" :"delete"') and json_contains(status, '"user_id" : 1'));

当我使用Spring Framework JPA (Spring Boot) 尝试此操作时,运行应用程序时出现异常。这是我绑定的声明:

    @Query("select c from CaseMessage c  where c.caseId=?1 and c.id not in(select cm.id from CaseMessage cm where json_contains(status, '\"status\": \"delete\"') and json_contains(status, '\"user_id\": ?2'))")
    List<CaseMessageResponse> getAllCaseMessages(long caseId, long userId);

我得到的错误是:

 Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: ( near line 1, column 172 [select c from com.cwot.domain.CaseMessage c  where c.caseId=?1 and c.id not in(select cm.id from com.cwot.domain.CaseMessage cm where json_contains(status, '"status": "delete"') and json_contains(status, '"user_id": ?1'))]

有人可以帮我解决这个问题吗?

非常感谢任何帮助。

【问题讨论】:

check if a value exists in json encode array in mysql的可能重复 @e4c5,我在看 JPA 的观点。我的查询在 MySQL 中工作 这没有任何区别。这是不适合 JSON 的情况 我有一个疑问。如果我需要检查是否有任何称为状态的键,那么如何检查呢? 【参考方案1】:

您必须使用原生查询才能使用 json_contains 等数据库函数:

@Query("select c from CaseMessage c  where c.caseId=?1 and c.id not in(select cm.id from CaseMessage cm where json_contains(status, '\"status\": \"delete\"') and json_contains(status, '\"user_id\": ?2'))", nativeQuery = true)
    List<CaseMessageResponse> getAllCaseMessages(long caseId, long userId);

或使用@NativeQuery 注释

更多信息:

Difference between query, native query, named query and typed query

【讨论】:

当我使用这个语句运行时,我得到一个错误,说org.springframework.dao.InvalidDataAccessApiUsageException: Parameter with that position [2] did not exist; nested exception is java.lang.IllegalArgumentException: Parameter with that position [2] did not exist 你必须修改你的查询,它必须成为一个原生的 不想使用原生查询怎么办?有什么解决办法吗?

以上是关于Spring Boot JPA:如何查询表中的 JSON 列的主要内容,如果未能解决你的问题,请参考以下文章

java - 如何在spring boot java中编写一个函数来处理JPA存储库中的自定义查询?

如何通过 Spring Boot JPA 执行具有 INTERVAL 子句的本机 SQL 查询?

Spring Boot REST/JPA 服务中的不相等查询

Spring Boot JPA中的自定义查询问题

spring boot系列spring boot 配置spring data jpa (查询方法)

如何在 Spring Boot 中从应用程序属性文件中读取 jpa 命名查询?