Hibernate學習9—檢索策略

來源:互聯網
上載者:User

標籤:gets   style   where   slist   配置   this   hibernate   代理類   generator   

本章,採用Class和Student     ——  1 對 多的關係;

Student.java:

package com.cy.model;public class Student {    private int id;    private String name;    private Class c;        public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Class getC() {        return c;    }    public void setC(Class c) {        this.c = c;    }        }
View Code

Class.java:

package com.cy.model;import java.util.HashSet;import java.util.Set;public class Class {    private int id;    private String name;    private Set<Student> students = new HashSet<Student>();            public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Set<Student> getStudents() {        return students;    }    public void setStudents(Set<Student> students) {        this.students = students;    }        }
View Code

Student.hbm.xml:

<hibernate-mapping package="com.cy.model">    <class name="Student" table="t_student">        <id name="id" column="stuId">            <generator class="native"></generator>        </id>        <property name="name" column="stuName"></property>                <many-to-one name="c" column="classId" class="com.cy.model.Class" cascade="save-update" lazy="proxy"></many-to-one>            </class></hibernate-mapping>
View Code

Class.hbm.xml:

<hibernate-mapping package="com.cy.model">    <class name="Class" table="t_class">        <id name="id" column="classId">            <generator class="native"></generator>        </id>        <property name="name" column="className"></property>                <set name="students" cascade="save-update" inverse="true" lazy="false" batch-size="3" fetch="join">            <key column="classId"></key>            <one-to-many class="com.cy.model.Student" />        </set>    </class></hibernate-mapping>
View Code

 

第一節:檢索策略屬性Lazy                                                  

Lazy:true:預設延遲檢索:用到才載入

    @Test    public void testLazy1(){        //因為在class.hbm中set端,一對多,配置的是lazy=true,載入class的時候,預設是不載入學生的。        Class c = (Class) session.get(Class.class, 1);                    //等到什麼時候會查詢學生資料?——等到他用的時候        //等到用到的時候才去檢索,這就是延遲檢索        Set<Student> students = c.getStudents();                System.out.println(students.size());        //        Iterator it = students.iterator();            }
View Code lazy:false: 查詢class,如果肯定會用到student資訊的話,可以立即檢索;設定lazy false也行的 lazy:extra:也是延遲的,但是增強;比如:配置lazy為true的話,想知道查詢出來學生數量的話:Class c = (Class) session.get(Class.class, 1);Set<Student> students = c.getStudents();System.out.println(students.size());發出的sql為查詢所有學生,然後知道3條記錄;但是其實只需要select count(*) from student就行了,這就是sql最佳化。配置lazy=extra就能實現;但是實際開發用的也不多,因為很少只查詢size的情況; lazy:proxy:取Student資訊的時候,裡面的班級Class是代理類,是不包含資料的;但是用到Class裡面內容的時候,就通過代理類去資料庫查詢內容了。
    @Test    public void testLazy2(){        //many to one端,預設lazy - proxy。取出的student中的Class是一個代理類。沒有實際資料        Student student = (Student) session.get(Student.class, 1);                //等到用到class的名字的時候,代理類才去發出sql查詢資料。        student.getC().getName();    }
View Code lazy:no-proxy:沒有代理類,取student的時候,裡面的class是個null值,等到用class內容了,再去查。很少用.......

 

第二節:檢索策略屬性batch-size                                          

1,批量延遲檢索;

對應的class.hbm配置:lazy="true" batch-size="3"

/**     * 批量延遲檢索,lazy=true     */    @Test    public void testBatch1(){        List<Class> classList = session.createQuery("from Class").list();        Iterator<Class> it = classList.iterator();        Class c1 = it.next();        Class c2 = it.next();        Class c3 = it.next();        c1.getStudents().iterator();        c2.getStudents().iterator();        c3.getStudents().iterator();                //先取出所有class,因為set students端配置了lazy=false        //等到c1、c2、c3用到student的時候,才去尋找。每個發出一條sql語句。        //假如classList很多很多的話,遍曆每個class,然後取每個class下面的students,每個都發出一條sql,這樣效率就很低了。        //所以,引入了batch-size,批量檢索。batch-size的值為批量的值                //在class.hbm.  set studens端,配置batch-size=3,發出的sql就是這樣了:        /**         * SELECT                 t_student.classId ,                 t_student.stuId ,                 t_student.stuName            FROM t_student            WHERE t_student.classId IN (1, 2, 3)         */    }
View Code

而未設定批量檢索batch-size,發出的sql是下面這樣,一條一條的查:

設定了批量檢索,batch-size=3後,查詢student資訊時,一次查3條;

 

2,批量立即檢索;

@Test    public void testBatch2(){        List<Class> classList = session.createQuery("from Class").list();        //這裡class.hbm.xml set students中配置lazy=false,batch-size=3,就是批量立即檢索了.        //發出的批量sql和上面一樣。        }
View Code

 

第三節:檢索策略屬性Fetch                                      

Fetch這裡也是在class端配置的; fetch:subselect,在資料量很大的時候,使用子查詢,可以使效能得到最佳化點。 
@Test    public void testFetch1(){        List<Class> classList = session.createQuery("from Class").list();        Iterator<Class> it = classList.iterator();        Class c1 = it.next();        Class c2 = it.next();        Class c3 = it.next();        c1.getStudents().iterator();        c2.getStudents().iterator();        c3.getStudents().iterator();        /**         * class.hbm set students 配置fetch="select",是預設的,發出的sql:         * SELECT                 t_student.classId ,                 t_student.stuId ,                 t_student.stuName            FROM t_student            WHERE t_student.classId IN (1, 2, 3)                                    現在改為fetch=subselect:sql變成了:            SELECT                 t_student.classId ,                 t_student.stuId ,                 t_student.stuName            FROM t_student            WHERE t_student.classId IN            (SELECT classId FROM t_class )         *          */    }
View Code

 

fetch:join:

@Test    public void testFetch2(){        Class c = (Class) session.get(Class.class, 1);        /**         * 這裡class.hbm配置:<set name="students" lazy="false" fetch="join">         * 查詢班級的時候,把屬於這個班級的學生也一起查出來,這裡fetch=join,sql中left outer join:         * 發出的sql:         * SELECT                t_class.classId,                t_class.className,                t_student.stuId,                t_student.stuName,                t_student.classId            FROM t_class            LEFT OUTER JOIN t_student ON t_class.classId = t_student.classId            WHERE t_class.classId = 1                     * 可以看到只發出一條sql語句了,t_class表和t_student表關聯,將class資訊和student資訊一起取了出來;         *          * 而如果fetch為select,是先取班級資訊;再取student資訊         */    }
View Code

 

Hibernate學習9—檢索策略

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.