spring-boot - 将多对多 IN 语句映射到 JPA(Spring Boot)
问题描述
我在 JPA 中创建了两个实体,Listing和ItemType - 它们存在于多对多关系中(Hibernate 自动生成连接表)。我正在尝试找到创建查询的最佳方法,该查询接受项目类型字符串的动态列表并返回与指定项目类型匹配的所有列表的 ID,但我是 JPA 中的新人。
目前我正在使用 JpaRepository 创建相对简单的查询。我一直在尝试使用 CriteriaQuery 来做到这一点,但我在其他地方读到的一些接近但不完全的答案似乎表明,因为这是在 Spring 中,这可能不是最好的方法,我应该使用JpaRepository 实现本身。这看起来合理吗?
我有一个感觉不到一百万英里的查询(基于 Baeldung 的示例和我在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 列表(Listing 中的 PK),其中有一行在联结表中匹配。如果我可以提供任何进一步的信息或帮助,请告诉我 - 我已经感觉到 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)
推荐阅读
- odoo - 在销售订单行中计算新的 price_unit
- css - 如何让我的角落色带正确渲染?
- python - 如何在表单中设置默认值
- php - AMQPException 库错误:表对于缓冲区来说太大
- powershell - 尝试通过 Powershell 从 GoDaddy 网站下载文件夹时出现权限错误
- sql - 我想要最多多列
- wordpress - 每当我重新启动时,docker-composer wordpress 都会询问安装
- docker - 从私有注册表中提取的 Docker 给出了本地错误:tls:坏记录 MAC
- mysql - 如何创建一个 MYSQL 触发器,在更新另一个表时更新产品的库存水平,该表具有该产品的多个实例?
- xamarin.forms - 使用 Prism 8 找不到方法 Shiny.IShinyStartup.ConfigureServices