最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?hibernate延遲加載get和load的區(qū)別

 更新時(shí)間:2022年09月23日 10:31:51   作者:文渡???????  
這篇文章主要介紹了Java?hibernate延遲加載get和load的區(qū)別,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

前言

在hibernate中我們知道如果要從數(shù)據(jù)庫(kù)中得到一個(gè)對(duì)象,通常有兩種方式,一種是通過session.get()方法,另一種就是通過session.load()方法,然后其實(shí)這兩種方法在獲得一個(gè)實(shí)體對(duì)象時(shí)是有區(qū)別的,在查詢性能上兩者是不同的。

一.load加載方式

當(dāng)使用load方法來得到一個(gè)對(duì)象時(shí),此時(shí)hibernate會(huì)使用延遲加載的機(jī)制來加載這個(gè)對(duì)象,即:當(dāng)我們使用session.load()方法來加載一個(gè)對(duì)象時(shí),此時(shí)并不會(huì)發(fā)出sql語(yǔ)句,當(dāng)前得到的這個(gè)對(duì)象其實(shí)是一個(gè)代理對(duì)象,這個(gè)代理對(duì)象只保存了實(shí)體對(duì)象的id值,只有當(dāng)我們要使用這個(gè)對(duì)象,得到其它屬性時(shí),這個(gè)時(shí)候才會(huì)發(fā)出sql語(yǔ)句,從數(shù)據(jù)庫(kù)中去查詢我們的對(duì)象。

session = HibernateUtil.openSession(); /* * 通過load的方式加載對(duì)象時(shí),會(huì)使用延遲加載機(jī)制,此時(shí)并不會(huì)發(fā)出sql語(yǔ)句,只有當(dāng)我們需要使用的時(shí)候才會(huì)從數(shù)據(jù)庫(kù)中去查詢 */ User user = (User)session.load(User.class, 2);

我們看到,如果我們僅僅是通過load來加載我們的User對(duì)象,此時(shí)從控制臺(tái)我們會(huì)發(fā)現(xiàn)并不會(huì)從數(shù)據(jù)庫(kù)中查詢出該對(duì)象,即并不會(huì)發(fā)出sql語(yǔ)句,但如果我們要使用該對(duì)象時(shí):

session = HibernateUtil.openSession();
      User user = (User)session.load(User.class, 2);
      System.out.println(user);

此時(shí)我們看到控制臺(tái)會(huì)發(fā)出了sql查詢語(yǔ)句,會(huì)將該對(duì)象從數(shù)據(jù)庫(kù)中查詢出來:

Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.born as born0_0_ from user user0_ where user0_.id=? User [id=2, username=aaa, password=111, born=2013-10-16 00:14:24.0]

這個(gè)時(shí)候我們可能會(huì)想,那么既然調(diào)用load方法時(shí),并不會(huì)發(fā)出sql語(yǔ)句去從數(shù)據(jù)庫(kù)中查出該對(duì)象,那么這個(gè)User對(duì)象到底是個(gè)什么對(duì)象呢?

其實(shí)這個(gè)User對(duì)象是我們的一個(gè)代理對(duì)象,這個(gè)代理對(duì)象僅僅保存了id這個(gè)屬性:

session = HibernateUtil.openSession(); /* * 通過load的方式加載對(duì)象時(shí),會(huì)使用延遲加載機(jī)制,此時(shí)得到的User對(duì)象其實(shí)是一個(gè)
             * 代理對(duì)象,該代理對(duì)象里面僅僅只有id這個(gè)屬性 */ User user = (User)session.load(User.class, 2);
            System.out.println(user.getId());

      console:  2 

