如何解决如何为JSONB列构建JPA谓词?
我在Postgres中有一个JSONB列,我想根据存储在JSON中的键值对过滤数据。 我目前正在使用Spring Data JPA,并且想使用谓词动态触发SQL查询。
SELECT car0_.model_name,car0_.year_of_manufacture,car0_.properties
FROM public.car AS car0_
WHERE car0_.year_of_manufacture < 2010
AND car0_.properties ->> 'country_of_manufacture'='US';
但是我不希望使用本机查询,因为它违反了使用ORM的目的。
此外,我必须动态构建查询,而不要使用静态查询,以便用户可以基于JSON中的任何键值对进行搜索。
解决方法
此答案适用于Hibernate 5.0到6.0。
首先,您需要打开psql并找出运算符->>
与使用\doS+ ->>
对应的功能。在这种情况下,jsonb_object_field_text
会达到您想要的条件jsonb_object_field_text(car0_.properties,'country_of_manufacture') = 'US'
。
现在,您需要在Hibernate中注册该功能才能在JPQL中使用它。为此,您必须在您的软件包为MetadataBuilderInitializer
的情况下实现com.mysite.util
。
package com.mysite.util;
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.spi.MetadataBuilderInitializer;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.StringType;
public class SQLFunctionContributor implements MetadataBuilderInitializer {
@Override
public void contribute(MetadataBuilder metadataBuilder,StandardServiceRegistry serviceRegistry) {
metadataBuilder.applySqlFunction("jsonb_object_field_text",new StandardSQLFunction("jsonb_object_field_text",StringType.INSTANCE));
}
}
最后一步是使用以下路径在资源文件夹中创建一个文本文件:
META-INF/services/org.hibernate.boot.spi.MetadataBuilderInitializer
文件必须包含新类的合格类名:
com.mysite.util.SQLFunctionContributor
现在,您可以像下面这样在JPQL中使用该功能:
SELECT c FROM Car c WHERE c.yearOfManufacture < :year AND FUNCTION('jsonb_object_field_text',c.properties,'country_of_manufacture') = :cc
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。