歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Hibernate One to Many 遲延加載分析

Hibernate One to Many 遲延加載分析

日期:2017/3/1 10:07:54   编辑:Linux編程

One to Many

1: Oneto Many,默認是采用延遲加載的(lazy=true),因為很多情況下,當我們獲取到One的一方後,Many的一方並非立即需要的,當我們經常只需要One的一方的時候,延遲加載就很有意義了.

2:Hibernate 中的延遲加載(lazy loading),當我們在程序中獲取到了一的一方,但是不需要多的一方,那麼使用延遲加載就是非常適合的.

3:當我們One和Many都要同時需要的時候,我們可以將One的一方的hbm.xml中用於保存Many的Set元素的lazy改為false

One to Many的延遲加載分析

當我們通過通過Session.get()查詢到One的一方後,其中用於保存Many的Set其實是一個代理,其類型為org.hibernate.collection.PersistentSet, PersistentSet 實現了Java.util.Set接口,並內置了一個用於存放實際數據的HashSet,初始時為空,當真正要訪問這個集合的元素時,如調用Java.util.Set#iterator()#toArray() #containsAll(),#toString,#equal()#hashCode等要真正訪問集合的元素的方法的時候,程序才主要發出SQL語句,真正加載Many一方,並且一次讀取完Many一方的所有元素.

PersistentSet 實現了Java.util.Set接口,並內置了一個HashSet實例,PersistentSet代理了Java.util.Set的#iterator()#toArray()

#containsAll(),#toString等方法: 而代理的過程很簡單:

若要訪問到Many的數據,則先加載Many的所有元素,再簡單調用被代理的方法!

這裡也是應用到"代理模式"的思想..框架裡,這個模式很常用......

在Hibernate裡,延遲加載基本是用"代理模式"實現的!

如:

  1. public class PersistentSet extendsAbstractPersistentCollection implements java.util.Set {
  2. 。。。。。。。。。。。。。。
  3. publicString toString() {
  4. read(); //先加載Many一方
  5. return set.toString();
  6. }
  7. 。。。。。。。。。。。
  8. }

再看看read()方法:

  1. public abstract classAbstractPersistentCollection implementsSerializable, PersistentCollection {
  2. …………………………………
  3. /**
  4. * Called by any read-only method of the collection interface
  5. */
  6. protected final void read() {
  7. initialize(false);
  8. }
  9. protectedfinal void initialize(boolean writing) {
  10. if (!initialized) {
  11. if(initializing) {
  12. throw new LazyInitializationException("illegal access toloading collection");
  13. }
  14. //檢查與數據庫的連接
  15. throwLazyInitializationExceptionIfNotConnected();
  16. //這裡真正加載Many
  17. session.initializeCollection(this, writing);
  18. }
  19. }
  20. …………………………………….
  21. }
Copyright © Linux教程網 All Rights Reserved