使用JPA标准的CriteriaBuilder,为Postgres的jsonb列构建谓词。

7

我需要为一个JSONB列添加谓词到我的现有谓词列表中。

实体:

@Entity
@Table(name = "a")
@TypeDefs({
        @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class),
})
public class EntityA {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "a_id_seq")
    @SequenceGenerator(sequenceName = "a_id_seq", allocationSize = 1, name = "a_id_seq")
    @Column(name = "id")
    private long id;

    @Column(name = "name")
    private String name;

    @Column(name = "json")
    @Type(type = "jsonb")
    private Json json;

    private static class Json {
        private String name;

        private Integer number;

        private String random;
    }
}

规格:

    public Specification<EntityA> buildSpecification(Filter filter){

            return (root, query, cb) -> {
                        List<Predicate> predicates = new ArrayList<>();


            Expression<String> nameExpression = root.get("name");

        Predicate namePredicate = nameExpression.in(filter.getNames());
                            predicates.add(namePredicate);

//TODO add a predicate for JSONB here


                        return cb.and(predicates.toArray(new Predicate[0]));
                    };

我的输入将是一个 List jsonNames 或 List jsonNumbers,我想用这个输入构建 CriteriaBuilder.In,并获取任何匹配项。

筛选条件:

@Data
public class Filter {
    private List<String> names;

    private List<String> jsonNames;

    private List<Integer> jsonNumbers;
}
1个回答

10

对于PostgreSQL

Predicate inJsonNumbers = cb
        .function("jsonb_extract_path_text", 
                String.class, 
                root.get("json"), 
                cb.literal("number"))
        .in(filter.getJsonNumbers())

Predicate inJsonNames = cb
        .function("jsonb_extract_path_text", 
                String.class, 
                root.get("json"), 
                cb.literal("name"))
        .in(filter.getJsonNames())

另外,是否可能将两个条件合并为一个谓词?我添加了第三个字段“随机”,但我只需要将“名称”和“数字”匹配为一个谓词。 - Niv
@nikolay-shevchenko 你有什么想法可以让这个适用于 int / Integer 字段吗? - Niv
@Niv,不行。我不能检查。也许这个链接会有帮助 https://dev59.com/WmDVa4cB1Zd3GeqPgLkN - Nikolai Shevchenko
Shevchenko,你有没有想法如何使用布尔对象使其工作? - Niv
3
@NikolaiShevchenko 如何使其适用于数组对象。我想从嵌套的JSON中获取JSON数组中的字段。是否有任何方法或函数可以实现这一点? - Arbaz Sheikh
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接