Hibernate應(yīng)用及其詳解(強(qiáng)力推薦)_第1頁(yè)
Hibernate應(yīng)用及其詳解(強(qiáng)力推薦)_第2頁(yè)
Hibernate應(yīng)用及其詳解(強(qiáng)力推薦)_第3頁(yè)
Hibernate應(yīng)用及其詳解(強(qiáng)力推薦)_第4頁(yè)
Hibernate應(yīng)用及其詳解(強(qiáng)力推薦)_第5頁(yè)
已閱讀5頁(yè),還剩89頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第4章

Hibernate應(yīng)用4.1Hibernate概述4.2Hibernate應(yīng)用基礎(chǔ)4.3Hibernate關(guān)系映射4.4Hibernate高級(jí)功能4.5Hibernate與Struts2整合應(yīng)用4.1Hibernate概述1.ORM簡(jiǎn)介對(duì)象/關(guān)系映射ORM(Object-RelationMapping)是用于將對(duì)象與對(duì)象之間的關(guān)系對(duì)應(yīng)到數(shù)據(jù)庫(kù)表與表之間的關(guān)系的一種模式。簡(jiǎn)單地說(shuō),ORM是通過(guò)使用描述對(duì)象和數(shù)據(jù)庫(kù)之間映射的元數(shù)據(jù),將Java程序中的對(duì)象自動(dòng)持久化到關(guān)系數(shù)據(jù)庫(kù)中。對(duì)象和關(guān)系數(shù)據(jù)是業(yè)務(wù)實(shí)現(xiàn)的兩種表現(xiàn)形式,業(yè)務(wù)實(shí)體在內(nèi)存中表現(xiàn)為對(duì)象,在數(shù)據(jù)庫(kù)中表現(xiàn)為關(guān)系數(shù)據(jù)。內(nèi)存中的對(duì)象之間存在著關(guān)聯(lián)和繼承關(guān)系。而在數(shù)據(jù)庫(kù)中,關(guān)系數(shù)據(jù)無(wú)法直接表達(dá)多對(duì)多關(guān)聯(lián)和繼承關(guān)系。因此,ORM系統(tǒng)一般以中間件的形式存在,主要實(shí)現(xiàn)程序?qū)ο蟮疥P(guān)系數(shù)據(jù)庫(kù)數(shù)據(jù)的映射。一般的ORM包括四個(gè)部分:對(duì)持久類(lèi)對(duì)象進(jìn)行CRUD操作的API、用來(lái)規(guī)定類(lèi)和類(lèi)屬性相關(guān)查詢(xún)的語(yǔ)言或API、規(guī)定mappingmetadata的工具,以及可以讓ORM實(shí)現(xiàn)同事務(wù)對(duì)象一起進(jìn)行dirtychecking、lazyassociationfetching和其他優(yōu)化操作的技術(shù)。4.1Hibernate概述2.Hibernate體系結(jié)構(gòu)Hibernate作為模型層/數(shù)據(jù)訪問(wèn)層。它通過(guò)配置文件(hibernate.cfg.xml或perties)和映射文件(*.hbm.xml)把Java對(duì)象或持久化對(duì)象(PersistentObject,PO)映射到數(shù)據(jù)庫(kù)中的數(shù)據(jù)表,然后通過(guò)操作PO,對(duì)數(shù)據(jù)庫(kù)中的表進(jìn)行各種操作,其中PO就是POJO(普通Java對(duì)象)加映射文件。Hibernate的體系結(jié)構(gòu)如圖4.1所示。圖4.1Hibernate體系結(jié)構(gòu)4.2Hibernate應(yīng)用基礎(chǔ)4.2.1Hibernate應(yīng)用實(shí)例開(kāi)發(fā)開(kāi)發(fā)Hibernate項(xiàng)目的步驟如下。1.建立數(shù)據(jù)庫(kù)及表本書(shū)使用SQLServer2005數(shù)據(jù)庫(kù)。在XSCJ數(shù)據(jù)庫(kù)中建立KCB表,其表結(jié)構(gòu)如附錄A.2所示。2.在MyEclipse中創(chuàng)建對(duì)SQLServer的連接啟動(dòng)MyEclipse,選擇【W(wǎng)indow】→【OpenPerspective】→【MyEclipseDatabaseExplorer】菜單項(xiàng),打開(kāi)MyEclipseDatabase瀏覽器,右擊菜單,如圖4.2所示,選擇【New…】菜單項(xiàng),出現(xiàn)如圖4.3所示的對(duì)話框,編輯數(shù)據(jù)庫(kù)連接驅(qū)動(dòng)。4.2.1Hibernate應(yīng)用實(shí)例開(kāi)發(fā)圖4.2MyEclipseDatabase瀏覽器,創(chuàng)建一個(gè)新的連接圖4.3編輯數(shù)據(jù)庫(kù)連接驅(qū)動(dòng)

4.2.1Hibernate應(yīng)用實(shí)例開(kāi)發(fā)編輯完成以后,在MyEclipseDatabase瀏覽器中,右擊剛才創(chuàng)建的MyConn數(shù)據(jù)庫(kù)連接,選擇“Openconnection…”菜單項(xiàng),打開(kāi)名為“MyConn”的數(shù)據(jù)連接,如圖4.4所示。圖4.4打開(kāi)數(shù)據(jù)庫(kù)連接4.2.1Hibernate應(yīng)用實(shí)例開(kāi)發(fā)3.創(chuàng)建Web項(xiàng)目,命名為“HibernateTest”4.添加Hibernate開(kāi)發(fā)能力右擊項(xiàng)目名HibernateTest,選擇【MyEclipse】→【AddHibernateCapabilites】菜單項(xiàng),出現(xiàn)如圖4.5所示的對(duì)話框,選擇Hibernate框架應(yīng)用版本及所需要的類(lèi)庫(kù)。圖4.5選擇Hibernate版本及所需Jar包4.2.1Hibernate應(yīng)用實(shí)例開(kāi)發(fā)單擊【Next】按鈕,進(jìn)入如圖4.6所示界面。創(chuàng)建Hibernate配置文件hibernate.cfg.xml,將該文件放在src文件夾下,后面會(huì)詳細(xì)介紹該文件內(nèi)容。這里先說(shuō)明添加Hibernate開(kāi)發(fā)功能的步驟。圖4.6創(chuàng)建配置文件hibernate.cfg.xml4.2.1Hibernate應(yīng)用實(shí)例開(kāi)發(fā)單擊【Next】按鈕,進(jìn)入如圖4.7所示界面,指定Hibernate數(shù)據(jù)庫(kù)連接細(xì)節(jié)。由于在前面已經(jīng)配置一個(gè)名為MyConn的數(shù)據(jù)庫(kù)連接,所以這里只需要選擇DBDriver為“MyConn”即可。

