如何将PSQL::json @>::json转换为jpa/jpql predicate

chhqkbe1  于 2023-02-16  发布在  其他
关注(0)|答案(2)|浏览(97)

假设我有一个如下所示的db-table:

CREATE TABLE myTable(
   id BIGINT, 
   date TIMESTAMP, 
   user_ids JSONB 
);

user_ids是一个
让此表的记录如下所示:

{
     "id":13,
     "date":"2019-01-25 11:03:57",
     "user_ids":[25, 661, 88]
};

我需要查询user_ids包含25的所有记录。在SQL中,我可以使用以下select语句实现这一点:

SELECT * FROM myTable where user_ids::jsonb @> '[25]'::jsonb;

现在我需要编写一个JPA predicate ,将"user_ids::jsonb @> '[25]'::jsonb"呈现为一个Hibernate可解析/可执行条件,然后我打算在session.createQuery()语句中使用它。简单地说,我需要知道如何将PSQL片段(user_ids::jsonb @> '[25]'::jsonb)编写为HQL表达式。

6jjcrrmo

6jjcrrmo1#

幸运的是,PostgreSQL中的每个比较运算符都只是函数的别名,您可以通过psql控制台键入\doS+和运算符来查找别名(尽管在此搜索中某些运算符被视为通配符,因此它们给出的结果比预期的要多)。
结果如下:

postgres=# \doS+ @>
                                          List of operators
   Schema   | Name | Left arg type | Right arg type | Result type |      Function       | Description 
------------+------+---------------+----------------+-------------+---------------------+-------------
 pg_catalog | @>   | aclitem[]     | aclitem        | boolean     | aclcontains         | contains
 pg_catalog | @>   | anyarray      | anyarray       | boolean     | arraycontains       | contains
 pg_catalog | @>   | anyrange      | anyelement     | boolean     | range_contains_elem | contains
 pg_catalog | @>   | anyrange      | anyrange       | boolean     | range_contains      | contains
 pg_catalog | @>   | box           | box            | boolean     | box_contain         | contains
 pg_catalog | @>   | box           | point          | boolean     | box_contain_pt      | contains
 pg_catalog | @>   | circle        | circle         | boolean     | circle_contain      | contains
 pg_catalog | @>   | circle        | point          | boolean     | circle_contain_pt   | contains
 pg_catalog | @>   | jsonb         | jsonb          | boolean     | jsonb_contains      | contains
 pg_catalog | @>   | path          | point          | boolean     | path_contain_pt     | contains
 pg_catalog | @>   | polygon       | point          | boolean     | poly_contain_pt     | contains
 pg_catalog | @>   | polygon       | polygon        | boolean     | poly_contain        | contains
 pg_catalog | @>   | tsquery       | tsquery        | boolean     | tsq_mcontains       | contains
(13 rows)

你需要的是两边都有jsonb参数,我们看到这个函数叫做jsonb_contains。所以jsonbcolumn @> jsonbvalue的等价物是jsonb_contains(jsonbcolumn, jsonbvalue)。现在你不能在JPQL或CriteriaBuilder中使用这个函数,除非你在使用Hibernate的时候通过一个定制的Dialect注册它。如果你在使用EclipseLink,我不知道那里的情况。
从这里开始,您可以选择使用本地查询,或者通过扩展现有的Hibernate方言来添加自己的Hibernate方言。

lsmepo6l

lsmepo6l2#

将“@〉”替换为“jsonb_contains()”不是一个好主意。运算符被索引,而不是函数。示例:https://dbfiddle.uk/-xMuHYAA

相关问题