日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Hibernate之Session解析

發(fā)布時間:2025/3/20 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hibernate之Session解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.Session概述

  • Session接口是Hibernate向應(yīng)用程序提供的操縱數(shù)據(jù)庫最主要的接口,它提供了基本的保存,更新,刪除和加載java對象的方法

  • Session具有一個緩存,位于緩存中的對象成為持久化對象,它和數(shù)據(jù)庫中的相關(guān)記錄對應(yīng),Session能夠在某些時間點,按照緩存中對象的變化來執(zhí)行相關(guān)的SQL語句,來同步更新數(shù)據(jù)庫,這一過程被成為刷新緩存(flush)

  • 站在持久化的角度,Hibernate把對象分為4種狀態(tài):持久化狀態(tài),臨時狀態(tài),游離狀態(tài),刪除狀態(tài)。Session的特定方法能使對象從一個狀態(tài)轉(zhuǎn)換到另一個狀態(tài)

2.Session緩存

? ?@Testpublic void testGet() { ?Session session = getSession();NewsEntity newsEntity = (NewsEntity) session.get(NewsEntity.class, 2);NewsEntity newsEntity1 = (NewsEntity) session.get(NewsEntity.class, 2);System.out.println(newsEntity);System.out.println(newsEntity1);session.close();}

該方法只會向數(shù)據(jù)庫發(fā)送1條SQL語句。當進行第二次獲取時,會從Session緩存中獲取數(shù)據(jù),而不是去向數(shù)據(jù)庫查詢

3.操作Session緩存

(1)flush緩存

  • Session按照緩存中對象的屬性變化來同步更新數(shù)據(jù)庫

  • 默認情況下Session在以下時間點刷新緩存:

    • 顯示調(diào)用flush()方法

    • 調(diào)用Transaction的commit()方法(該方法先flush,再提交事務(wù))

    • 當應(yīng)用程序執(zhí)行一些查詢操作時,如果緩存中持久化對象的屬性已經(jīng)發(fā)生了變化,會flush緩存

  • 特殊情況:如果使用native生成器生成OID,那么當調(diào)用Session的save()方法保存對象,會立即執(zhí)行插入操作

(2)設(shè)定刷新緩存的時間點

  • 若希望改變flush的默認時間點,可以通過Session的setFlushMode()方法顯式設(shè)定flush的時間點

/*調(diào)用Session的查詢方法時,清理緩存,注意:這條規(guī)則必須保證顯式開啟的事務(wù)中調(diào)用Session.commit()時,清理緩存調(diào)用Session.flush()時,清理緩存 */ session.setFlushMode(FlushMode.AUTO); ? //默認模式 ? ? /* 調(diào)用Session的查詢方法時,不清理緩存調(diào)用Session.commit()時,不清理緩存調(diào)用Session.flush()時,清理緩存 */ session.setFlushMode(FlushMode.MANUAL); ? /*調(diào)用Session的查詢方法時,不清理緩存調(diào)用Session.commit()時,清理緩存調(diào)用Session.flush()時,清理緩存 */ session.setFlushMode(FlushMode.COMMIT); ? ? /* 調(diào)用Session的查詢方法時,清理緩存,注意:這條規(guī)則必須保證顯式開啟的事務(wù)中 調(diào)用Session.commit()時,清理緩存 調(diào)用Session.flush()時,清理緩存 */ session.setFlushMode(FlushMode.ALWAYS);

4.持久化對象的狀態(tài)

Hibernate把對象分為4種狀態(tài):

持久化狀態(tài),臨時狀態(tài),游離狀態(tài),刪除狀態(tài)

  • 臨時對象(Transient)

    • 在使用代理主鍵的情況下,OID通常為null

    • 不處于Session的緩存中

    • 在數(shù)據(jù)庫中沒有對應(yīng)的記錄

  • 持久化對象(Persist)

    • OID不為null

    • 位于Session緩存中

    • 若在數(shù)據(jù)庫中已經(jīng)有和其對應(yīng)的記錄,持久化對象和數(shù)據(jù)庫中的相關(guān)記錄對應(yīng)

    • Session在flush緩存時,會根據(jù)持久化對象的屬性變化,來同步更新數(shù)據(jù)庫

    • 在同一個Session實例的緩存中,數(shù)據(jù)庫表中的每條記錄只對應(yīng)唯一的持久化對象

  • 刪除對象(Removed)

    • 在數(shù)據(jù)庫中沒有和其OID對應(yīng)的記錄

    • 不再處于Session緩存中

    • 一般情況下,應(yīng)用程序不該再使用被刪除的對象

  • 游離對象(Detached)

    • OID不為null

    • 不再處于Session緩存中

    • 一般情況下,游離對象是由持久化對象轉(zhuǎn)變過來的,因此在數(shù)據(jù)庫中可能還存在與它對應(yīng)的記錄

5.對象的狀態(tài)轉(zhuǎn)換圖

6.save()方法

  • Session的save()方法使一個臨時對象轉(zhuǎn)變?yōu)槌志没瘜ο?/p>

  • 當對象為持久化狀態(tài)時,不允許程序隨意修改它的ID

