我在 Hibernate 中表示对象层次结构时遇到了一些问题。我四处搜索,但未能找到任何执行此操作或类似操作的示例 - 如果这是一个常见问题,我深表歉意。
我想使用 Hibernate 坚持使用两种类型:组和项。
* 组由其名称和父组的组合唯一标识。
* 组排列在许多树中,这样每个组都有零个或一个父组。
* 每个项目可以是零个或多个组的成员。
理想情况下,我想要一种双向关系,让我能够:
* 项目所属的所有组
* 属于特定组或其后代的所有项目。
我还需要能够从顶部遍历组树,以便在 UI 上显示它。
理想情况下,基本对象结构如下所示:
class Group {
...
/** @return all items in this group and its descendants */
Set<Item> getAllItems() { ... }
/** @return all direct children of this group */
Set<Group> getChildren() { ... }
...
}
class Item {
...
/** @return all groups that this Item is a direct member of */
Set<Group> getGroups() { ... }
...
}
最初,我只是在 Items 和 Groups 之间建立了一个简单的双向多对多关系,这样获取组层次结构中的所有项目需要递归到树下,而获取一个 Item 的组是一个简单的 getter ,即:
class Group {
...
private Set<Item> items;
private Set<Group> children;
...
/** @return all items in this group and its descendants */
Set<Item> getAllItems() {
Set<Item> allItems = new HashSet<Item>();
allItems.addAll(this.items);
for(Group child : this.getChildren()) {
allItems.addAll(child.getAllItems());
}
return allItems;
}
/** @return all direct children of this group */
Set<Group> getChildren() {
return this.children;
}
...
}
class Item {
...
private Set<Group> groups;
/** @return all groups that this Item is a direct member of */
Set<Group> getGroups() {
return this.groups;
}
...
}
但是,这会导致多个数据库请求获取具有许多后代的组中的项目,或者检索整个组树以显示在 UI 中。这似乎非常低效,尤其是对于更深、更大的组树。 在 Hibernate 中是否有更好或标准的方式来表示这种关系?
我有没有做错或愚蠢的事情?
到目前为止,我唯一的想法是:
用指定组的整个祖先的唯一“路径”字符串替换组的 id、parent 和 name 字段,例如:
/根组
/rootGroup/aChild
/rootGroup/aChild/aGrandChild
Groups 和 Items 之间的连接表将包含 group_path 和 item_id。
这立即解决了我之前遇到的两个问题:
1. 整个组层次结构可以在一次查询中从数据库中获取并在内存中重建。
2. 要检索组中的所有项目或其后代,我们可以从 group_item 中选择 group_path='N' 或 group_path like 'N/%'
然而,这似乎违背了使用 Hibernate 的意义。欢迎所有想法!
最佳答案
我认为真正的问题是您希望性能受到哪些影响。如果你宣称你所有的关系都是懒惰的,并拉出你需要的东西,那么你会随着时间的推移分散打击。在许多情况下,这意味着您的用户(人或芯片)感知到更快的 react 时间。即使您一次处理整个图,您实际上也不需要同时将整个图存储在内存中。
另一方面,将整个图表拉到一起可以预先提高性能,同时加快操作速度。
两者之间的最大区别在于您的具体用例。如果这是一个网络服务器,将整个图形拉入内存将杀死服务器。无论如何,大多数人无法处理超过 7-10 个选项,而且整个图表很容易让用户不知所措,让用户界面难以导航。
还要记住这些优化规则:
- 不要
- 说真的,不要。将硬件投入性能问题会更便宜,然后将您的代码优化到不再可维护的程度。
- 如果您认为必须,找到 1 瓶颈,使用分析工具并修复它。
关于java - Hibernate 中层次结构的高效表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2067297/