2010-05-19 67 views
3

我使用Hibernate/Spring和MySQL数据库进行数据管理。在数据库中保存树状结构

目前我在JTable中显示一个树形结构。一棵树可以有多个分支,而一个分支又可以有几个分支(最多九层),或者有叶子。最近我有性能问题,只要我想在更深层次上创建新的分支。

此时分支有一个外键给它的父项。 domainobject通过调用getParent()来访问其父项,getParent()返回父分支。级别越深,创建新分支所需的时间越长。

微基准测试结果创建一个新的分支像:

1级:32毫秒。 3级:80毫秒。 9级:232毫秒。

很明显,级别(这意味着父母的数量)是负责这一点。所以我想问一下,是否有附件可以解决这类问题。我不明白为什么Hibernate需要在创建一个新的分支的时候知道整个对象树(所有父母直到根)。但据我所知,这可能是创建新分支时延迟的唯一原因,因为分支与其他任何对象没有任何关系。

我会非常感谢任何解决方法或建议。

映入眼帘, ymene

+0

终于我的openId注册工作。生病告诉你,哪个解决方案最适合我,并且评价你的帮助。非常感谢大家。 – crusam 2010-05-21 09:25:11

回答

2

基本上你有一种多对一的关系结构吗? 在hibernate中,所有都依赖于映射。调整您的映射,使用java.util.Set从父到子使用一对多关系。

不要使用ArrayList becasue List是有序的,所以hibernate将只为该顺序添加额外的列。

另请检查您的懒惰属性。如果您加载父级,并且您的子集属性中设置了lazy =“false”,则其所有子级都将从DB加载,这可能会影响性能。

此外,请检查儿童的'反向'属性。如果child表中的inverse为true,则表示可以单独管理子实体。否则,您必须仅使用父级来执行此操作。

谷歌左右反转,它一定会帮助你。

谢谢。

+0

谢谢你的详细解答。 U是正确的,关系被声明为一对多并且使用集合的方式。首先生病尝试着重于我的映射。所以谢谢你的提示。生病检查你谈论的所有属性。 – crusam 2010-05-21 07:28:41

+0

谢谢,我希望它能为你工作。冬眠总是很棘手,并且让我们感到困惑...... :) – Parth 2010-05-21 08:37:45

1

我不知道Hibernate的如何处理这个内部。然而,在数据库中存储树结构有不同的方法。一个对树上许多查询非常有效的方法是使用“nested set”方法 - 但这基本上会导致您看到的性能问题(例如昂贵的插入)。如果你需要快速插入或删除,我会与你有什么,例如一个简单的家长ID,并尝试看看Hibernate现在在做什么。

+0

我也读过关于嵌套集。不幸的是,我需要快速改变结构的能力,所以我不再关注它,因为像你这样的嵌套集已经说结构变化很昂贵,但是对于读命令来说非常好。 您只使用Ids而不是对象的想法很有趣。这对我来说有点不对劲,但可能值得一试,因为休眠应该无法解决整个分区。所以谢谢你后面! – crusam 2010-05-21 07:43:42

1

如果您不需要在SQL中报告数据,则可以将您的JTable序列化到数据库(可能使用类似XStream的东西)。这样你就不必担心处理树木的昂贵的数据库查询。

+0

对于大型树来说,这将会很昂贵,因为即使您只需要第一级节点,您也必须在每次更新时序列化整个事物并获取整个事物。 – tster 2010-05-19 11:37:29

+0

不幸的是我必须报告很多,所以我不能使用它。 – crusam 2010-05-21 07:44:51

1

你可以做的一件事是在MySQL中使用XML支持。这会给你原生支持层次结构的能力。我从来没有在MySQL中使用过XML支持,所以我不知道它是否与其他DBMS一样功能齐全(我知道SQL Server和DB2对我有很大的支持,可能我也会猜到Oracle)。
请注意,我从来没有使用过hibernate,所以我不知道你是否可以与之交互,或者如果你在这种情况下必须编写自己的DB代码(我的猜测是,你将写作您自己的查询)。

+0

我宁愿在我的数据库管理系统上保持独立,但如果我没有看到其他机会,我也会尝试研究这一点。从来没有听说过它,但非常有趣的提示。也要对此进行研究!谢谢! – crusam 2010-05-21 07:47:49