Hibernate中List和Iterate的區別

Hibernate中List和Iterate的區別

Hibernate在國內沒有國外那麼火,國內的ORM框架幾乎被Mybatis霸佔,因爲Hibernate的底層採用了大量的反射機制與緩存機制,所以對很多的地方都需要進行調優,而Mybatis的操作幾乎是傻瓜式。Hibernate有時候會因一點點配置的差異會導致項目響應出現極大的反差,今天我們就來說一下Hibernate中Query的兩個獲取對象集合的方法

Query中有兩個獲取對象集合的方法分別爲 List 和 Iterate 

 

List和Iterate的不同

List 和 Iterate 的不同主要是在一對多和多對一的時候體現出來的。

1、獲取的方式不同

// List的獲取方式
List<Invitation> list = query.list();

// Iterator的獲取方式
Iterator<Invitation> it = query.iterate();

2、List 只是查詢一級緩存,而Iterate還會查詢二級緩存

3、List方法返回的對象都是實體對象,而Iterator返回的是代理對象

4、session中的List第二次發出請求,仍會到數據庫査詢,而Iterate 第二次,首先找session 級緩存

 

List和Iterate的利與弊

List()方法在執行時,現在一級緩存中找,沒有再立馬到數據庫中查詢所需要的數據。對於List()方式的查詢通常只會執行一條SQL語句,List()方法會一次取出所有的結果集對象,以及對象屬性多對一的屬性數據,就是會依據查詢的結果初始化所有的結果集對象(多對一或者一對多)。如果在結果集的數據非常龐大的時候,就會佔據大量的內存,甚至會導致內存的溢出。

Iterator()方法則是先執行得到對象ID的查詢,然後在根據每個ID值去取得所要查詢的對象。而對於iterator()方法的查詢則可能需要執行N+1條SQL語句(N爲結果集中的記錄數),Iterator()方法在執行時不會一次初始化所有的對象,而是根據對結果集的訪問情況來初始化對象,如果你需要使用這個對象中的對象值,那麼它纔會到數據庫中查詢,而且一次在訪問中可以控制緩存中對象的數量,以避免佔用過多的緩存,導致內存溢出情況的發生。

 

實際調試的數據

測試環境:IDEA、Hibernate 5.4.10.Final、JUNIT 4.0、MySQL 8.0

list獲取數據的調試記錄

測試代碼:

@Test
    public void testGetList() {
        Session session = sf.openSession();

        String hql = "from Invitation";
        // list()方法在執行時,直接運行查詢結果所需要的查詢語句。
        // 對於list()方式的查詢通常只會執行一個SQL語句
        // list()方法會一次取出所有的結果集對象,而且他會依據查詢的結果初始化所有的結果集對象。
        // 如果在結果集非常龐大的時候會佔據非常多的內存,甚至會造成內存溢出的情況發生。
        Query<Invitation> query = session.createQuery(hql, Invitation.class);

        List<Invitation> list = query.list();
        for (Invitation l : list) {
            System.out.println(l);
        }
        session.close();
    }

Iterate的調試記錄

測試代碼:

@Test
    public void testGetIterate() {
        Session session = sf.openSession();
        // HQL 語句
        String hql = "from Invitation";
        // 獲取Query對象
        // iterator()方法則是先執行得到對象ID的查詢,然後在根據每個ID值去取得所要查詢的對象。
        // 而對於iterator()方法的查詢則可能需要執行N+1條SQL語句(N爲結果集中的記錄數).
        // iterator()方法在執行時不會一次初始化所有的對象,而是根據對結果集的訪問情況來初始化對象。
        // 一次在訪問中可以控制緩存中對象的數量,以避免佔用過多的緩存,導致內存溢出情況的發生。
        Query<Invitation> query = session.createQuery(hql, Invitation.class);
        Iterator<Invitation> iterate = query.iterate();
        Invitation invitation;
        while (iterate.hasNext()) {
            System.out.println("暫時沒有往數據庫中查詢數據");
            invitation = iterate.next();
            System.out.println(invitation);
        }
        session.close();
    }

發佈了45 篇原創文章 · 獲贊 9 · 訪問量 9702
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章