【问题标题】:Spring with Hibernate - SQL - return list of obejcts with nested list by condition带有 Hibernate 的 Spring - SQL - 按条件返回具有嵌套列表的对象列表
【发布时间】:2022-12-08 09:58:41
【问题描述】:

我将 Spring 与 Hibernate、MySQL、JPQL 一起使用。我的存储库中有这样一个方法:

@Query("""
  SELECT w FROM Window w
  LEFT JOIN w.ramps r
  WHERE r.isDeleted = false
  AND w.id = :id
""")

@EntityGraph(attributePaths = {"warehouse", ...})
Optional<Window> findByIdWithNotDeletedRamps(long id);

我的目标:我想获取所有依赖ramps但只有未删除ramps(ramp.isDeleted = false)的窗口。如果窗口只删除了ramps 那么我应该会收到一个带有ramps 空列表的窗口

到目前为止,我获取了所有窗口,然后在代码中使用 Mapstruct 过滤了 window.ramps 以接收 windows 并且仅未删除(isDeleted 标志 = false)斜坡。我想知道如何编写 sql 来接收 windows 以及仅未删除的列表 ramps?可能吗?

我试过上面的代码,但这是一个不好的方法,因为当 Windows 没有任何斜坡时,就不会收到这个特定的 window。

【问题讨论】:

  • r.isDeleted = 假作为 join 的一部分而不是 where 的一部分。这使您的左连接变为内连接SELECT w FROM Window w LEFT JOIN w.ramps r on r.isDeleted = false WHERE w.id = :id

标签: java hibernate jpql


【解决方案1】:

您应该为此使用 DTO,我认为这是 Blaze-Persistence Entity Views 的完美用例。

我创建了库以允许在 JPA 模型和自定义接口或抽象类定义的模型之间轻松映射,类似于 Spring Data Projections on steroids。这个想法是您按照自己喜欢的方式定义目标结构(领域模型),并通过 JPQL 表达式将属性(getter)映射到实体模型。

使用 Blaze-Persistence Entity-Views,您用例的 DTO 模型可能如下所示:

@EntityView(Window.class)
public interface WindowDto {
    @IdMapping
    Long getId();
    String getName();
    @Mapping("ramps[isDeleted = false]")
    Set<RampDto> getRamps();

    @EntityView(Ramp.class)
    interface RampDto {
        @IdMapping
        Long getId();
        String getName();
    }
}

查询是将实体视图应用于查询的问题,最简单的就是通过 id 进行查询。

WindowDto a = entityViewManager.find(entityManager, WindowDto.class, id);

Spring Data 集成允许您几乎像使用 Spring Data Projections 一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

Page<WindowDto> findAll(Pageable pageable);

最好的部分是,它只会获取实际需要的状态!

【讨论】:

    猜你喜欢
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多