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

Mapping many-to-many IN statement into JPA (Spring Boot)

我在 JPA 中创建了两个实体,ListingItemType - 它们存在于多对多关系中(Hibernate auto - 生成一个连接 table)。我正在尝试找到创建查询的最佳方法,该查询接受项目类型字符串的动态列表和 returns 所有与指定项目类型匹配的列表的 ID,但我是 JPA 的新手。

目前我正在使用 JpaRepository 创建相对简单的查询。我一直在尝试使用 CriteriaQuery 来做到这一点,但我在其他地方读到的一些接近但不完全的答案似乎表明,因为这是在 Spring 中,所以这可能不是最好的方法,我应该这样做使用 JpaRepository 实现本身来处理这个问题。这看起来合理吗?

我有一个感觉不到一百万英里的查询(基于 Baeldung 的 example and my reading on WikiBooks),但对于初学者来说,我在加入时收到原始类型警告,更不用说我不确定这是否会 运行,我确信有更好的方法来解决这个问题。

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 的动态列表(ItemType 中的字段)和 return 唯一的 id 列表( PK in Listing),其中有一行在联结 table 中匹配。如果我可以提供任何进一步的信息或帮助,请告诉我 - 我已经感觉到 JPA 及其对动态查询的处理是其面包和黄油的一部分!

条件 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)