【问题标题】:JPA specification join many tablesJPA 规范连接许多表
【发布时间】:2021-06-22 12:25:11
【问题描述】:

我有货架实体、HubProducts 实体、产品实体。

  1. 货架上有 HubProducts
  2. HubProducts 有产品
  3. 产品有名称
public class Shelf extends BaseEntity {
    
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "hub_product_id")
    private Set<HubProducts> hubProducts;
}

public class HubProducts extends BaseEntity {
    
    @JsonBackReference
    @JoinColumn(name = "products_id")
    @ManyToOne(fetch = FetchType.LAZY)
    private Products product;
}

同样,产品实体也有名称字段。

现在我想使用 JPA 规范进行查询,以便过滤所有与产品名称匹配的记录

为此,我写了:

private static void applyKeywordFilter(CriteriaBuilder cb,
                                       Root<Shelf> root,
                                       Collection<Predicate> predicates,
                                       String keyword) {
    if (!ObjectUtils.isEmpty(keyword)) {
        predicates.add(cb.or(
            // Shelf->hubProducts->Products -> [name]
            cb.like(root.join("hubProducts", JoinType.LEFT).join("product",  JoinType.LEFT).get("name"), "%" + keyword + "%"),
            cb.like(root.get("shelfDetails"), "%" + keyword + "%")));
    }
}

但不幸的是, cb.like(root.join("hubProducts", JoinType.LEFT).join("product", JoinType.LEFT).get("name"), "%" + keyword + "%"), 不起作用。

有人可以帮忙吗?

【问题讨论】:

  • 你能具体说明“不起作用”是什么意思吗?您是否收到错误或与预期不同的结果?
  • @OHGODSPIDERS,我希望应该过滤与产品名称匹配的记录。

标签: java spring-boot hibernate spring-data-jpa specifications


【解决方案1】:

在我的例子中,我必须实体 Producers、Movie、Actor。电影有多名演员和一名制片人。为了执行搜索,我使用了这个:

private Specification<Movie> searchSpecification(String keyword) {
        return ((root, criteriaQuery, criteriaBuilder) -> {
            criteriaQuery.distinct(true);
            if ((keyword ==null)) {
                return null;
            }
            return criteriaBuilder.or(
                    criteriaBuilder.like(root.get("name"), "%" + keyword + "%"),
                    criteriaBuilder.like(root.get("plot"), "%" + keyword + "%"),
                    criteriaBuilder.like(root.join("actors").get("name"), "%" + keyword + "%"),
                    criteriaBuilder.like(root.join("producer").get("name"), "%" + keyword + "%")
            );
        });
    }

您参考这个来生成您自己的规范和连接表。这里我加入了 3 个表。

【讨论】:

    猜你喜欢
    • 2021-09-07
    • 1970-01-01
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多