@Testpublic void testAdd() { ?Session session = getSession();//3. 開啟事務(wù)Transaction transaction = session.beginTransaction();//4. 執(zhí)行保存操作NewsEntity newsEntity = new NewsEntity();newsEntity.setTitle("java語句很強嗎");newsEntity.setAuthor("hello123");newsEntity.setData(new Date());session.save(newsEntity);newsEntity.setId(5);//5. 提交事務(wù)transaction.commit();//6. 關(guān)閉 Sessionsession.close();}
  • save()之后,又修改了NewsEntity,程序會拋出異常

  • persist()和save()的區(qū)別:

/*** persist(): 也會執(zhí)行 INSERT 操作* * 和 save() 的區(qū)別 : * 在調(diào)用 persist 方法之前, 若對象已經(jīng)有 id 了, 則不會執(zhí)行 INSERT, 而拋出異常*/@Testpublic void testPersist(){Session session = getSession();//3. 開啟事務(wù)Transaction transaction = session.beginTransaction();//4. 執(zhí)行保存操作NewsEntity newsEntity = new NewsEntity();newsEntity.setTitle("測試");newsEntity.setAuthor("java555");newsEntity.setData(new Date());newsEntity.setId(333);session.persist(newsEntity);//5. 提交事務(wù)transaction.commit();//6. 關(guān)閉 Sessionsession.close();}/*** 1. save() 方法* 1). 使一個臨時對象變?yōu)槌志没瘜ο? 2). 為對象分配 ID.* 3). 在 flush 緩存時會發(fā)送一條 INSERT 語句.* 4). 在 save 方法之前的 id 是無效的* 5). 持久化對象的 ID 是不能被修改的!*/@Testpublic void testSave(){Session session = getSession();//3. 開啟事務(wù)Transaction transaction = session.beginTransaction();//4. 執(zhí)行保存操作NewsEntity newsEntity = new NewsEntity();newsEntity.setTitle("測試");newsEntity.setAuthor("java555");newsEntity.setData(new Date());newsEntity.setId(333);session.save(newsEntity);//5. 提交事務(wù)transaction.commit();//6. 關(guān)閉 Sessionsession.close(); // news.setId(101); }

7.get()和load()方法

/*** get VS load:* * 1. 執(zhí)行 get 方法: 會立即加載對象. * ? 執(zhí)行 load 方法, 若不適用該對象, 則不會立即執(zhí)行查詢操作, 而返回一個代理對象* ? ?* ? get 是 立即檢索, load 是延遲檢索. * * 2. load 方法可能會拋出 LazyInitializationException 異常: 在需要初始化* 代理對象之前已經(jīng)關(guān)閉了 Session* * 3. 若數(shù)據(jù)表中沒有對應(yīng)的記錄, Session 也沒有被關(guān)閉. ?* ? get 返回 null* ? load 若不使用該對象的任何屬性, 沒問題; 若需要初始化了, 拋出異常. ?*/ ?@Testpublic void testLoad(){Session session = getSession();NewsEntity news = (NewsEntity) session.load(NewsEntity.class, 1);System.out.println(news.getClass().getName()); ? // session.close(); // System.out.println(news); } ?@Testpublic void testGet1(){Session session = getSession();NewsEntity news = (NewsEntity) session.get(NewsEntity.class, 1); // session.close();System.out.println(news);}

8.update()方法

  • Session 的 update() 方法使一個游離對象轉(zhuǎn)變?yōu)槌志没瘜ο? 并且計劃執(zhí)行一條 update 語句.

  • 若希望 Session 僅當修改了 News 對象的屬性時, 才執(zhí)行 update() 語句, 可以把映射文件中 <class> 元素的 select-before-update 設(shè)為 true. 該屬性的默認值為 false

  • 當 update() 方法關(guān)聯(lián)一個游離對象時, 如果在 Session 的緩存中已經(jīng)存在相同 OID 的持久化對象, 會拋出異常

  • 當 update() 方法關(guān)聯(lián)一個游離對象時, 如果在數(shù)據(jù)庫中不存在相應(yīng)的記錄, 也會拋出異常

9.saveOrUpdate()方法

? ?/*** 注意:* 1. 若 OID 不為 null, 但數(shù)據(jù)表中還沒有和其對應(yīng)的記錄. 會拋出一個異常.* 2. 了解: OID 值等于 id 的 unsaved-value 屬性值的對象, 也被認為是一個游離對象*/@Testpublic void testSaveOrUpdate(){Session session = getSession();//3. 開啟事務(wù)Transaction transaction = session.beginTransaction();NewsEntity news = new NewsEntity("FFF", "fff", new Date());news.setId(11);session.saveOrUpdate(news);//5. 提交事務(wù)transaction.commit();//6. 關(guān)閉 Sessionsession.close();}

10.delete()方法

?/*** delete: 執(zhí)行刪除操作. 只要 OID 和數(shù)據(jù)表中一條記錄對應(yīng), 就會準備執(zhí)行 delete 操作* 若 OID 在數(shù)據(jù)表中沒有對應(yīng)的記錄, 則拋出異常** 可以通過設(shè)置 hibernate 配置文件 hibernate.use_identifier_rollback 為 true,* 使刪除對象后, 把其 OID 置為 null*/@Testpublic void testDelete(){Session session = getSession();NewsEntity news = (NewsEntity) session.get(NewsEntity.class, 23);session.delete(news); ?System.out.println(news);}

?

總結(jié)

以上是生活随笔為你收集整理的Hibernate之Session解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。