我們看到,如果我們只打印出這個(gè)user對(duì)象的id值時(shí),此時(shí)控制臺(tái)會(huì)打印出該id值,但是同樣不會(huì)發(fā)出sql語(yǔ)句去從數(shù)據(jù)庫(kù)中去查詢。這就印證了我們的這個(gè)user對(duì)象僅僅是一個(gè)保存了id的代理對(duì)象,但如果我需要打印出user對(duì)象的其他屬性值時(shí),這個(gè)時(shí)候會(huì)不會(huì)發(fā)出sql語(yǔ)句呢?答案是肯定的:

 session = HibernateUtil.openSession(); /* * 通過load的方式加載對(duì)象時(shí),會(huì)使用延遲加載機(jī)制,此時(shí)得到的User對(duì)象其實(shí)是一個(gè)
             * 代理對(duì)象,該代理對(duì)象里面僅僅只有id這個(gè)屬性 */ User user = (User)session.load(User.class, 2);
            System.out.println(user.getId()); // 如果此時(shí)要得到user其他屬性,則會(huì)從數(shù)據(jù)庫(kù)中查詢
            System.out.println(user.getUsername());   

此時(shí)我們看控制臺(tái)的輸出:

2 Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.born as born0_0_ from user user0_ where user0_.id=? aaa

相信通過上述的幾個(gè)例子,大家應(yīng)該很好的了解了load的這種加載對(duì)象的方式了吧。

二、get加載方式

相對(duì)于load的延遲加載方式,get就直接的多,當(dāng)我們使用session.get()方法來得到一個(gè)對(duì)象時(shí),不管我們使不使用這個(gè)對(duì)象,此時(shí)都會(huì)發(fā)出sql語(yǔ)句去從數(shù)據(jù)庫(kù)中查詢出來:

session = HibernateUtil.openSession(); /* * 通過get方法來加載對(duì)象時(shí),不管使不使用該對(duì)象,都會(huì)發(fā)出sql語(yǔ)句,從數(shù)據(jù)庫(kù)中查詢 */ User user = (User)session.get(User.class, 2);

此時(shí)我們通過get方式來得到user對(duì)象,但是我們并沒有使用它,但是我們發(fā)現(xiàn)控制臺(tái)會(huì)輸出sql的查詢語(yǔ)句:

Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.born as born0_0_ from user user0_ where user0_.id=?

因此我們可以看到,使用load的加載方式比get的加載方式性能要好一些,因?yàn)閘oad加載時(shí),得到的只是一個(gè)代理對(duì)象,當(dāng)真正需要使用這個(gè)對(duì)象時(shí)再去從數(shù)據(jù)庫(kù)中查詢。

三、使用get和load時(shí)的一些小問題

當(dāng)了解了load和get的加載機(jī)制以后,我們此時(shí)來看看這兩種方式會(huì)出現(xiàn)的一些小問題:

①如果使用get方式來加載對(duì)象,當(dāng)我們?cè)噲D得到一個(gè)id不存在的對(duì)象時(shí),此時(shí)會(huì)報(bào)NullPointException的異常

session = HibernateUtil.openSession(); /* * 當(dāng)通過get方式試圖得到一個(gè)id不存在的user對(duì)象時(shí),此時(shí)會(huì)報(bào)NullPointException異常 */ User user = (User)session.get(User.class, 20);
            System.out.println(user.getUsername());

此時(shí)我們看控制臺(tái)的輸出信息,會(huì)報(bào)空指針的異常:

Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.born as born0_0_ from user user0_ where user0_.id=? java.lang.NullPointerException  .........

這是因?yàn)橥ㄟ^get方式我們會(huì)去數(shù)據(jù)庫(kù)中查詢出該對(duì)象,但是這個(gè)id值不存在,所以此時(shí)user對(duì)象是null,所以就會(huì)報(bào)NullPointException的異常了。

②如果使用load方式來加載對(duì)象,當(dāng)我們?cè)噲D得到一個(gè)id不存在的對(duì)象時(shí),此時(shí)會(huì)報(bào)ObjectNotFoundException異常:

