簡體   English   中英

使用Spring,Hibernate和Ehcache緩存整個數據庫

[英]Cache a whole database using Spring, Hibernate, and Ehcache

我正在開發一個應用程序,該應用程序主要使用讀取和某些更新來進行緩存。

我使用的技術堆棧是Spring + Hibernate + Ehcache。 我需要使用緩存為請求提供服務,而根本不訪問數據庫。 我采用的方法是使用諸如getSession().createCriteria(<Entity>.class).list()查詢在應用程序啟動時緩存所有數據,然后使用session.get()向Hibernate詢問實體調用,以便它使用二級緩存進行解析。

我看到的一個挑戰是我的實體類具有很多集合和關聯屬性(多對多帶有額外的列,一對多,一對一)。

對於這種緩存,我有兩種方法:

  1. 保留所有關系,以獲取EAGER。 啟動時,緩存中將使用包含左外部聯接的大查詢填充數據。 我擔心急於加載數據可能會導致不必要的長時間運行的查詢返回多行。

  2. 將關系保持為LAZY並遍歷所有行,然后調用.getSetOf<Entity>以加載相關的實體。 我擔心在啟動時實際上會對所有數據進行迭代,因此我不確定這是否是一個好習慣。

由於Hibernate中的關聯是使用組合鍵和外鍵關聯的,而不是作為單獨的ID存儲的,因此加載此類關聯/集合似乎很麻煩。

我更希望表數據位於不同的緩存區域中,它們的外鍵關系只是ID(而不是合成/集合)。 我將所有這些實體緩存在不同的區域中,並在運行時通過遍歷這些區域來組合結果。

誰能建議我應該采用哪種方法? 如果有其他替代方法,請提出建議。

我正在一個項目中進行技術堆棧spring + hibernate + hazelcast 我也在使用休眠二級緩存 我們還將在服務器啟動時將數據加載到緩存中。 根據我的說法,您不應該對一個急切的實體進行所有收集,因為它會使對象變得很沉重。我們正在使用混合方法。根據需要,我們的一些收集是渴望的,有些是懶惰的。 如果您的館藏數據非常龐大,請使其變得懶惰,否則請使其熱心。 我們正在做的另一件事,就是在查詢中使用LEFT JOIN FETCH ,如果集合定義為lazy,也將加載集合。例如:

SELECT DISTINCT userInfo FROM UserInfo userInfo
LEFT JOIN FETCH userInfo.userRoles
LEFT JOIN FETCH userInfo.regions
LEFT JOIN FETCH userInfo.countries

在我的實體UserInfo中,我使region Eager (因為區域數較少)和country Lazy (因為國家數較多)。現在,此查詢仍返回已滿載國家和地區的userInfo對象。提取不會執行多個查詢。

希望對您有所幫助。

從您的描述還不清楚您的應用程序是否控制對數據庫的訪問。

  • 如果不是,則性能文檔指出您可能會擁有過時的數據。 在這種情況下您該怎么辦?
  • 如果是這樣,並且只有在您真的需要最大程度地減少數據庫命中次數時,我才不會使用Hibernate或Ehcache。 除了初始負載外,ORM進行的工作不多,我認為這並不能成為Hibernate的用例。 我會在啟動時使用Spring JDBC進行批處理選擇。 這將減少調用次數,並減少可能的內存不足異常(“正常”的select語句將引用其讀取的數據,因此隨着記錄的進行,您將擁有無法被GC引用的更多引用)。 它還減少了1負擔,從而減少了您的技術堆棧。 您可以在更改狀態后立即更新緩存和數據庫。 您可能需要考慮交易范圍。 左聯接可以在您的映射器中解決。 我還將放棄面向對象的方法,並使用數組或數據映射。 僅出於對象的目的而用對象封裝每組數據可能會過大(內存消耗,CPU,...)。 特別是一次全部加載的要求使我認為這里沒有發生很多交互。 並刪除Ehcache。 如果確實需要最小化數據庫調用,則可以將所有內容都放入Map中,因為不需要逐出策略。

為了清楚起見,我不是反對OO或Hibernate或Ehcache。 我只是想知道它們是否適合您(有限的)說明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM