欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

淺談Hibernate對(duì)象狀態(tài)之間的神奇轉(zhuǎn)換

狀態(tài)分類(lèi)

劍河網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián),劍河網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為劍河成百上千提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站制作要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的劍河做網(wǎng)站的公司定做!

在Hibernate框架中,為了管理持久化類(lèi),Hibernate將其分為了三個(gè)狀態(tài):

  • 瞬時(shí)態(tài)(Transient Object)
  • 持久態(tài)(Persistent Object)
  • 脫管態(tài)(Detached Object)

有很多人好像對(duì)這些概念和它們之間的轉(zhuǎn)換不太明白,那么本篇文章就是來(lái)解決這些問(wèn)題的,看完了還不會(huì)你來(lái)找我。(開(kāi)個(gè)玩笑~~)

詳細(xì)描述

我們先來(lái)詳細(xì)地了解一下三種狀態(tài):

1、瞬時(shí)態(tài)

對(duì)象由new操作符創(chuàng)建,且尚未與Hibernate中的Session關(guān)聯(lián)的對(duì)象被認(rèn)為處于瞬時(shí)態(tài)。瞬時(shí)態(tài)對(duì)象不會(huì)被持久化到數(shù)據(jù)庫(kù)中,也不會(huì)賦予持久化標(biāo)識(shí),如果程序中失去了瞬時(shí)態(tài)對(duì)象的引用,瞬時(shí)態(tài)對(duì)象將被垃圾回收機(jī)制銷(xiāo)毀。

2、持久態(tài)

持久化實(shí)例在數(shù)據(jù)庫(kù)中有對(duì)應(yīng)的記錄,并擁有一個(gè)持久化標(biāo)識(shí)。持久化的實(shí)例可以是剛剛保存的,也可以是剛剛被加載的。無(wú)論哪一種,持久化對(duì)象都必須與指定的Session對(duì)象關(guān)聯(lián)。

3、脫管態(tài)

某個(gè)實(shí)例曾經(jīng)處于持久化狀態(tài),但隨著與之關(guān)聯(lián)的Session被關(guān)閉,該對(duì)象就變成脫管狀態(tài)。脫管狀態(tài)的引用引用依然有效,對(duì)象可繼續(xù)被修改。如果重新讓脫管對(duì)象與某個(gè)Session關(guān)聯(lián),該脫管對(duì)象會(huì)重新轉(zhuǎn)換為持久化狀態(tài)。

瞬時(shí)態(tài)持久態(tài)脫管態(tài)
是否存于Session緩存中××
數(shù)據(jù)庫(kù)中是否有對(duì)應(yīng)記錄×

例如:

public class HibernateTest {

	private Session session;
	private Transaction transaction;

	@Before
	public void before() {
		session = HibernateUtil.getSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void after() {
		transaction.commit();
		session.close();
	}

	@Test
	public void test() {
		Person p = new Person();
		p.setPname("張三");
		p.setAge(20);
		session.save(p);
	}
}

那么在這樣的一個(gè)例子中,從創(chuàng)建Person對(duì)象到給name和age屬性賦值,這些過(guò)程都處于瞬時(shí)態(tài),而當(dāng)調(diào)用了session對(duì)象的save()方法之后,該對(duì)象才從瞬時(shí)態(tài)轉(zhuǎn)為了持久態(tài)。而當(dāng)session關(guān)閉之后,該對(duì)象又從持久態(tài)轉(zhuǎn)為了脫管態(tài)。

對(duì)象狀態(tài)之間的轉(zhuǎn)換

了解了三種對(duì)象狀態(tài)的相關(guān)概念后,我們來(lái)看一看三種對(duì)象狀態(tài)之間是如何神奇地相互轉(zhuǎn)換的。

瞬時(shí)態(tài) <——> 持久態(tài)

我們知道當(dāng)創(chuàng)建一個(gè)對(duì)象之后,該對(duì)象即為瞬時(shí)態(tài),那么它將如何轉(zhuǎn)換為持久態(tài)呢?
看一個(gè)例子:

@Test
public void test() {
	Person p = new Person();
	p.setPid(2);
	p.setPname("李四");
	p.setAge(30);
	session.save(p);
	//session.saveOrUpdate(p);
}

給name和age屬性賦值時(shí),該對(duì)象仍然處于瞬時(shí)態(tài),這個(gè)前面已經(jīng)說(shuō)過(guò)了。但需要注意的是,當(dāng)給主鍵也就是Pid屬性賦值時(shí),該對(duì)象將不再處于瞬時(shí)態(tài),而是轉(zhuǎn)換為脫管態(tài),因?yàn)榇藭r(shí)已經(jīng)有了持久化標(biāo)識(shí),但是并沒(méi)有與Session發(fā)生關(guān)聯(lián)。而當(dāng)調(diào)用session對(duì)象的update()或者saveOrUpdate()方法時(shí),該對(duì)象才會(huì)轉(zhuǎn)換為持久態(tài)。
當(dāng)然,調(diào)用session對(duì)象的get()、load()、query、find()等方法從數(shù)據(jù)庫(kù)中查詢(xún)得到的對(duì)象也處于持久態(tài)。
而僅僅當(dāng)session對(duì)象調(diào)用delete()方法將一個(gè)持久化的對(duì)象從數(shù)據(jù)庫(kù)中刪除后,該對(duì)象才從持久態(tài)轉(zhuǎn)為了瞬時(shí)態(tài)。

持久態(tài) <——> 脫管態(tài)

當(dāng)調(diào)用session對(duì)象的close()、clear()等方法后,該session所關(guān)聯(lián)的對(duì)象將從持久態(tài)轉(zhuǎn)為脫管態(tài),此時(shí)這些對(duì)象失去了相關(guān)session的關(guān)聯(lián)。而要想從脫管態(tài)轉(zhuǎn)回持久態(tài),只需調(diào)用save()、saveOrUpdate()等方法即可。

瞬時(shí)態(tài) ——> 脫管態(tài)

這個(gè)前面也已經(jīng)說(shuō)過(guò)了,當(dāng)創(chuàng)建對(duì)象后調(diào)用setXXX()方法設(shè)置主鍵屬性時(shí),該對(duì)象就從瞬時(shí)態(tài)轉(zhuǎn)為脫管態(tài),前提是這個(gè)主鍵是數(shù)據(jù)庫(kù)中存在的。

對(duì)象生命周期

淺談Hibernate對(duì)象狀態(tài)之間的神奇轉(zhuǎn)換

下面以一個(gè)對(duì)象從創(chuàng)建到保存至數(shù)據(jù)庫(kù)的流程做一個(gè)分析:

try {
	Session session = HibernateUtil.openSession();
	//開(kāi)始事務(wù)
	session.beginTransaction();
	//person對(duì)象進(jìn)入瞬時(shí)狀態(tài)態(tài)
	Person p = new Person();
	p.setPname("王五");
	p.setAge(40);
	//person對(duì)象進(jìn)入持久化狀態(tài)
	session.save(p);
	//提交事務(wù),隱式包含了session.flush()的動(dòng)作
	session.getTransaction().commit();
	//提交完成后,person處于游離狀態(tài)
} catch (HibernateException e) {
	e.printStackTrace();
	if (session != null)
	session.getTransaction().rollback();
} finally {
	if (session != null)
	session.close();
}

當(dāng)一個(gè)對(duì)象被實(shí)例化后,該對(duì)象是瞬時(shí)狀態(tài),當(dāng)調(diào)用session.save(Object)后,該對(duì)象被加入到session緩存中,進(jìn)入持久化狀態(tài),這時(shí)數(shù)據(jù)庫(kù)中還不存在對(duì)應(yīng)的記錄。當(dāng)session提交事務(wù)后,數(shù)據(jù)庫(kù)生成了對(duì)應(yīng)的記錄,但是這里需要注意一點(diǎn),因?yàn)槭聞?wù)提交的時(shí)候默認(rèn)會(huì)去調(diào)用session.flush()方法來(lái)清空緩存,相當(dāng)于調(diào)用了clear()方法,而我們知道,調(diào)用了clear()方法,對(duì)象會(huì)從持久態(tài)轉(zhuǎn)為脫管態(tài)。而處于脫管態(tài)的對(duì)象會(huì)被垃圾回收機(jī)制銷(xiāo)毀。這就是一個(gè)對(duì)象從創(chuàng)建到保存至數(shù)據(jù)庫(kù)的完整生命周期過(guò)程。

其它

對(duì)于對(duì)象狀態(tài)有了一定的了解之后,可以用來(lái)解釋很多現(xiàn)象。

在Hibernate中,唯有當(dāng)對(duì)象從其它狀態(tài)轉(zhuǎn)為持久態(tài)時(shí),它才會(huì)去自動(dòng)生成sql語(yǔ)句,其它時(shí)候是不會(huì)去重復(fù)生成sql,這就是Hibernate框架提高效率的關(guān)鍵所在。

例如:

@Test
public void test2() {
	Session session = HibernateUtil.getSession();
	Transaction transaction = session.beginTransaction();
	Person p = new Person();
	p.setPname("李四");
	p.setAge(30);
	session.save(p);
	p.setPname("王五");
	session.update(p);
	transaction.commit();
	session.close();
}

我在transaction.commit();這條語(yǔ)句上打了一個(gè)斷電,然后調(diào)試運(yùn)行。

淺談Hibernate對(duì)象狀態(tài)之間的神奇轉(zhuǎn)換

可以看到,控制臺(tái)只輸出了一條sql語(yǔ)句,也就是執(zhí)行save()方法時(shí)生成的插入語(yǔ)句,但是執(zhí)行update()方法卻并沒(méi)有生成sql。這是因?yàn)樵趫?zhí)行update()方法時(shí),Hibernate框架會(huì)去判斷當(dāng)前對(duì)象的狀態(tài),它發(fā)現(xiàn)當(dāng)前對(duì)象處于持久態(tài),所以不重復(fù)生成sql,只是將持久態(tài)對(duì)象的值改變而已,然后調(diào)用commit()方法進(jìn)行事務(wù)提交的時(shí)候才去生成更新語(yǔ)句。

我們繼續(xù)看一個(gè)例子:

@Test
public void test2() {
	Session session = HibernateUtil.getSession();
	Transaction transaction = session.beginTransaction();
	Person p = new Person();
	p.setPname("張三");
	p.setAge(30);
	session.save(p);//此時(shí)該對(duì)象從瞬時(shí)態(tài)轉(zhuǎn)為持久態(tài),生成sql語(yǔ)句
		
	p.setPname("王五");
	session.save(p);//此時(shí)該對(duì)象為持久態(tài),不生成sql語(yǔ)句
	
	p.setPname("趙六");
	session.update(p);//此時(shí)該對(duì)象為持久態(tài),不生成sql語(yǔ)句
	
	transaction.commit();
	session.close();
}

你要知道,這跟你調(diào)用哪個(gè)方法是無(wú)關(guān)的,關(guān)鍵在于對(duì)象的狀態(tài),只有轉(zhuǎn)為持久態(tài)時(shí)才會(huì)生成sql語(yǔ)句。所以上面的程序段依然只會(huì)產(chǎn)生兩條sql,一條是save()方法產(chǎn)生的,一條是commit()方法產(chǎn)生的。
控制臺(tái)信息如下:

Hibernate: 
  insert 
  into
    PERSON
    (PNAME, AGE) 
  values
    (?, ?)
Hibernate: 
  update
    PERSON 
  set
    PNAME=?,
    AGE=? 
  where
    PID=?

理解Hibernate的三種狀態(tài),將更有利于理解Hibernate的運(yùn)行機(jī)制,這些可以讓你在開(kāi)發(fā)中對(duì)疑點(diǎn)問(wèn)題的定位產(chǎn)生關(guān)鍵性的幫助。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

網(wǎng)頁(yè)名稱(chēng):淺談Hibernate對(duì)象狀態(tài)之間的神奇轉(zhuǎn)換
本文路徑:http://aaarwkj.com/article46/gpiohg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、云服務(wù)器動(dòng)態(tài)網(wǎng)站、App設(shè)計(jì)外貿(mào)建站、

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)
美女被强到爽高潮不断在线| 亚洲三级成人一区在线| 亚洲欧美综合伊人看片综合| 亚洲午夜经典一区二区日韩| 国产亚洲黄片免费在线观看| 综合久久99中文综合久久| 国产av无毛一区二区三区| 亚洲午夜一区二区精品| 日本道视频一区二区三区| 日本的一级片一区二区| 男人午夜激情免费网站| 大龄熟妇丰满有水多毛浓| 亚洲成人av毛片在线观看| 国产精品久久久久精品日日三级| 国产日韩欧美高清免费视频| 日韩av一区二区久久久| 日韩毛片中文字幕在线观看| 校园春色亚洲欧美日韩| 亚洲av乱码国产精品观看| 国产精品亚洲伦理在线| 国产蜜臀视频一区二区三区| 四虎在线观看免费资源| 日本不卡一区二区在线观看| 国产免费不卡午夜福利在线| 日韩专区亚洲专区欧美专区| 日韩精品欧美成人高清一区二区 | 久久亚洲一区二区内射| 国产亚洲理论片在线观看| 欧美日韩电影一区二区三区在线观看| 欧美在线观看日韩精品| 亚洲狠狠爱一区二区三区| 国产亚洲av麻豆精品推荐| 一区二区三区毛片av网站| 欧美精品欧美激情免费区| 亚洲综合欧美日韩一区 | 日本特黄高清免费大片| 欧美一区二区三区情色| 亚洲精品中文字幕码专区| 亚洲av毛片在线免费播放| 97精品少妇一区二区三区| 国产毛片一区二区在线|