hibernate--lazy(懶加載)屬性


關聯映射文件中<class>標簽中的lazy(懶加載)屬性

Lazy(懶加載):只有在正真使用該對象時,才會創建這個對象

Hibernate中的lazy(懶加載):只有我們在正真使用時,它才會發出SQL語句,給我們去查詢,如果不使用對象則不會發SQL語句進行查詢。

Hibernate中lazy(懶加載)的實現:

采用了第三方組件的庫,這個庫叫cglib.jar(比較流行),這個庫對我們的類生成代理類(JDK的動態代理,只能對JDK中實現了接口的類進行代理),代理可以控制源對象並且可以對源對象的功能進行增強,而cglib.jar可以對類進行代理(cglib對我們的類進行繼承,生成一個子類,這個子類作為代理類返回給你)。

只有你正真代理類的方法,則會查看你有沒有加載目標對象,如果沒有則會加載目標對象。

Lazy(懶加載)在hibernate何處使用:

1、<class>標簽上,可以取值:true/false,(默認值為:true)

2、<property>標簽上,可以取值:true/false,需要類增強工具

3、<set>、<list>集合上,可以取值:true/false/extra,(默認值為:true)

4、<one-to-one>、<many-to-one>單端關聯上,可以取值:false/proxy/noproxy

Session.load()方法支持lazy,而session.get()不支持lazy;

Hibernate的lazy生效期:

生效期和session一樣的,session關閉,lazy失效

hibernate支持lazy策略只有在session打開狀態下有效。

<class>標簽上,可以取值:true/false,(默認值為:true):

實例一:設置<class標簽上的lazy=true(默認)

@Test
    public void LazyTest() {
        session = HibernateUtil.getSession();
        tx = session.beginTransaction();

        // 執行此語並不會發SQL語句,只是返回一個代理類
        Group group = (Group) session.load(Group.class, 1);

        // 不會發SQL語句,使用上面輸入的1值
        System.out.println("group.id=" + group.getId());

        // 此處使用對象,會發出SQL語句
        System.out.println("group.name=" + group.getName());

        // 提交事務
        tx.commit();
    }

輸出:

group.id=1
Hibernate: select group0_.id as id1_1_0_, group0_.name as name2_1_0_ from t_group group0_ where group0_.id=?

設置<class標簽上的lazy=true(默認)

@Test
    public void LazyTest1(){
        Session session = null;
        Transaction tx = null;
        Group group = null;
            
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
    
            group =(Group)session.load(Group.class, 1);
            
            System.out.println("group.name=" + group.getName());
            
            //提交事務
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession(session);
        }
        
        //不能正確輸出,拋出了LazyInitalizationException異常,因為session已經關閉
        //hibernate支持lazy策略只有在session打開狀態下有效。
        System.out.println("group.name=" + group.getName());
    }

關聯映射文件中集合標簽中的lazy(懶加載)屬性

<set>、<list>集合上,可以取值:true/false/extra,(默認值為:true)

實例一:(集合上的lazy=true(默認))

@Test
    public void LazyTest2() {

        session = HibernateUtil.getSession();
        tx = session.beginTransaction();
        // 不會發出SQL語句
        Classes classes = (Classes) session.load(Classes.class, 1);
        // 發出SQL語句,因為在使用對象
        System.out.println("classes.name=" + classes.getName());

        // 不會發SQL語句,只會返回一個代理類,因為沒有使用對象
        Set<Student> students = classes.getStudents();

        // 會發出SQL語句,因為使用了對象
        for (Iterator<Student> iter = students.iterator(); iter.hasNext();) {
            Student student = iter.next();
            System.out.println(student.getName());
        }

        // 提交事務
        tx.commit();
    }

實例二:集合上的lazy=true(默認)

session = HibernateUtils.getSession();
            tx = session.beginTransaction();
    
            //不會發出SQL語句
            Classes classes = (Classes)session.load(Classes.class, 1);
            //發出SQL語句,因為在使用對象
            System.out.println("classes.name=" + classes.getName());
            
            //不會發SQL語句,只會返回一個代理類,因為沒有使用對象
            Set<Student> students = classes.getStudents();
            
            //會發出SQL語句,發出查詢全部數據的SQL,效率不高
            System.out.println("student.count=" + students.size());
            
            //提交事務
            tx.commit();

實例三:集合上的lazy=false,其它保持默認