session = HibernateUtil.openSession(); /* * 當(dāng)通過get方式試圖得到一個(gè)id不存在的user對(duì)象時(shí),此時(shí)會(huì)報(bào)ObjectNotFoundException異常 */ User user = (User)session.load(User.class, 20);
            System.out.println(user.getId());
            System.out.println(user.getUsername());

我們看看控制臺(tái)的輸出:

20 Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.born as born0_0_ from user user0_ where user0_.id=? org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.xiaoluo.bean.User#20]......

為什么使用load的方式和get的方式來得到一個(gè)不存在的對(duì)象報(bào)的異常不同呢??其原因還是因?yàn)閘oad的延遲加載機(jī)制,使用load時(shí),此時(shí)的user對(duì)象是一個(gè)代理對(duì)象,僅僅保存了當(dāng)前的這個(gè)id值,當(dāng)我們?cè)噲D得到該對(duì)象的username屬性時(shí),這個(gè)屬性其實(shí)是不存在的,所以就會(huì)報(bào)出ObjectNotFoundException這個(gè)異常了。

③org.hibernate.LazyInitializationException異常

接下來我們?cè)賮砜匆粋€(gè)例子:

public class UserDAO
{ public User loadUser(int id)
    {
        Session session = null;
        Transaction tx = null;
        User user =  null; try {
            session = HibernateUtil.openSession();
            tx = session.beginTransaction();
            user = (User)session.load(User.class, 1);
            tx.commit();
        } catch (Exception e)
        {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.close(session);
        } return user;
    }
} 
@Test public void testLazy06()
    {
        UserDAO userDAO = new UserDAO();
        User user = userDAO.loadUser(2);
        System.out.println(user);
    }

模擬了一個(gè)UserDAO這樣的對(duì)象,然后我們?cè)跍y(cè)試用例里面來通過load加載一個(gè)對(duì)象,此時(shí)我們發(fā)現(xiàn)控制臺(tái)會(huì)報(bào)LazyInitializationException異常

org.hibernate.LazyInitializationException: could not initialize proxy - no Session  .............

這個(gè)異常是什么原因呢??還是因?yàn)閘oad的延遲加載機(jī)制,當(dāng)我們通過load()方法來加載一個(gè)對(duì)象時(shí),此時(shí)并沒有發(fā)出sql語(yǔ)句去從數(shù)據(jù)庫(kù)中查詢出該對(duì)象,當(dāng)前這個(gè)對(duì)象僅僅是一個(gè)只有id的代理對(duì)象,我們還并沒有使用該對(duì)象,但是此時(shí)我們的session已經(jīng)關(guān)閉了,所以當(dāng)我們?cè)跍y(cè)試用例中使用該對(duì)象時(shí)就會(huì)報(bào)LazyInitializationException這個(gè)異常了。

所以以后我們只要看到控制臺(tái)報(bào)LazyInitializationException這種異常,就知道是使用了load的方式延遲加載一個(gè)對(duì)象了,解決這個(gè)的方法有兩種,一種是將load改成get的方式來得到該對(duì)象,另一種是在表示層來開啟我們的session和關(guān)閉session。

至此,hibernate的兩種加載方式get和load已經(jīng)分析完畢?。?!

到此這篇關(guān)于Java hibernate延遲加載get和load的區(qū)別的文章就介紹到這了,更多相關(guān)Java hibernate 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

延安市| 苍南县| 枝江市| 桓台县| 桦川县| 商南县| 克东县| 基隆市| 托克逊县| 南宫市| 邵东县| 安吉县| 榆林市| 张家口市| 商丘市| 砚山县| 磐安县| 阳东县| 桐庐县| 郎溪县| 灵山县| 深泽县| 黄龙县| 宜兴市| 阜平县| 洛川县| 平山县| 长寿区| 铁力市| 新晃| 永宁县| 额敏县| 宁南县| 夏津县| 江达县| 墨竹工卡县| 武义县| 神农架林区| 瑞安市| 白玉县| 张家川|