首页 > 代码库 > (十六)Hibernate中的延迟加载

(十六)Hibernate中的延迟加载

一、什么是延迟加载

    为了节省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 = "http://www.mamicode.com/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中的延迟加载