1. 程式人生 > >(十六)Hibernate中的延遲加載

(十六)Hibernate中的延遲加載

pan nco exce bsp fetch gin turn list logs

一、什麽是延遲加載

為了節省Hibernate加載對象的性能節銷,在Hibernate中真正需要用到這個對象時,才會發出

SQL語句來抓取這個對象。這一個過程稱為延遲加載。

二、延遲加載的分類

A:實體對象的延遲加載

B:一對多|多對多的延遲加載

C:多對一|一對一的延遲加載

D:屬性的延遲加載

  • A:實體對象的延遲加載:使用session.get()和session.load()獲取對象的區別就是是否開啟延遲加載。

Hibernate只加載實體對象的ID,需要其他屬性,才真正的發出SQL來加載這個對象。

Load:采用延遲加載 加載到的是一個代理對象

Get:沒有采用延遲加載 加載到的是一個實體對象。

  • 案例:

User user=(User)session.load(clazz, id);//直接返回的是代理對象

System.out.println(user.getId());//沒有發送sql語句到數據庫加載

user.getName();//創建真實的User實例,並發送sql語句到數據庫中

  • 註意:1.不能判斷User=null;代理對象不可能為空

      2.代理對象的限制:和代理關聯的session對象,如果session關閉後訪問代理則拋異常。session關閉之前訪問數據庫

  • B:一對多|多對多的延遲加載

fetch = FetchType.Lazy:表示開啟延遲加載。讀取班級時,不會發出讀取學生的SQL語句。等真正使用學生數據時,才會發出一條SQL語句讀取學生

fetch = FetchType.EAGER:取消延遲加裁。讀取班級會左關聯讀取學生。

@OneToMany(cascade = { CascadeType.REMOVE },fetch=FetchType.EAGER)
@JoinColumn(name = "classes_id")
@OrderBy(value = " studentID desc")
public List<StudentBean> getStuList() {
return stuList;
}

  • C : 多對一|一對一的延遲加裁

    默認是取消延遲加載的。

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "group_id")
    private GroupBean groupBean;

  • 延遲加載帶來的問題: session關閉之後,再訪問代理對象(延遲加載獲取的是代理對象)會拋出“no session”異常。
package action;

import java.util.Set;

import javassist.compiler.ast.IntConst;

import org.hibernate.Session; import org.hibernate.Transaction; import bean.ClassBean; import bean.StudentBean; import util.HibernateSessionUtil; public class Test { public static void main(String[] args) { ClassBean cla=Test.load(); //當Test.load()執行完畢之後,session就被關閉,這時候再訪問代理對象則會拋出異常。 使用session。get就不會出現這個問題 System.out.println(cla.getClassName()); } private static ClassBean load() { ClassBean cla = null; Session session = null; Transaction tran = null; try { session = HibernateSessionUtil.getSession(); tran = session.beginTransaction(); cla = (ClassBean) session.load(ClassBean.class, new Integer(2)); //使用延遲加載,獲得的是代理對象 tran.commit(); return cla; } catch (Exception e) { e.printStackTrace(); tran.rollback(); } finally { HibernateSessionUtil.closeSession(); //關閉session } return null; } }
  • 橙色字體處代碼會出現“no session”異常。

(十六)Hibernate中的延遲加載