2.session生命周期(hibernate筆記)

一、持久化對象的狀態(tài)

來源于網(wǎng)絡(luò).jpg
  • 1.瞬時對象(Transient Objects)
    或臨時對象省有,使用new操作符初始化的對象不是立刻就持久化的硬梁。它們的狀態(tài)是瞬時的跃脊,也就是說它們沒有任何跟數(shù)據(jù)庫表相關(guān)聯(lián)的行為,只要應(yīng)用不再引用這些對象(不再被任何其它對象所引用)捧书,它們的狀態(tài)將會丟失吹泡,并由垃圾回收機制回收。沒有納入Session的管理鳄厌。

  • 2.持久化對象(Persistent Objects)
    持久化實例是任何具有數(shù)據(jù)庫標識的實例荞胡。它有持久化管理器Session統(tǒng)一管理,持久化實例是在事務(wù)中進行操作的-它們的狀態(tài)在事務(wù)結(jié)束時同數(shù)據(jù)庫集進行同步了嚎。當事務(wù)提交時泪漂,通過執(zhí)行sql的insert、update和delete語句把內(nèi)存中的狀態(tài)同步到數(shù)據(jù)庫中歪泳。納入到Session的管理萝勤,在清零緩存(臟數(shù)據(jù)檢查)的時候,會和數(shù)據(jù)庫同步呐伞。

  • 3.離線對象(Detached Objects)
    Session關(guān)閉后敌卓,持久化對象就變成離線對象。離線表示這個對象不能再與數(shù)據(jù)庫保持同步伶氢,它們不再受Hibernate管理趟径。在數(shù)據(jù)庫中有與之匹配的數(shù)據(jù)(和瞬時對象的主要區(qū)別,如瞬時對象就不能進行如updata操作)癣防,但是沒有納入Session的管理蜗巧。

示例:(工程hibernate_session
由于Session對象是一個重量級對象,所以我們采用單例模式:
HibernateUtils.java

package cn.itcast.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
    private static SessionFactory factory;
    
    static{
        try{
            //讀取配置文件
            Configuration cfg = new Configuration().configure();
            //初始化SessionFactory
            factory = cfg.buildSessionFactory();
            
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static SessionFactory getSessionFactory(){
        return factory;
    }
    public static Session getSession(){
        //Session由工廠產(chǎn)生
        return factory.openSession();
    }
    public static void closeSession(Session session){
        if(session != null){
            if(session.isOpen()){
                session.close();
            }
        }
    }
}

其他文件和上個例子基本一樣蕾盯,我們在這里新建一個數(shù)據(jù)庫hibernate_session幕屹,然后使用類ExportDB.java自動生成數(shù)據(jù)庫表。

測試:
SessionTest.java

package junit.test;
import java.util.Date;
import java.util.UUID;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.itcast.model.User;
import cn.itcast.util.HibernateUtils;
public class SessionTest {
    
    @Test
    public void testSave1(){
        Session session = null;
        Transaction transaction = null;
        User user = null;
        try{
            //得到Session
            session = HibernateUtils.getSession();
            //開啟事務(wù)
            transaction = session.beginTransaction();
            
            //Transient狀態(tài)(臨時狀態(tài))
            user = new User();
            user.setId(UUID.randomUUID().toString());
            user.setName("zhang");
            user.setPassword("1111");
            user.setCreateTime(new Date());
            user.setExpireTime(new Date());
            
            //persistent狀態(tài),當屬性發(fā)生改變的時候望拖,hibernate會自動和數(shù)據(jù)庫同步
            session.save(user);
            user.setName("tom");
            session.update(user);
            transaction.commit();

        }catch(Exception e){
            e.printStackTrace();
            transaction.rollback();
        }finally{
            HibernateUtils.closeSession(session);
        }
        
        //detached狀態(tài)(離線狀態(tài))
        user.setName("jack");
        try{
            session = HibernateUtils.getSession();
            session.beginTransaction();
            //persistent狀態(tài)
            session.update(user);
            session.getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateUtils.closeSession(session);
        }
    }
}

說明:可以看到當執(zhí)行save方法之后對象變?yōu)榱藀ersistent狀態(tài)渺尘,此時會發(fā)出insert語句,同時此時的狀態(tài)下说敏,如果我們修改對象鸥跟,在提交事務(wù)的時候會清理緩存(或叫臟數(shù)據(jù)檢查),會將新的對象存到數(shù)據(jù)庫中盔沫,發(fā)出update語句锌雀。而當Session關(guān)閉之后,對象變成了離線狀態(tài)迅诬,此時如果我們想修改數(shù)據(jù)庫中對象的值腋逆,那么需要重新獲取Session并開啟事務(wù),最后提交侈贷。

測試get方法:

@Test
    public void testReadByGetMethod1(){
        Session session = null;
        try{
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //會立即發(fā)出查詢語句惩歉,加載User對象,此時對象是persistent狀態(tài)
            User user = (User) session.get(User.class, "61bb68a4-5835-4825-8fa5-a93c41f2987f");
            System.out.println("user.name = " + user.getName());
            
            //persistent狀態(tài)下改變對象會自動和數(shù)據(jù)庫同步
            user.setName("tom");
            session.getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateUtils.closeSession(session);
        }
    }

說明:其中g(shù)et方法的第二個參數(shù)是上個測試例子中存入數(shù)據(jù)的id俏蛮,試驗可知撑蚌,當使用get方法時會立即發(fā)出查詢語句,對象稱為persistent狀態(tài)搏屑,此時改變對象會在事務(wù)提交的時候清理緩存争涌,發(fā)出修改語句。但是辣恋,如果我們給出的id號在數(shù)據(jù)庫中不存在亮垫,那么get方法返回null。

測試load方法:

@Test
    public void testReadByLoadMethod1(){
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            //執(zhí)行l(wèi)oad方法時不會立即發(fā)出查詢語句伟骨,而是在要使用此對象的時候才會發(fā)出饮潦,比如下面的打印語句
            //因為load方法實現(xiàn)了lazy方法(懶加載或延遲加載)
            User user = (User) session.load(User.class, "61bb68a4-5835-4825-8fa5-a93c41f2987f");
            //執(zhí)行下面這條語句的時候才會發(fā)出查詢語句
            System.out.println("user.name = " + user.getName());
            
            user.setName("jack");
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateUtils.closeSession(session);
        }
    }

