将多对多IN语句映射到JPA(Spring Boot)

时间:2019-06-16 12:33:51

标签: spring-boot jpa persistence

我在JPA中创建了两个实体 Listing ItemType -它们存在多对多关系(Hibernate自动生成联结表)。我正在尝试找到创建查询的最佳方法,该查询接受项目类型字符串的动态列表并返回与指定项目类型匹配的所有列表的ID,但是我是JPA的最近发起人。

目前,我正在使用JpaRepository创建相对简单的查询。我一直在尝试使用CriteriaQuery进行此操作,但是我在其他地方阅读过的一些接近但不完全的答案似乎表明,因为这是在Spring中,这可能不是最佳方法,因此我应该使用JpaRepository实现本身。看起来合理吗?

我有一个查询距离没有100万英里(基于Baeldung的example和我对WikiBooks的阅读),但对于初学者来说,我在Join上收到Raw Type警告,更不用说我不确定是否会运行,而且我确定还有更好的方法来解决这个问题。

public List<ListingDTO> getListingsByItemType(List<String> itemTypes) {

    List<ListingDTO> listings = new ArrayList<>();

    CriteriaQuery<Listing> criteriaQuery = criteriaBuilder.createQuery(Listing.class);

    Root<Listing> listing = criteriaQuery.from(Listing.class);
    //Here Be Warnings. This should be Join<?,?> but what goes in the diamond?
    Join itemtype = listing.join("itemtype", JoinType.LEFT);

    In<String> inClause = criteriaBuilder.in(itemtype.get("name"));

    for (String itemType : itemTypes) {

        inClause.value(itemType);

    }

    criteriaQuery.select(listing).where(inClause);

    TypedQuery<Listing> query = entityManager.createQuery(criteriaQuery);

    List<Listing> results = query.getResultList();

    for (Listing result : results) {

        listings.add(convertListingToDto(result));

    }

    return listings;

}

我正在尝试了解如何最好地传递name s(ItemType中的字段)的动态列表,并返回唯一的id s(清单中的PK)的列表,其中是在联结表中匹配的行。请让我知道是否可以提供进一步的信息或帮助-我已经感觉到JPA及其对动态查询的处理是它的主要内容!

1 个答案:

答案 0 :(得分:2)

当您需要基于各种...标准动态创建查询时,标准API很有用。

您需要的是一个静态JPQL查询:

select distinct listing from Listing listing 
join listing.itemTypes itemType 
where itemType.name in :itemTypes

由于您使用的是Spring-data-jpa,因此只需要定义一个方法并在存储库界面中使用@Query对其进行注释:

@Query("<the above query>")
List<Listing> findByItemTypes(List<String> itemTypes)