圖4.7指定hibernate數(shù)據(jù)庫(kù)連接4.2.1Hibernate應(yīng)用實(shí)例開(kāi)發(fā)單擊【Next】按鈕,出現(xiàn)如圖4.8所示界面。Hibernate中有一個(gè)與數(shù)據(jù)庫(kù)打交道重要的類(lèi)Session。而這個(gè)類(lèi)是由工廠SessionFactory創(chuàng)建的。這個(gè)界面詢(xún)問(wèn)是否需要?jiǎng)?chuàng)建SessionFactory類(lèi)。如果需要?jiǎng)?chuàng)建,還需要指定創(chuàng)建的位置和類(lèi)名。這些接口都會(huì)在后面詳細(xì)介紹。單擊【Finish】按鈕,完成Hibernate的配置。圖4.8創(chuàng)建SessionFactory類(lèi)來(lái)簡(jiǎn)化Hibernate會(huì)話處理4.2.1Hibernate應(yīng)用實(shí)例開(kāi)發(fā)5.生成數(shù)據(jù)庫(kù)表對(duì)應(yīng)的Java類(lèi)對(duì)象和映射文件首先在MyEclispse下創(chuàng)建一個(gè)名為“org.model”的包,這個(gè)包將用來(lái)存放與數(shù)據(jù)庫(kù)表對(duì)應(yīng)的Java類(lèi)POJO。從主菜單欄,選擇【W(wǎng)indows】→【OpenPerspective】→【Other】→【MyEclipseDatabaseExplorer】菜單項(xiàng),打開(kāi)MyEclipseDatabaseExplorer視圖。打開(kāi)前面創(chuàng)建的MyConn數(shù)據(jù)連接,選擇【XSCJ】→【dbo】→【TABLE】菜單項(xiàng),右擊KCB表,選擇【HibernateReverseEngineering…】菜單項(xiàng),如圖4.9所示,將啟動(dòng)HibernateReverseEngineering向?qū)?,該向?qū)в糜谕瓿蓮囊延械臄?shù)據(jù)庫(kù)表生成對(duì)應(yīng)的Java類(lèi)和相關(guān)映像文件的配置工作。圖4.9Hibernate反向工程菜單4.2.1Hibernate應(yīng)用實(shí)例開(kāi)發(fā)首先,選擇生成的Java類(lèi)和映像文件所在的位置,如圖4.10所示。POJO(PlainOldJavaObject,簡(jiǎn)單的Java對(duì)象),通常也稱(chēng)為VO(ValueObject,值對(duì)象)。圖4.10生成Hibernate映射文件和Java類(lèi)4.2.1Hibernate應(yīng)用實(shí)例開(kāi)發(fā)使用POJO名稱(chēng)是為了避免和EJB混淆起來(lái),其中有一些屬性及getter、setter方法。當(dāng)然,如果有一個(gè)簡(jiǎn)單的運(yùn)算屬性也是可以的,但不允許有業(yè)務(wù)方法。單擊【Next】按鈕,進(jìn)入如圖4.11所示的界面,選擇主鍵生成策略。圖4.11配置反向工程細(xì)節(jié)4.2.1Hibernate應(yīng)用實(shí)例開(kāi)發(fā)6.創(chuàng)建測(cè)試類(lèi)在src文件夾下創(chuàng)建包test,在該包下建立測(cè)試類(lèi),命名為T(mén)est.java,其代碼。7.運(yùn)行因?yàn)樵摮绦驗(yàn)镴avaApplication,所以可以直接運(yùn)行。運(yùn)行程序,控制臺(tái)就會(huì)打印出“機(jī)電”。在完全沒(méi)有操作數(shù)據(jù)庫(kù)的情況下,就完成了對(duì)數(shù)據(jù)的插入。下面將詳細(xì)講解各文件的作用。4.2.2Hibernate各種文件的作用1.POJO類(lèi)和其映射配置文件POJO類(lèi)如下:packageorg.model;publicclassKcbimplementsjava.io.Serializable{ privateStringkch; //對(duì)應(yīng)表中KCH字段 privateStringkcm; //對(duì)應(yīng)表中KCM字段 privateShortkxxq; //對(duì)應(yīng)表中KXXQ字段 privateIntegerxs; //對(duì)應(yīng)表中XS字段 privateIntegerxf; //對(duì)應(yīng)表中XF字段 publicKcb(){ } //上述屬性的getter和setter方法}可以發(fā)現(xiàn),該類(lèi)中的屬性和表中的字段是一一對(duì)應(yīng)的。那么通過(guò)什么方法把它們一一映射起來(lái)呢?就是前面提到的*.hbm.xml映射文件。這里當(dāng)然就是Kcb.hbm.xml,其代碼。4.2.2Hibernate各種文件的作用該配置文件大致分為3個(gè)部分:(1)類(lèi)、表映射配置<classname="org.model.Kcb"table="KCB">name屬性指定POJO類(lèi)為org.model.Kcb,table屬性指定當(dāng)前類(lèi)對(duì)應(yīng)數(shù)據(jù)庫(kù)表KCB。(2)id映射配置<idname="kch"type="java.lang.String"> <columnname="KCH"length="3"/> <generatorclass="assigned"/></id>Hibernate的主鍵生成策略分為三大類(lèi):Hibernate對(duì)主鍵id賦值、應(yīng)用程序自身對(duì)id賦值、由數(shù)據(jù)庫(kù)對(duì)id賦值。assigned:應(yīng)用程序自身對(duì)id賦值。當(dāng)設(shè)置<generatorclass="assigned"/>時(shí),應(yīng)用程序自身需要負(fù)責(zé)主鍵id的賦值。例如下述代碼:Kcbkc=newKcb(); //創(chuàng)建POJO類(lèi)對(duì)象kc.setKch("198"); //設(shè)置課程號(hào)kc.setKcm("機(jī)電"); //設(shè)置課程名kc.setKxxq(newInteger(5).shortValue()); //設(shè)置開(kāi)學(xué)學(xué)期kc.setXf(newInteger(4).shortValue()); //設(shè)置學(xué)分kc.setXs(newInteger(59).shortValue()); //設(shè)置學(xué)時(shí)4.2.2Hibernate各種文件的作用native:由數(shù)據(jù)庫(kù)對(duì)id賦值。當(dāng)設(shè)置<generatorclass="native"/>時(shí),數(shù)據(jù)庫(kù)負(fù)責(zé)主鍵id的賦值,最常見(jiàn)的是int型的自增型主鍵。hilo:通過(guò)hi/lo算法實(shí)現(xiàn)的主鍵生成機(jī)制,需要額外的數(shù)據(jù)庫(kù)表保存主鍵生成歷史狀態(tài)。seqhilo:與hi/lo類(lèi)似,通過(guò)hi/lo算法實(shí)現(xiàn)的主鍵生成機(jī)制,只是主鍵歷史狀態(tài)保存在sequence中,適用于支持sequence的數(shù)據(jù)庫(kù),如Oracle。increment:主鍵按數(shù)值順序遞增。此方式的實(shí)現(xiàn)機(jī)制為在當(dāng)前應(yīng)用實(shí)例中維持一個(gè)變量,以保存當(dāng)前的最大值,之后每次需要生成主鍵的時(shí)候?qū)⒋酥导?作為主鍵。identity:采用數(shù)據(jù)庫(kù)提供的主鍵生成機(jī)制,如SQLServer、MySQL中的自增主鍵生成機(jī)制。sequence:采用數(shù)據(jù)庫(kù)提供的sequence機(jī)制生成主鍵,如Oraclesequence。uuid.hex:由Hibernate基于128位唯一值產(chǎn)生算法,根據(jù)當(dāng)前設(shè)備IP、時(shí)間、JVM啟動(dòng)時(shí)間、內(nèi)部自增量等4個(gè)參數(shù)生成十六進(jìn)制數(shù)值(編碼后長(zhǎng)度為32位的字符串表示)作為主鍵。即使是在多實(shí)例并發(fā)運(yùn)行的情況下,這種算法在最大程度上保證了產(chǎn)生id的唯一性。當(dāng)然,重復(fù)的概率在理論上依然存在,只是概率比較小。uuid.string:與uuid.hex類(lèi)似,只是對(duì)生成的主鍵進(jìn)行編碼(長(zhǎng)度16位)。foreign:使用外部表的字段作為主鍵。select:Hibernate3新引入的主鍵生成機(jī)制,主要針對(duì)遺留系統(tǒng)的改造工程。4.2.2Hibernate各種文件的作用(3)屬性、字段映射配置屬性、字段映射將映射類(lèi)屬性與庫(kù)表字段相關(guān)聯(lián)。<propertyname="kcm"type="java.lang.String"> <columnname="KCM"length="12"/></property>name="kcm"指定映像類(lèi)中的屬性名為“kcm”,此屬性將被映像到指定的庫(kù)表字段KCM。type="java.lang.String"指定映像字段的數(shù)據(jù)類(lèi)型。columnname="KCM"指定類(lèi)的kcm屬性映射KCB表中的KCM字段。4.2.2Hibernate各種文件的作用2.hibernate.cfg.xml文件該文件是Hibernate重要的配置文件,配置該文件主要是配置SessionFractory類(lèi)。其主要代碼及解釋。

3.HibernateSessionFactoryHibernateSessionFactory類(lèi)是自定義的SessionFactory,名字可以根據(jù)自己的喜好來(lái)決定。這里用的是HibernateSessionFactory,其內(nèi)容及解釋。在Hibernate中,Session負(fù)責(zé)完成對(duì)象持久化操作。該文件負(fù)責(zé)創(chuàng)建Session對(duì)象,以及關(guān)閉Session對(duì)象。從該文件可以看出,Session對(duì)象的創(chuàng)建大致需要以下3個(gè)步驟:①初始化Hibernate配置管理類(lèi)Configuration。②通過(guò)Configuration類(lèi)實(shí)例創(chuàng)建Session的工廠類(lèi)SessionFactory。③通過(guò)SessionFactory得到Session實(shí)例。4.2.3Hibernate核心接口1.Configuration接口Configuration負(fù)責(zé)管理Hibernate的配置信息。Hibernate運(yùn)行時(shí)需要一些底層實(shí)現(xiàn)的基本信息。這些信息包括:數(shù)據(jù)庫(kù)URL、數(shù)據(jù)庫(kù)用戶名、數(shù)據(jù)庫(kù)用戶密碼、數(shù)據(jù)庫(kù)JDBC驅(qū)動(dòng)類(lèi)、數(shù)據(jù)庫(kù)dialect。用于對(duì)特定數(shù)據(jù)庫(kù)提供支持,其中包含了針對(duì)特定數(shù)據(jù)庫(kù)特性的實(shí)現(xiàn),如Hibernate數(shù)據(jù)庫(kù)類(lèi)型到特定數(shù)據(jù)庫(kù)數(shù)據(jù)類(lèi)型的映射等。使用Hibernate必須首先提供這些基礎(chǔ)信息以完成初始化工作,為后續(xù)操作做好準(zhǔn)備。這些屬性在Hibernate配置文件hibernate.cfg.xml中加以設(shè)定,當(dāng)調(diào)用:Configurationconfig=newConfiguration().configure();時(shí),Hibernate會(huì)自動(dòng)在目錄下搜索hibernate.cfg.xml文件,并將其讀取到內(nèi)存中作為后續(xù)操作的基礎(chǔ)配置。4.2.3Hibernate核心接口2.SessionFactory接口SessionFactory負(fù)責(zé)創(chuàng)建Session實(shí)例,可以通過(guò)Configuration實(shí)例構(gòu)建SessionFactory。Configurationconfig=newConfiguration().configure();SessionFactorysessionFactory=config.buildSessionFactory();Configuration實(shí)例config會(huì)根據(jù)當(dāng)前的數(shù)據(jù)庫(kù)配置信息,構(gòu)造SessionFacory實(shí)例并返回。SessionFactory一旦構(gòu)造完畢,即被賦予特定的配置信息。也就是說(shuō),之后config的任何變更將不會(huì)影響到已經(jīng)創(chuàng)建的SessionFactory實(shí)例sessionFactory。如果需要使用基于變更后的config實(shí)例的SessionFactory,需要從config重新構(gòu)建一個(gè)SessionFactory實(shí)例。SessionFactory保存了對(duì)應(yīng)當(dāng)前數(shù)據(jù)庫(kù)配置的所有映射關(guān)系,同時(shí)也負(fù)責(zé)維護(hù)當(dāng)前的二級(jí)數(shù)據(jù)緩存和StatementPool。由此可見(jiàn),SessionFactory的創(chuàng)建過(guò)程非常復(fù)雜、代價(jià)高昂。這也意味著,在系統(tǒng)設(shè)計(jì)中充分考慮到SessionFactory的重用策略。由于SessionFactory采用了線程安全的設(shè)計(jì),可由多個(gè)線程并發(fā)調(diào)用。4.2.3Hibernate核心接口3.Session接口Session是Hibernate持久化操作的基礎(chǔ),提供了眾多持久化方法,如save、update、delete等。通過(guò)這些方法,透明地完成對(duì)象的增加、刪除、修改、查找等操作。同時(shí),值得注意的是,HibernateSession的設(shè)計(jì)是非線程安全的,即一個(gè)Session實(shí)例同時(shí)只可由一個(gè)線程使用。同一個(gè)Session實(shí)例的多線程并發(fā)調(diào)用將導(dǎo)致難以預(yù)知的錯(cuò)誤。Session實(shí)例由SessionFactory構(gòu)建:Configurationconfig=newConfiguration().configure();SessionFactorysessionFactory=config.buldSessionFactory();Sessionsession=sessionFactory.openSession();4.Transaction接口Transaction是Hibernate中進(jìn)行事務(wù)操作的接口,Transaction接口是對(duì)實(shí)際事務(wù)實(shí)現(xiàn)的一個(gè)抽象,這些實(shí)現(xiàn)包括JDBC的事務(wù)、JTA中的UserTransaction,甚至可以是CORBA事務(wù)。之所以這樣設(shè)計(jì)是可以讓開(kāi)發(fā)者能夠使用一個(gè)統(tǒng)一的操作界面,使得自己的項(xiàng)目可以在不同的環(huán)境和容器之間方便地移值。事務(wù)對(duì)象通過(guò)Session創(chuàng)建。例如以下語(yǔ)句:Transactionts=session.beginTransaction();4.2.3Hibernate核心接口5.Query接口在Hibernate2.x中,find()方法用于執(zhí)行HQL語(yǔ)句。Hibernate3.x廢除了find()方法,取而代之的是Query接口,它們都用于執(zhí)行HQL語(yǔ)句。Query和HQL是分不開(kāi)的。Queryquery=session.createQuery(“fromKcbwherekch=198”);例如以下語(yǔ)句:Queryquery=session.createQuery("fromKcbwherekch=?");就要在后面設(shè)置其值:Query.setString(0,"要設(shè)置的值");上面的方法是通過(guò)“?”來(lái)設(shè)置參數(shù),還可以用“:”后跟變量的方法來(lái)設(shè)置參數(shù),如上例可以改為:Queryquery=session.createQuery("fromKcbwherekch=:kchValue");Query.setString("kchValue","要設(shè)置的課程號(hào)值");其使用方法是相同的,例如:Query.setParameter(0,"要設(shè)置的值");Query還有一個(gè)list()方法,用于取得一個(gè)List集合的示例,此示例中包括可能是一個(gè)Object集合,也可能是Object數(shù)組集合。例如:Queryquery=session.createQuery("fromKcbwherekch=198");Listlist=query.list();4.2.4HQL查詢(xún)下面介紹HQL的幾種常用的查詢(xún)方式。1.基本查詢(xún)基本查詢(xún)是HQL中最簡(jiǎn)單的一種查詢(xún)方式。下面以課程信息為例說(shuō)明其幾種查詢(xún)情況。(1)查詢(xún)所有課程信息…Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();Queryquery=session.createQuery("fromKcb");Listlist=query.list();mit();HibernateSessionFactory.closeSession();…4.2.4HQL查詢(xún)(2)查詢(xún)某門(mén)課程信息...Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();//查詢(xún)一門(mén)學(xué)時(shí)最長(zhǎng)的課程Queryquery=session.createQuery("fromKcborderbyxsdesc");query.setMaxResults(1); //設(shè)置最大檢索數(shù)目為1//裝載單個(gè)對(duì)象Kcbkc=(Kcb)query.uniqueResult();mit();HibernateSessionFactory.closeSession();...4.2.4HQL查詢(xún)(3)查詢(xún)滿足條件的課程信息...Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();//查詢(xún)課程號(hào)為001的課程信息Queryquery=session.createQuery("fromKcbwherekch=001");Listlist=query.list();mit();HibernateSessionFactory.closeSession();...4.2.4HQL查詢(xún)2.條件查詢(xún)查詢(xún)的條件有幾種情況,下面舉例說(shuō)明。(1)按指定參數(shù)查詢(xún)...Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();//查詢(xún)課程名為計(jì)算機(jī)基礎(chǔ)的課程信息Queryquery=session.createQuery("fromKcbwherekcm=?");query.setParameter(0,"計(jì)算機(jī)基礎(chǔ)");Listlist=query.list();mit();HibernateSessionFactory.closeSession();...4.2.4HQL查詢(xún)(2)使用范圍運(yùn)算查詢(xún)...Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();//查詢(xún)這樣的課程信息,課程名為計(jì)算機(jī)基礎(chǔ)或數(shù)據(jù)結(jié)構(gòu),且學(xué)時(shí)在40~60之間Queryquery=session.createQuery("fromKcbwhere(xsbetween40and60)andkcmin('計(jì)算機(jī)基礎(chǔ)','數(shù)據(jù)結(jié)構(gòu)')");Listlist=query.list();mit();HibernateSessionFactory.closeSession();...4.2.4HQL查詢(xún)(3)使用比較運(yùn)算符查詢(xún)...Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();//查詢(xún)學(xué)時(shí)大于51且課程名不為空的課程信息Queryquery=session.createQuery("fromKcbwherexs>51andkcmisnotnull");Listlist=query.list();mit();HibernateSessionFactory.closeSession();...4.2.4HQL查詢(xún)(4)使用字符串匹配運(yùn)算查詢(xún)...Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();//查詢(xún)課程號(hào)中包含“001”字符串且課程名前面三個(gè)字為計(jì)算機(jī)的所有課程信息Queryquery=session.createQuery("fromKcbwherekchlike'%001%'andkcmlike'計(jì)算機(jī)%'");Listlist=query.list();mit();HibernateSessionFactory.closeSession();...4.2.4HQL查詢(xún)3.分頁(yè)查詢(xún)?yōu)榱藵M足分頁(yè)查詢(xún)的需要,Hibernate的Query實(shí)例提供了兩個(gè)有用的方法:setFirstResult(intfirstResult)和setMaxResults(intmaxResult)。其中setFirstResult(intfirstResult)方法用于指定從哪一個(gè)對(duì)象開(kāi)始查詢(xún)(序號(hào)從0開(kāi)始),默認(rèn)為第1個(gè)對(duì)象,也就是序號(hào)0。SetMaxResults(intmaxResult)方法用于指定一次最多查詢(xún)出的對(duì)象的數(shù)目,默認(rèn)為所有對(duì)象。如下面的代碼片段:...Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();Queryquery=session.createQuery("fromKcb");intpageNow=1; //想要顯示第幾頁(yè)intpageSize=5; //每頁(yè)顯示的條數(shù)query.setFirstResult((pageNow-1)*pageSize); //指定從哪一個(gè)對(duì)象開(kāi)始查詢(xún)query.setMaxResults(pageSize); //指定最大的對(duì)象數(shù)目Listlist=query.list();mit();HibernateSessionFactory.closeSession();...4.3Hibernate關(guān)系映射4.3.1一對(duì)一關(guān)聯(lián)1.共享主鍵方式在注冊(cè)某個(gè)論壇會(huì)員的時(shí)候,往往不但要填寫(xiě)登錄賬號(hào)和密碼,還要填寫(xiě)其他的詳細(xì)信息,這兩部分信息通常會(huì)放在不同的表中,如表4.1、表4.2所示。字段名稱(chēng)數(shù)據(jù)類(lèi)型主鍵自增允許為空描述IDint(4)是ID號(hào)USERNAMEvarchar(20)登錄賬號(hào)PASSWORDvarchar(20)登錄密碼字段名稱(chēng)數(shù)據(jù)類(lèi)型主鍵自增允許為空描述IDint(4)是增1ID號(hào)TRUENAMEvarchar(8)是真實(shí)姓名EMAILvarchar(50)是電子郵件表4.1登錄表Login表4.2詳細(xì)信息表Detail4.3.1一對(duì)一關(guān)聯(lián)登錄表和詳細(xì)信息表屬于典型的一對(duì)一關(guān)聯(lián)關(guān)系,可按共享主鍵方式進(jìn)行。步驟如下:①創(chuàng)建Java項(xiàng)目,命名為“Hibernate_mapping”。②添加Hibernate開(kāi)發(fā)能力,步驟同4.2.1節(jié)第4步。HibernateSessionFactory類(lèi)同樣位于org.util包下。③編寫(xiě)生成數(shù)據(jù)庫(kù)表對(duì)應(yīng)的Java類(lèi)對(duì)象和映射文件。Login表對(duì)應(yīng)的POJO類(lèi)Login.java:packageorg.model;publicclassLoginimplementsjava.io.Serializable{ privateintid; //ID號(hào)

privateStringusername; //登錄賬號(hào) privateStringpassword; //密碼 privateDetaildetail; //詳細(xì)信息 //省略上述各屬性的getter和setter方法}4.3.1一對(duì)一關(guān)聯(lián)Detail表對(duì)應(yīng)的Detail.java:packageorg.model;publicclassDetailimplementsjava.io.Serializable{ privateintid; //ID號(hào) privateStringtrueName; //真實(shí)姓名 privateStringemail; //電子郵件 privateLoginlogin; //登錄信息 //省略上述各屬性的getter和setter方法}Login表與Login類(lèi)的ORM映射文件Login.hbm.xml。Detail表與Detail類(lèi)的ORM映射文件Detail.hbm.xml:4.3.1一對(duì)一關(guān)聯(lián)④在hibernate.cfg.xml文件中加入配置映射文件的語(yǔ)句。<mappingresource="org/model/Detail.hbm.xml"/><mappingresource="org/model/Login.hbm.xml"/>⑤創(chuàng)建測(cè)試類(lèi)。在src文件夾下創(chuàng)建包test,在該包下建立測(cè)試類(lèi),命名為“Test.java”。其代碼。⑥運(yùn)行程序,測(cè)試結(jié)果。因?yàn)樵摮绦驗(yàn)镴avaApplication,所以可以直接運(yùn)行。在完全沒(méi)有操作數(shù)據(jù)庫(kù)的情況下,程序就完成了對(duì)數(shù)據(jù)的插入。插入數(shù)據(jù)后,Login表和Detail表的內(nèi)容如圖4.12、圖4.13所示。

圖4.12Login表

圖4.13Detail表4.3.1一對(duì)一關(guān)聯(lián)2.唯一外鍵方式唯一外鍵的情況很多,例如,每個(gè)人對(duì)應(yīng)一個(gè)房間。其實(shí)在很多情況下,可以是幾個(gè)人住在同一個(gè)房間里面,就是多對(duì)一的關(guān)系。但是如果把這個(gè)多變成唯一,也就是說(shuō)讓一個(gè)人住一個(gè)房間,就變成了一對(duì)一的關(guān)系了,這就是前面說(shuō)的一對(duì)一的關(guān)系其實(shí)是多對(duì)一關(guān)聯(lián)關(guān)系的一種特殊情況。對(duì)應(yīng)的Person表和Room表如表4.3、表4.4所示。字段名稱(chēng)數(shù)據(jù)類(lèi)型主鍵自增允許為空描述Idint是增1ID號(hào)namevarchar(20)姓名room_idint(20)是房間號(hào)字段名稱(chēng)數(shù)據(jù)類(lèi)型主鍵自增允許為空描述idint(4)是增1ID號(hào)addressvarchar(100)地址表4.3Person表表4.4Room表4.3.1一對(duì)一關(guān)聯(lián)步驟如下:①在項(xiàng)目Hibernate_mapping的org.model包下編寫(xiě)生成數(shù)據(jù)庫(kù)表對(duì)應(yīng)的Java類(lèi)對(duì)象和映射文件。Person表對(duì)應(yīng)的POJO類(lèi)Person.java:packageorg.model;publicclassPersonimplementsjava.io.Serializable{privateIntegerid;privateStringname;privateRoomroom;//省略上述各屬性的getter和setter方法}Room表對(duì)應(yīng)的POJO類(lèi)Room.java:packageorg.model;publicclassRoomimplementsjava.io.Serializable{privateintid;privateStringaddress;privatePersonperson;//省略上述各屬性的getter和setter方法}4.3.1一對(duì)一關(guān)聯(lián)Person表與Person類(lèi)的ORM映射文件Person.hbm.xml:<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping><classname="org.model.Person"table="Person"><idname="id"column="id"type="java.lang.Integer"><generatorclass="native"/></id><propertyname="name"column="name"type="java.lang.String"/><many-to-onename="room" //屬性名稱(chēng)column="room_id" //充當(dāng)外鍵的字段名class="org.model.Room" //被關(guān)聯(lián)的類(lèi)的名稱(chēng)cascade="all" //主控類(lèi)所有操作,對(duì)關(guān)聯(lián)類(lèi)也執(zhí)行同樣操作unique="true"/> //唯一性約束,實(shí)現(xiàn)一對(duì)一</class></hibernate-mapping>4.3.1一對(duì)一關(guān)聯(lián)Room表與Room類(lèi)的ORM映射文件Room.hbm.xml:<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping><classname="org.model.Room"table="Room"><idname="id"column="id"><generatorclass="native"/></id> <propertyname="address" column="address"type="java.lang.String"/> <one-to-onename="person" //屬性名class="org.model.Person" //被關(guān)聯(lián)的類(lèi)的名稱(chēng)

property-ref="room"/> //指定關(guān)聯(lián)類(lèi)的屬性名</class></hibernate-mapping>4.3.1一對(duì)一關(guān)聯(lián)②在hibernate.cfg.xml文件中加入如下的配置映射文件的語(yǔ)句。<mappingresource="org/model/Person.hbm.xml"/><mappingresource="org/model/Room.hbm.xml"/>③編寫(xiě)測(cè)試代碼。在src文件夾下的包test的Test類(lèi)中加入如下代碼:…Personperson=newPerson();person.setName("liumin");Roomroom=newRoom();room.setAddress("NJ-S1-328");person.setRoom(room);session.save(person);…4.3.1一對(duì)一關(guān)聯(lián)④運(yùn)行程序,測(cè)試結(jié)果。因?yàn)樵摮绦驗(yàn)镴avaApplication,所以可以直接運(yùn)行。在完全沒(méi)有操作數(shù)據(jù)庫(kù)的情況下,程序就完成了對(duì)數(shù)據(jù)的插入。插入數(shù)據(jù)后,Person表和Room表的內(nèi)容如圖4.14、圖4.15所示。

圖4.14Person表

圖4.15Room表4.3.2多對(duì)一單向關(guān)聯(lián)只要把上例中的一對(duì)一的唯一外鍵關(guān)聯(lián)實(shí)例稍微修改就可以變成多對(duì)一。步驟如下:①在項(xiàng)目Hibernate_mapping的org.model包下編寫(xiě)生成數(shù)據(jù)庫(kù)表對(duì)應(yīng)的Java類(lèi)對(duì)象和映射文件。其對(duì)應(yīng)表不變,Person表對(duì)應(yīng)的類(lèi)也不變,對(duì)應(yīng)的Person.hbm.xml文件修改如下:<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping><classname="org.model.Person"table="Person"><idname="id"column="id"type="java.lang.Integer"><generatorclass="native"/></id><propertyname="name"column="name"type="java.lang.String"/><many-to-onename="room" //屬性名稱(chēng) column="room_id" //充當(dāng)外鍵的字段名 class="org.model.Room" //被關(guān)聯(lián)的類(lèi)的名稱(chēng) cascade="all"/> //主控類(lèi)所有操作,對(duì)關(guān)聯(lián)類(lèi)也執(zhí)行同樣操作</class></hibernate-mapping>4.3.2多對(duì)一單向關(guān)聯(lián)而Room表不變,對(duì)應(yīng)的POJO類(lèi)如下:packageorg.model;publicclassRoomimplementsjava.io.Serializable{privateintid;privateStringaddress;//省略上述各屬性的getter和setter方法}Room表與Room類(lèi)的ORM映射文件Room.hbm.xml如下:<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping><classname="org.model.Room"table="room"><idname="id"column="id"><generatorclass="native"/></id><propertyname="address"column="address"type="java.lang.String"/></class></hibernate-mapping>4.3.2多對(duì)一單向關(guān)聯(lián)②編寫(xiě)測(cè)試代碼。在src文件夾下的包test的Test類(lèi)中加入如下代碼:

…Roomroom=newRoom();room.setAddress("NJ-S1-328");Personperson=newPerson();person.setName("liuyanmin");person.setRoom(room);session.save(person);…4.3.2多對(duì)一單向關(guān)聯(lián)③運(yùn)行程序,測(cè)試結(jié)果。因?yàn)樵摮绦驗(yàn)镴avaApplication,所以可以直接運(yùn)行。在完全沒(méi)有操作數(shù)據(jù)庫(kù)的情況下,程序就完成了對(duì)數(shù)據(jù)的插入。插入數(shù)據(jù)后,Person表和Room表的內(nèi)容如圖4.16、圖4.17所示。

圖4.16Person表

圖4.17Room表4.3.3一對(duì)多雙向關(guān)聯(lián)下面通過(guò)修改4.3.2節(jié)的例子來(lái)完成雙向多對(duì)一的實(shí)現(xiàn)。步驟如下:①在項(xiàng)目Hibernate_mapping的org.model包下編寫(xiě)生成數(shù)據(jù)庫(kù)表對(duì)應(yīng)的Java類(lèi)對(duì)象和映射文件。Person表對(duì)應(yīng)的POJO及其映射文件不用改變,現(xiàn)在來(lái)修改Room表對(duì)應(yīng)的POJO類(lèi)及其映射文件。對(duì)應(yīng)的POJO類(lèi)Room.java。Room表與Room類(lèi)的ORM映射文件Room.hbm.xml。該配置文件中cascade配置的是級(jí)聯(lián)程度,它有以下幾種取值:all:表示所有操作句在關(guān)聯(lián)層級(jí)上進(jìn)行連鎖操作。save-update:表示只有save和update操作進(jìn)行連鎖操作。delete:表示只有delete操作進(jìn)行連鎖操作。all-delete-orphan:在刪除當(dāng)前持久化對(duì)象時(shí),它相當(dāng)于delete;在保存或更新當(dāng)前持久化對(duì)象時(shí),它相當(dāng)于save-update。另外它還可以刪除與當(dāng)前持久化對(duì)象斷開(kāi)關(guān)聯(lián)關(guān)系的其他持久化對(duì)象。4.3.3一對(duì)多雙向關(guān)聯(lián)②編寫(xiě)測(cè)試代碼。在src文件夾下的包test的Test類(lèi)中加入如下代碼:…Personperson1=newPerson();Personperson2=newPerson();Roomroom=newRoom();room.setAddress("NJ-S1-328");person1.setName("李方方");person2.setName("王艷");person1.setRoom(room);person2.setRoom(room);//這樣完成后就可以通過(guò)Session對(duì)象//調(diào)用session.save(person1)和session.save(person)//會(huì)自動(dòng)保存roomsession.save(person1);session.save(person2);…4.3.3一對(duì)多雙向關(guān)聯(lián)③運(yùn)行程序,測(cè)試結(jié)果。因?yàn)樵摮绦驗(yàn)镴avaApplication,所以可以直接運(yùn)行。在完全沒(méi)有操作數(shù)據(jù)庫(kù)的情況下,程序就完成了對(duì)數(shù)據(jù)的插入。插入數(shù)據(jù)后,Person表和Room表的內(nèi)容如圖4.18、圖4.19所示。

圖4.18Person表

圖4.19Room表4.3.3一對(duì)多雙向關(guān)聯(lián)由于是雙向的,當(dāng)然也可以從Room的一方來(lái)保存Person,在Test.java中加入如下代碼:...Personperson1=newPerson();Personperson2=newPerson();Roomroom=newRoom();person1.setName("李方方");person2.setName("王艷");Setpersons=newHashSet();persons.add(person1);persons.add(person2);room.setAddress("NJ-S1-328");room.setPerson(persons);//這樣完成后,就可以通過(guò)Session對(duì)象//調(diào)用session.save(room)//會(huì)自動(dòng)保存person1和person2...4.3.3一對(duì)多雙向關(guān)聯(lián)運(yùn)行程序,插入數(shù)據(jù)后,Person表和Room表的內(nèi)容如圖4.20、圖4.21所示。

圖4.20Person表

圖4.21Room表4.3.4多對(duì)多關(guān)聯(lián)1.多對(duì)多單向關(guān)聯(lián)學(xué)生和課程就是多對(duì)多的關(guān)系,一個(gè)學(xué)生可以選擇多門(mén)課程,而一門(mén)課程又可以被多個(gè)學(xué)生選擇。多對(duì)多關(guān)系在關(guān)系數(shù)據(jù)庫(kù)中不能直接實(shí)現(xiàn),還必須依賴(lài)一張連接表。如表4.6、表4.7和表4.8所示。字段名稱(chēng)數(shù)據(jù)類(lèi)型主鍵自增允許為空描述IDint是增1ID號(hào)SNUMBERvarchar(10)學(xué)號(hào)SNAMEvarchar(10)是姓名SAGEint是年齡字段名稱(chēng)數(shù)據(jù)類(lèi)型主鍵自增允許為空描述IDint是增1ID號(hào)CNUMBERvarchar(10)課程號(hào)CNAMEvarchar(20)是課程名表4.6學(xué)生表student表4.7課程表course字段名稱(chēng)數(shù)據(jù)類(lèi)型主鍵自增允許為空描述SIDint是學(xué)生ID號(hào)CIDint是課程ID號(hào)表4.8連接表stu_cour4.3.4多對(duì)多關(guān)聯(lián)由于是單向的,也就是說(shuō)從一方可以知道另一方,反之不行。這里以從學(xué)生知道選擇了哪些課程為例實(shí)現(xiàn)多對(duì)多單向關(guān)聯(lián)。步驟如下:①在項(xiàng)目Hibernate_mapping的org.model包下編寫(xiě)生成數(shù)據(jù)庫(kù)表對(duì)應(yīng)的Java類(lèi)對(duì)象和映射文件。student表對(duì)應(yīng)的POJO類(lèi)如下:packageorg.model;importjava.util.HashSet;importjava.util.Set;publicclassStudentimplementsjava.io.Serializable{ privateintid; privateStringsnumber; privateStringsname; privateintsage; privateSetcourses=newHashSet(); //省略上述各屬性的getter和setter方法}student表與Student類(lèi)的ORM映射文件Student.hbm.xml。4.3.4多對(duì)多關(guān)聯(lián)course表對(duì)應(yīng)的POJO如下:packageorg.model;publicclassCourseimplementsjava.io.Serializable{ privateintid; privateStringcnumber; privateStringcname; //省略上述各屬性的getter和setter方法。}course表與Course類(lèi)的ORM映射文件Course.hbm.xml。②在hibernate.cfg.xml文件中加入如下的配置映射文件的語(yǔ)句。

<mappingresource="org/model/Student.hbm.xml"/><mappingresource="org/model/Course.hbm.xml"/>③編寫(xiě)測(cè)試代碼。在src文件夾下的包test的Test類(lèi)中加入如下代碼。4.3.4多對(duì)多關(guān)聯(lián)④運(yùn)行程序,測(cè)試結(jié)果。因?yàn)樵摮绦驗(yàn)镴avaApplication,所以可以直接運(yùn)行。在完全沒(méi)有操作數(shù)據(jù)庫(kù)的情況下,程序就完成了對(duì)數(shù)據(jù)的插入。插入數(shù)據(jù)后,student表、course表及連接表stu_cour表的內(nèi)容如圖4.22、圖4.23、圖4.24所示。圖4.22student表

圖4.23course表

圖4.24stu_cour表4.3.4多對(duì)多關(guān)聯(lián)2.多對(duì)多雙向關(guān)聯(lián)首先將其Course表所對(duì)應(yīng)的POJO對(duì)象修改成如下代碼:packageorg.model;importjava.util.HashSet;importjava.util.Set;publicclassCourseimplementsjava.io.Serializable{ privateintid; privateStringcnumber; privateStringcname; privateSetstus=newHashSet(); //省略上述各屬性的getter和setter方法}Course表與Course類(lèi)的ORM映射文件Course.hbm.xml:4.4Hibernate高級(jí)功能4.4.1Hibernate批量處理1.批量插入(1)通過(guò)Hibernate的緩存進(jìn)行批量插入使用這種方法時(shí),首先要在Hibernate的配置文件hibernate.cfg.xml中設(shè)置批量尺寸屬性hibernate.jdbc.batch_size,且最好關(guān)閉Hibernate的二級(jí)緩存以提高效率。例如:<hibernate-configuration> <session-factory> … <propertyname="hibernate.jdbc.batch_size">50</property> //設(shè)置批量尺寸 <propertyname="hibernate.cache.use_second_level_cache">false</property> //關(guān)閉二級(jí)緩存 </session-factory></hibernate-configuration>4.4.1Hibernate批量處理下面以4.2.1節(jié)的例子中的課程進(jìn)行批量插入為例,說(shuō)明批量插入操作的具體過(guò)程,這里假設(shè)批量插入500個(gè)課程到數(shù)據(jù)中:Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();for(inti=0;i<500;i++){ Kcbkcb=newKcb(); //這里設(shè)置課程號(hào)為i,在實(shí)際應(yīng)用中應(yīng)該是被插入的課程對(duì)象 //已經(jīng)放在集合或數(shù)組中,這里只要取出 kcb.setKch(i+""); session.save(kcb); if(i%50==0){ //以50個(gè)課程為一個(gè)批次向數(shù)據(jù)庫(kù)提交,此值應(yīng)與配置的批量尺寸一致 session.flush();//將該批量數(shù)據(jù)立即插入數(shù)據(jù)庫(kù)中 session.clear();//清空緩存區(qū),釋放內(nèi)存供下批數(shù)據(jù)使用 }}mit();HibernateSessionFactory.closeSession();4.4.1Hibernate批量處理(2)繞過(guò)Hibernate直接調(diào)用JDBC進(jìn)行插入由于Hibernate只是對(duì)JDBC進(jìn)行了輕量級(jí)的封裝,因此完全可以繞過(guò)Hibernate直接調(diào)用JDBC進(jìn)行批量插入。因此上例可以改成如下代碼:Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();Connectionconn=session.connection();try{ PreparedStatementstmt=conn.prepareStatement("insertintoKCB(KCH)values(?)"); for(inti=0;i<500;i++){ stmt.setString(1,i+""); stmt.addBatch(); //添加到批處理命令中 } stmt.executeBatch(); //執(zhí)行批處理任務(wù) }catch(SQLExceptione){ e.printStackTrace(); }mit();HibernateSessionFactory.closeSession();4.4.1Hibernate批量處理2.批量更新(1)由Hibernate直接進(jìn)行批量更新為了使Hibernate的HQL直接支持update/delete的批量更新語(yǔ)法,首先要在Hibernate的配置文件hibernate.cfg.xml中設(shè)置HQL/SQL查詢(xún)翻譯器屬性hibernate.query.factory_class。<hibernate-configuration> <session-factory> …… <propertyname="hibernate.query.factory_class"> org.hibernate.hql.ast.ASTQueryTranslatorFactory </property> </session-factory><hibernate-configuration> 4.4.1Hibernate批量處理下面使用HQL批量更新把課程表中的XS修改為30。由于這里是用Hibernate操作,故HQL要用類(lèi)對(duì)象及其屬性。Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();//在HQL查詢(xún)中使用update進(jìn)行批量更新Queryquery=session.createQuery("updateKcbsetxs=30");query.executeUpdate();mit();HibernateSessionFactory.closeSession();4.4.1Hibernate批量處理(2)繞過(guò)Hibernate調(diào)用JDBC進(jìn)行批量更新由于這里是直接操作數(shù)據(jù)庫(kù),故要操作對(duì)應(yīng)表,而不是類(lèi)。Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();Connectionconn=session.connection();try{ Statementstmt=conn.createStatement(); //調(diào)用JDBC的update進(jìn)行批量更新 stmt.executeUpdate("updateKCBsetXS=30");}catch(SQLExceptione){ e.printStackTrace();}mit();HibernateSessionFactory.closeSession();4.4.1Hibernate批量處理3.批量刪除(1)由Hibernate直接進(jìn)行批量刪除與批量更新一樣,為了使Hibernate的HQL直接支持update/delete的批量刪除語(yǔ)法,首先要在Hibernate的配置文件hibernate.cfg.xml中設(shè)置HQL/SQL查詢(xún)翻譯器屬性hibernate.query.factory_class。<hibernate-configuration> <session-factory> …… <propertyname="hibernate.query.factory_class"> org.hibernate.hql.ast.ASTQueryTranslatorFactory </property> </session-factory><hibernate-configuration>4.4.1Hibernate批量處理下面將使用HQL批量刪除課程表中課程號(hào)大于200的課程。Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();//在HQL查詢(xún)中使用delete進(jìn)行批量刪除Queryquery=session.createQuery("deleteKcbwherekch>200");query.executeUpdate();mit();HibernateSessionFactory.closeSession();4.4.1Hibernate批量處理(2)繞過(guò)Hibernate調(diào)用JDBC進(jìn)行批量刪除同樣刪除課程表中課程號(hào)大于200的課程。Sessionsession=HibernateSessionFactory.getSession();Transactionts=session.beginTransaction();Connectionconn=session.connection();try{ Statementstmt=conn.createStatement(); //調(diào)用JDBC的delete進(jìn)行批量刪除 stmt.executeUpdate("deletefromKCBwhereKCH>200"); }catch(SQLExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace();}mit();HibernateSessionFactory.closeSession();4.4.2實(shí)體對(duì)象生命周期實(shí)體對(duì)象的生命周期有以下3種狀態(tài)。1.transient(瞬時(shí)態(tài))瞬時(shí)態(tài),即實(shí)體對(duì)象在內(nèi)存中的存在,與數(shù)據(jù)庫(kù)中的記錄無(wú)關(guān)。如下面的代碼:Studentstu=newStudent();stu.setSnumber("081101");stu.setSname("李方方");stu.setSage(21);2.persisent(持久態(tài))在這種狀態(tài)下,實(shí)體對(duì)象的引用被納入Hibernate實(shí)體容器中加以管理。處于持久狀態(tài)的對(duì)象,其變更將由Hibernate固化到數(shù)據(jù)庫(kù)中。例如下面的代碼。4.4.2實(shí)體對(duì)象生命周期3.Detached(脫管狀態(tài))處于持久態(tài)的對(duì)象,其對(duì)應(yīng)的Session實(shí)例關(guān)閉之后,此對(duì)象就處于脫管狀態(tài)。Session實(shí)例可以看做是持久對(duì)象的宿主,一旦此宿主失效,其從屬的持久對(duì)象進(jìn)入脫管狀態(tài)。如下面的代碼://stu處于瞬時(shí)態(tài)Studentstu=newStudent();Studentstu1=newStudent();stu.setSnumber("081101");stu.setSname("李方方");stu.setSage(21);stu1.setSnumber("081102");stu1.setSname("程明");stu1.setSage(22);Transactiontx=session.beginTransaction();//stu對(duì)象由Hibernate納入管理容器,處于持久狀態(tài)session.save(stu);mit();//stu對(duì)象狀態(tài)為脫管態(tài),因?yàn)榕c其關(guān)聯(lián)的session已經(jīng)關(guān)閉session.close();4.4.3Hibernate事務(wù)管理1.基于JDBC的事務(wù)管理Hibernate是JDBC的輕量級(jí)封裝,本身并不具備事務(wù)管理能力。在事務(wù)管理層,Hibernate將其委托給底層的JDBC或JTA,以實(shí)現(xiàn)事務(wù)管理和調(diào)度功能。在JDBC的數(shù)據(jù)庫(kù)操作中,一項(xiàng)事務(wù)是由一條或多條表達(dá)式組成的不可分割的工作單元,通過(guò)提交commit()或回滾rollback()來(lái)結(jié)束事務(wù)的操作。將事務(wù)管理委托給JDBC進(jìn)行處理是最簡(jiǎn)單的實(shí)現(xiàn)方式,Hibernate對(duì)于JDBC事務(wù)的封裝也比較簡(jiǎn)單。如下面的代碼:Sessionsession=sessio

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論