如何使用SQL或JPA确定记录的层次结构

4
我有一个系统来确定菜单链接的层次结构并构建面包屑导航。我有两个表:VoceVociVoce既是菜单链接名称,也是页面标题名称。Voci表示Voce的层次结构。每个Voce都可以有另一个Voce作为子级(这里您看不到相关代码,但我使用JPA将一个Voce绑定到多个Voci)。例如,这是页面/链接“添加多个项目”的层次结构:菜单-->管理菜单-->添加多个项目。
 ----------
|         |
|        \/           Voce
|       -----------------------
|       |id |      name       |    
|       -----------------------
|       |1  |menu             |   
|      -----------------------
|       |2  |manage menu      |  
|       -----------------------
|       |3  |add single item  |
|       -----------------------
|       |4  |add many items   |
|       -----------------------
|
|_____________
        |     |
        |     |
Voci    |     |
-----------------
|id |father|son |
 ----------------
|1  |  1   |  2 |
 ----------------
|2  |  2   |  3 |
-----------------
|3  |  2   |  4 |
-----------------

我的问题是:如何确定链接“添加多个项目”的层次结构,以建立相对面包屑?我必须从最后一个元素(“添加多个项目”)开始确定层次结构,这是我唯一拥有的数据。
是否存在单个查询或JPA方式(我正在使用Spring MVC和Hibernate),可以让我知道所有确定链接“添加多个项目”层次结构的Voci记录。
希望我的表述清楚。
谢谢。

1
你使用的是哪个数据库?在Oracle数据库中,CONNECT BY PRIOR语句可以帮助你。否则,你需要在Java/JPA中获取父级,然后获取父级的父级,直到父级为null(或根节点)。 - Gaël J
1个回答

1
我建议使用闭包表模式。除了父级和子级ID之外,闭包表还包含一个depth列。对于每个深度,层次结构中的所有项目都会被添加。
|parent|child|depth 
|1     |1    |0 
|1     |2    |1
|1     |3    |2
|1     |4    |3

|2     |2    |0 
|2     |3    |1
|2     |4    |2

|3     |3    |0 
|3     |4    |1

|4     |4    |0

现在你需要做的是查询所有子菜单为所选菜单的条目,并按深度排序:
select parent from Voci where child = 4 order by depth

returns 4,3,2,1

-> select * from Voce where id in (select parent from Voci where child = 4 order by depth)
   or a correspondent JPA Query

有几种其他的存储层次结构的模式。一些数据库支持(供应商特定的)递归查询,但是使用简单的父ID - Voci本质上也不过如此 - 被认为是一种反模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接