//不會發出SQL語句,因為只設置了集合上的lazy為false,其它保持默認
            Classes classes = (Classes)session.load(Classes.class, 1);
            //發出兩條SQL語句,分別加載classes和student
            //並且把集合中的數據也加載上來(雖然並沒有使用集合中的對象),因為設置了集合的lazy=false
            System.out.println("classes.name=" + classes.getName());
            
            //不會發SQL語句,因為已經在前面加載了數據
            Set<Student> students = classes.getStudents();
            
            //會發出SQL語句,因為已經在前面加載了數據
            for (Iterator<Student> iter = students.iterator();iter.hasNext();){
                Student student = iter.next();
                System.out.println(student.getName());
            }

實例四:集合上的lazy=false,其它保持默認

//不會發出SQL語句
        Classes classes = (Classes)session.load(Classes.class, 1);
        //發出兩條SQL語句,分別加載classes和student
        //並且把集合中的數據也加載上來(雖然並沒有使用集合中的對象),因為設置了集合的lazy=false
        System.out.println("classes.name=" + classes.getName());
        
        //不會發SQL語句,因為已經在前面加載了數據
        Set<Student> students = classes.getStudents();
        
        //不會發SQL語句,因為已經在前面加載了數據
        System.out.println("student.count=" + students.size());

實例五:設置集合上lazy=extra,其它默認

session = HibernateUtils.getSession();
            tx = session.beginTransaction();
    
            //不會發出SQL語句
            Classes classes = (Classes)session.load(Classes.class, 1);

            //會發出SQL語句
            System.out.println("classes.name=" + classes.getName());
            
            //不會發出SQL語句,只返回代理類
            Set<Student> students = classes.getStudents();
            
            //會發出SQL語句
            for (Iterator<Student> iter = students.iterator();iter.hasNext();){
                Student student = iter.next();
                System.out.println(student.getName());
            }

實例六:設置集合上lazy=extra,其它默認

session = HibernateUtils.getSession();
        tx = session.beginTransaction();

        //不會發出SQL語句
        Classes classes = (Classes)session.load(Classes.class, 1);
        //發出兩條SQL語句
        System.out.println("classes.name=" + classes.getName());
        
        //不會發出SQL語句
        Set<Student> students = classes.getStudents();
        
        //發出SQL語句,發出一條比較智能的SQL語句(select count(id) form t_student where classesid=?)
        System.out.println("student.count=" + students.size());
        
        //提交事務
        tx.commit();

<one-to-one>、<many-to-one>單端關聯上的lazy(懶加載)屬性

Ø <one-to-one>、<many-to-one>單端關聯上,可以取值:false/proxy/noproxy(false/代理/不代理)

實例一:所有lazy屬性默認(支持懶加載)

session = HibernateUtils.getSession();
            tx = session.beginTransaction();

            //不發出SQL語句,支持lazy(懶加載)
            User user = (User) session.load(User.class, 3);
            //發出SQL語句,只加載普通屬性,集合中的數據不會加載
            System.out.println("user.name=" + user.getName());
            
            //不會發出SQL語句,只返回代理類
            Group group = user.getGroup();
            //發出SQL語句,因為現在真正使用對象
            System.out.println("group.name=" + group.getName());
            tx.commit();

實例二:將<many-to-one>中的lazy設置為false,其它默認

session = HibernateUtils.getSession();
            tx = session.beginTransaction();

            //不會發出SQL
            User user = (User) session.load(User.class, 3);
            //會發出SQL,發出兩條SQL,分別是User和組
            //因為<many-to-one>中的lazy=false,則會加載Group
            System.out.println("user.name=" + user.getName());
            
            //不會發出,已經在上面加載了數據
            Group group = user.getGroup();
            //不會發出,已經在上面加載了數據
            System.out.println("group.name=" + group.getName());
            tx.commit();

實例三:將<class>中的lazy設置為false,其它默認

session = HibernateUtils.getSession();
            tx = session.beginTransaction();

            //會發出SQL,因為<class>中的lazy=false
            User user = (User) session.load(User.class, 3);
            //不會發出SQL,已經在上面加載了
            System.out.println("user.name=" + user.getName());
            
            //不會發出,因為<class>標簽上的lazy只對普通屬性的影響
            //<class>標簽上的lazy不會影響到單端關聯上的lazy特性
            Group group = user.getGroup();
            //會發出,因為開始使用對象
            System.out.println("group.name=" + group.getName());

            tx.commit();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM