pub 機制 否則 on() color 檢索 不存在 bsp 數據庫查詢

1.從返回結果上對比:

load方式檢索不到的話會拋出org.hibernate.ObjectNotFoundException異常;

get方法檢索不到的話會返回null;

2.從檢索執行機制上對比:

load方法的執行則比較復雜首先查找session的persistent Context(一級緩存)中是否有緩存,如果有則直接返回,如果沒有則去查找二級緩存,如果有則返回,如果沒有則判斷是否是lazy,若不是lazy,直接訪問數據庫檢索,查到記錄返回(並且同時在二級緩存中存放查到的數據方便下次使用,若再下次使用時在二級緩存命中,就是查到數據,則有可能將數據放到

一級緩存中。),查不到拋出異常。 若是lazy,則返回代理對象,而不到數據庫中查找,除非使用此對象時,才到數據庫中查找。

get方法先到一級緩存,然後二級,最後db查找。

Get加載(數據庫中存在檢索的數據)

public void testLoadNotNull() {  
        Session session= HibernateUtils.getSession();  
        
        // 數據庫中存在id為2的數據  
        User user = (User)session.load(User.class, 2);
    
        System.out.println(user);  
        System.out.println(user.getId() + "---->>" + 
         user.getName());  

        HibernateUtils.closeSession();  
    
}

因為Hibernate規定get方法不能使用延遲加載,當執行到User user = (User)session.get(User.class, 2);這條語句時,get方法首先會查詢session緩存,沒有的話就查詢二級緩存,最後會查詢數據庫,因此在執行該語句的時候,會先發出sql語句進行查詢。而且,執行get方法的時候,get方法每次都會從數據庫直接查詢。

Get加載(數據庫中不存在檢索的數據)

/** 
 * 查詢數據庫中不存在的數據 
 */  
public void testGetWithNull() {  

         Session session  = HibernateUtils.getSession();  

       User user = (User)session.get(User.class, 0);
        System.out.println(user);  
        HibernateUtils.closeSession();  
   
}

同上,在執行到User user = (User)session.get(User.class, 0);這條語句時,get方法每次都是直接查詢數據庫,在執行該語句時,Hibernate會發出sql語句,到數據庫進行查詢數據,由於id為0的數據不存在,get方法查詢不到數據時,會返回null。

Load加載(數據庫中存在檢索的數據)

/** 
 * 數據庫中存在查詢的數據 
 */  
public void testLoadNotNull() {  
  
        Session session = HibernateUtils.getSession();  

       User user = (User)session.load(User.class, 2);</span>  
       
        System.out.println(user);  
       
        user.getName());  
       
        HibernateUtils.closeSession(session);  
    }  
}
Hibernate中,load方法是支持懶加載的,在執行到User user = (User)session.load(User.class, 2);這條語句時,load方法首先會查找session的persistent Context中是否存在緩存,如果存在則直接返回;如果沒有緩存,則load方法會判斷是否是lazy加載,如果不是lazy方式,則直接訪問數據庫,查詢Id為2的數據,由於數據庫中存在Id為2的數據,因此get方法會返回實體對象。
在這個例子中,load方法采用的是lazy方式,因此在執行load方法時,Hibernate不會發出sql語句,因為此時Hibernate建立了代理對象,但並沒有訪問代理對象的屬性。當執行System.out.println(user);時,Hibernate才會初次發出sql語句,

Load加載(數據庫中不存在檢索的數據)

/** 
 * 數據庫中不存在查詢的數據 
 */  
public void testLoadWithNull() {  
        Session session = HibernateUtils.getSession();  
       User user = (User)session.load(User.class, 0);
        System.out.println(user);  
        user.getName());  
        HibernateUtils.closeSession(session);  
    
}

在執行到load方法時,load方法會首先查詢session中是否存在緩存,如果存在則直接返回,如果不存在則會判斷是否為lazy,這裏設置的是lazy方式,因此load方法會認為數據庫 中存在數據,直接建立代理對象,把代理對象返回給user。
而執行到System.out.println(user);時,Hibernate會發出sql語句,訪問數據庫查詢Id為0的數據,由於數據庫中不存在Id為0的數據,因此load方法會返回org.hibernate.ObjectNotFoundException,直接拋出異常。
總之對於get和load的根本區別,一句話,hibernate對於load方法認為該數據在數據庫中一定存在,可以放心的使用代理來延遲加載,如果在使用過程中發現了問題,只能拋異常;而對於get方法,hibernate一定要獲取到真實的數據,否則返回null。

Hibernate中get方法和load方法的區別