我有带jsonb字段的Postgres数据库。我在JPA中使用了条件构建器的条件列表的谓词列表。现在,我想基于多个原因和JSON来获取存储在数据库中的JSON数据。怎么可能呢?
private List<Predicate> whereClause(CriteriaBuilder criteriaBuilder, Root<KafkaLog> kafkaLog,
KafkaLogSearchDto search) {
List<Predicate> predicates = new ArrayList<>();
if (search.getTopic() != null && !search.getTopic().isEmpty()) {
Expression<String> literal =
criteriaBuilder.literal("%" + search.getTopic().toUpperCase() + "%");
predicates.add(criteriaBuilder.like(criteriaBuilder.upper(kafkaLog.get("topic")), literal));
}
if (search.getOffset() != null) {
predicates.add(criteriaBuilder.equal(kafkaLog.get("offset"), search.getOffset()));
}
if (search.getResourceId() != null) {
predicates.add(criteriaBuilder.equal(kafkaLog.get("invoiceId"), search.getResourceId()));
}
if (search.getPartition() != null) {
predicates.add(criteriaBuilder.equal(kafkaLog.get("partition"), search.getPartition()));
}
if (search.getStatus() != null) {
predicates.add(criteriaBuilder.equal(kafkaLog.get("status"), search.getStatus()));
}
if (search.getCreatedAtFrom() != null && search.getCreatedAtTo() != null) {
predicates.add(criteriaBuilder.and(
criteriaBuilder.greaterThanOrEqualTo(kafkaLog.get("createdAt").as(Date.class),
search.getCreatedAtFrom()),
criteriaBuilder.lessThanOrEqualTo(kafkaLog.get("createdAt").as(Date.class),
search.getCreatedAtTo())));
}
if (search.getPayload() != null && !search.getPayload().isEmpty()) {
Expression<String> literal =
criteriaBuilder.literal("%" + search.getPayload().toUpperCase() + "%");
}
return predicates;
}
private CriteriaQuery<KafkaLog> getKafkaBySearchCriteria(KafkaLogSearchDto search, String orderBy,
int sortingDirection) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<KafkaLog> criteriaQuery = criteriaBuilder.createQuery(KafkaLog.class);
Root<KafkaLog> kafkaLog = criteriaQuery.from(KafkaLog.class);
List<Predicate> predicates = whereClause(criteriaBuilder, kafkaLog, search);
criteriaQuery.where(predicates.toArray(new Predicate[] {}));
if (orderBy == null || orderBy.isEmpty()) {
orderBy = "topic";
}
Expression<?> orderColumn = kafkaLog.get(orderBy);
if (orderColumn != null) {
if (sortingDirection == 0) {
criteriaQuery.orderBy(criteriaBuilder.asc(orderColumn));
} else if (sortingDirection == 1) {
criteriaQuery.orderBy(criteriaBuilder.desc(orderColumn));
}
}
return criteriaQuery;
}
答案 0 :(得分:0)
显然,自定义数据类型的支持一直到JDBC /数据库级别都不是JPA本身的一部分。只需阅读JSON,您就可以通过映射到String
的实体来做到这一点(如果JPA实现允许的话)。
但是,您有一些选择:
在读取JSONB字段时,您可以让数据库使用显式类型转换将其转换为String(因为JDBC中尚无直接JSON支持),例如:
SELECT payload::text FROM my_table WHERE ...
...或者对JSON字段本身进行一些精美的过滤,或者仅返回JSON数据的一部分。
答案 1 :(得分:0)
这是使用like子句搜索jsonb的示例谓词:
predicate.getExpressions()。add(cb.and(cb.like(cb.function(“ jsonb_extract_path_text”,String.class,root.get(“ tags”),cb.literal(this.key)),, “%” + this.value +“%”))));