用于分层数据的动态JPA CriteriaBuilder

用于分层数据的动态JPA CriteriaBuilder,jpa,eclipselink,Jpa,Eclipselink,我的分层数据结构如下所示,其中节点映射到父节点,如下所示: @Entity public class Node implements Serializable { @Id private long id; @Column(name="PARENT_ID") private Long parentId; @OneToMany @JoinColumn(name="PARENT_ID") public List<N

我的分层数据结构如下所示,其中节点映射到父节点,如下所示:

@Entity
public class Node implements Serializable { 
    @Id
    private long id;

     @Column(name="PARENT_ID")
     private Long parentId;

    @OneToMany    
    @JoinColumn(name="PARENT_ID")    
    public List<Node> children = new LinkedList<Node>();

}
现在我想在JPA CriteriaBuilder中构建一个动态查询,它可以查询任何节点并返回其子节点的结果。例如,如果我查询B,我会得到以下结果:

  • B
  • D
  • E
  • G
如果我查询E,我会得到:

-E -G


等等…

因为我使用SQL Server 2012作为我的数据库,所以我使用with子句如下:

@Entity
public class Node implements Serializable { 
    @Id
    private long id;

     @Column(name="PARENT_ID")
     private Long parentId;

    @OneToMany    
    @JoinColumn(name="PARENT_ID")    
    public List<Node> children = new LinkedList<Node>();

}
假设[E]节点id为8:

自上而下:

WITH NODE_TREE AS(
     SELECT N.ID, N.PARENT_ID FROM NODE_TABLE N WHERE N.ID = 8
     UNION ALL
     SELECT N.ID, N.PARENT_ID FROM NODE_TABLE N
     INNER JOIN NODE_TREE NT
     ON N.ID = NT.PARENT_ID
)

SELECT * FROM NODE_TREE;
WITH NODE_TREE AS(
     SELECT N.ID, N.PARENT_ID FROM NODE_TABLE N WHERE N.ID = 8
     UNION ALL
     SELECT N.ID, N.PARENT_ID FROM NODE_TABLE N
     INNER JOIN NODE_TREE NT
     ON N.PARENT_ID = NT.ID
)

SELECT * FROM NODE_TREE;
这将返回从上到下的节点列表:

B、 E,D,G

自下而上:

WITH NODE_TREE AS(
     SELECT N.ID, N.PARENT_ID FROM NODE_TABLE N WHERE N.ID = 8
     UNION ALL
     SELECT N.ID, N.PARENT_ID FROM NODE_TABLE N
     INNER JOIN NODE_TREE NT
     ON N.ID = NT.PARENT_ID
)

SELECT * FROM NODE_TREE;
WITH NODE_TREE AS(
     SELECT N.ID, N.PARENT_ID FROM NODE_TABLE N WHERE N.ID = 8
     UNION ALL
     SELECT N.ID, N.PARENT_ID FROM NODE_TABLE N
     INNER JOIN NODE_TREE NT
     ON N.PARENT_ID = NT.ID
)

SELECT * FROM NODE_TREE;
这将返回从下至上的节点列表:


B、 A

要做到这一点,您需要知道数据的深度,对吗?但是,如果不先看数据,你怎么知道深度呢?我总是在数据库中递归查找这种数据。不,这些数据的深度是未知的,可以是任何数字。您使用什么算法为此类数据生成查询生成器?为什么不直接返回E并使用node.getChildren()递归处理其子项?在查询中没有一种简单的方法可以做到这一点。这也是可能的,但我认为在查询级别上也可以做到。PostgreSQL也有这样的功能。但在JPA中如何实现这一点?@gkephorus您可以通过提供sql代码和实体类来发送本机查询,如
createNativeQuery(sqlString,klass).getResultList()中所示