2010-05-19 50 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