說明:這里要注意load方法和get方法的區(qū)別,load方法采用的是延遲加載携狭,只有當要使用對象的時候才會去數(shù)據(jù)庫中查詢继蜡。同時如果我們給出的id號在數(shù)據(jù)庫中不存在,則會拋出ObjectNotFoundException異常逛腿。

測試update方法:

@Test
    public void testUpdate1(){
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            //手動構(gòu)造的detached對象
            User user = new User();
            user.setId("61bb68a4-5835-4825-8fa5-a93c41f2987f");
            user.setName("德華");
            user.setPassword("2222");
            session.update(user);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateUtils.closeSession(session);
        }
    }

說明:手動構(gòu)造detached狀態(tài)對象時我們給出的id必須是數(shù)據(jù)庫中存在的稀并,不然會拋出異常。同時表明detached對象可以update单默。雖然這里的對象是我們new出來的碘举,但是在數(shù)據(jù)庫中是有與之對應(yīng)的主鍵的,所以是detached狀態(tài)對象雕凹。

測試delete方法:

@Test
    public void testDelete1(){
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            User user = (User) session.load(User.class, "61bb68a4-5835-4825-8fa5-a93c41f2987f");
            session.delete(user);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateUtils.closeSession(session);
        }
        //刪除之后稱為Transient狀態(tài)
    }

說明:這里我們可以看到從數(shù)據(jù)庫中刪除數(shù)據(jù)之后對象成為了Transient狀態(tài)殴俱。本來對象是persistent狀態(tài),刪除之后就變?yōu)門ransient狀態(tài)枚抵。

最后:

  • get和load方法的區(qū)別是get不支持lazy线欲,而load支持;采用get加載數(shù)據(jù)汽摹,如果沒有與之匹配的數(shù)據(jù)返回null李丰,而load則拋出異常。
  • Transient狀態(tài)的特征是:在數(shù)據(jù)庫中沒有與之匹配的數(shù)據(jù)逼泣,沒有納入Session的管理趴泌。
  • detached的特征是:在數(shù)據(jù)庫中有與之匹配的數(shù)據(jù),也沒有納入Session的管理拉庶。
  • get和load方法都只能根據(jù)主鍵進行查詢嗜憔,即單一查詢。

二氏仗、Query接口入門

我們可以使用Query接口發(fā)送hql語句進行查詢吉捶。
QueryTest.java

package junit.test;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.junit.Test;
import cn.itcast.model.User;
import cn.itcast.util.HibernateUtils;

public class QueryTest {
    
    @Test
    public void testQuery(){
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            Query query = session.createQuery("from User");
            //查詢從哪里開始
            query.setFirstResult(0);
            //查詢出多少條數(shù)據(jù)
            query.setMaxResults(2);
            //查詢出的數(shù)據(jù)Query接口會自動幫我們存入到一個List集合中
            List<User> list = query.list();
            for(User user : list){
                System.out.println(user.getId());
                System.out.println(user.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateUtils.closeSession(session);
        }
    }
}

說明:這里我們可以使用hql語句將所有數(shù)據(jù)都查詢出來,同時還可以進行分頁皆尔,對于hql語句呐舔,它是針對對象的查詢語句,所以對于對象名是區(qū)分大小寫的慷蠕。查詢出來都 數(shù)據(jù)Query接口會自動幫我們存入到一個List集合中珊拼。在后面我們還會詳細說明。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末流炕,一起剝皮案震驚了整個濱河市澎现,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌每辟,老刑警劉巖昔头,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異影兽,居然都是意外死亡揭斧,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門峻堰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來讹开,“玉大人,你說我怎么就攤上這事捐名〉┩颍” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵镶蹋,是天一觀的道長成艘。 經(jīng)常有香客問我赏半,道長,這世上最難降的妖魔是什么淆两? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任断箫,我火速辦了婚禮,結(jié)果婚禮上秋冰,老公的妹妹穿的比我還像新娘仲义。我一直安慰自己,他們只是感情好剑勾,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布埃撵。 她就那樣靜靜地躺著,像睡著了一般虽另。 火紅的嫁衣襯著肌膚如雪暂刘。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天捂刺,我揣著相機與錄音鸳惯,去河邊找鬼。 笑死叠萍,一個胖子當著我的面吹牛芝发,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播苛谷,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼辅鲸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了腹殿?” 一聲冷哼從身側(cè)響起独悴,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锣尉,沒想到半個月后刻炒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡自沧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年坟奥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拇厢。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡爱谁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出孝偎,到底是詐尸還是另有隱情访敌,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布衣盾,位于F島的核電站寺旺,受9級特大地震影響爷抓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜阻塑,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一蓝撇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧叮姑,春花似錦、人聲如沸据悔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽极颓。三九已至朱盐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間菠隆,已是汗流浹背兵琳。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留骇径,地道東北人躯肌。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像破衔,于是被迫代替她去往敵國和親清女。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容