繁体   English   中英

DTO在递归结构上的投影

[英]DTO projection on a recursive structure

在我的数据模型中,有一个实体“位置”是递归的。 此外,与其他实体也有关系。

相应的JPA(Spring Data JPA)实体看起来像:

@Entity
@Table(name = "location")
class Location{

  @OneToMany(mappedBy = "parent", orphanRemoval = true)
  @OrderBy("name ASC")
  Set<Location> children = null

  @ManyToOne(fetch = FetchType.EAGER)
  @JoinColumn(name = "parent_id")
  Location parent = null

  @Column(name = "name")
  String name = null

  @OneToMany(mappedBy = "location", fetch = FetchType.EAGER)
  Stops stops = null
  ...

进行只读查询的最有效方式是什么? 我只需要具有完整递归结构的实体(表位置)内部的信息,而无需来自相关实体的信息。

我已经读过DTO投影一词,但与递归结构无关。

读取递归结构通常是通过利用SQL称为递归CTE来完成的 JPA不立即支持该功能,因为并非所有RDBMS都支持它。 如果您知道您的DBMS支持它,则可以使用以下SQL来做到这一点:

WITH RECURSIVE nodes(id, parent_id) AS (
  SELECT id, parent_id FROM location l where id = ?
  UNION ALL
  SELECT l.id, l.parent_id FROM nodes n JOIN location l ON n.parent_id = l.id
)
SELECT id, parent_id FROM nodes

这样一来,您将获得一个特定的父级位置ID列表以及它们各自的父级ID。 您将不得不在其中引入结构。

List<Object[]> result = //get the result of the query
Map<Integer, LocationDto> locationMap = new HashMap<>();
result.forEach(r -> locationMap.put(result.get(0), new LocationDto(result[0], result[1])));
locationMap.values().forEach(l -> l.setParent(locaitonMap.get(l.getParentId())));

如果您由于可移植性问题而不想使用纯SQL,或者只是因为不想放弃抽象而使用Blaze-Persistence ,则可以在JPA之上使用Blaze-Persistence ,并增加对CTE的支持。 。 您的查询具有持久性,看起来像这样

List<LocationCte> result = criteriaBuilderFactory.create(entityManager, LocationCte.class)
  .withRecursive(LocationCte.class)
    .from(Location.class, "l")
    .bind("id").select("l.id")
    .bind("parent").select("l.parent.id")
    .where("id").eq(initialId)
  .unionAll()
    .from(Location.class, "l")
    .innerJoinOn(LocationCte.class, "cte")
      .on("cte.parent").eqExpression("l.id)
    .end()
    .bind("id").select("l.id")
    .bind("parent").select("l.parent.id")
  .end()
  .from(LocationCte.class)
  .getResultList();

您还将需要此特殊实体类

@CTE
@Entity
public class LocationCte {
  @Id Integer id;
  Integer parent;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM