ITjob就業(yè)培訓(xùn)java教材34_第1頁(yè)
ITjob就業(yè)培訓(xùn)java教材34_第2頁(yè)
ITjob就業(yè)培訓(xùn)java教材34_第3頁(yè)
ITjob就業(yè)培訓(xùn)java教材34_第4頁(yè)
ITjob就業(yè)培訓(xùn)java教材34_第5頁(yè)
已閱讀5頁(yè),還剩11頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

ITjob就業(yè)培訓(xùn)java教材34ITjob就業(yè)培訓(xùn)java教材34ITjob就業(yè)培訓(xùn)java教材34xxx公司ITjob就業(yè)培訓(xùn)java教材34文件編號(hào):文件日期:修訂次數(shù):第1.0次更改批準(zhǔn)審核制定方案設(shè)計(jì),管理制度第三十四章:Hibernate基礎(chǔ)學(xué)習(xí)目標(biāo)理解ORM機(jī)制理解Hibernate的工作原理Hibernate的配置和對(duì)象-映射文件理解對(duì)象持久化Hibernate簡(jiǎn)介Hibernate是Java應(yīng)用和關(guān)系數(shù)據(jù)庫(kù)之間的橋梁,它負(fù)責(zé)Java對(duì)象關(guān)系數(shù)據(jù)之間的映射。Hibernate內(nèi)部封裝了通過JDBC訪問數(shù)據(jù)庫(kù)的操作,向上層應(yīng)用提供了面向?qū)ο蟮臄?shù)據(jù)訪問API。在Java應(yīng)用中使用Hibernate包含以下步驟。(1)創(chuàng)建Hibernate的配置文件。(2)創(chuàng)建持久化類。(3)創(chuàng)建對(duì)象-關(guān)系映射文件。(4)通過HibernateAPI編寫訪問數(shù)據(jù)庫(kù)的代碼。建立簡(jiǎn)單的Hibernate應(yīng)用本章通過一個(gè)簡(jiǎn)單的例子customerApp應(yīng)用,演示如何運(yùn)用Hibernate來訪問關(guān)系數(shù)據(jù)庫(kù)。customerApp應(yīng)用的功能非常簡(jiǎn)單:通過Hibernate保存、更新、刪除、加載以及查詢Customer對(duì)象。創(chuàng)建Hibernate的配置文件Hibernate從其配置文件中讀取和數(shù)據(jù)庫(kù)連接有關(guān)的信息,這個(gè)配置文件應(yīng)該位于應(yīng)用的classpath中。Hibernate的配置文件有兩種形式:一種是XML格式的文件;還有一種是Java屬性文件,采用“健=值”的形式。下面介紹如何以Java屬性文件的格式來創(chuàng)建Hibernate的配置文件。這種配置文件的默認(rèn)文件名為。的內(nèi)容如下:==true以上文件包含了一系列屬性及其屬性值,Hibernate將根據(jù)這些屬性來連接數(shù)據(jù)庫(kù),本例為連接MySQL數(shù)據(jù)庫(kù)的配置代碼。下表對(duì)以上文件中的所有屬性做了描述。屬性描述SQL指定數(shù)據(jù)庫(kù)使用的方言指定數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序指定連接數(shù)據(jù)庫(kù)的指定連接數(shù)據(jù)庫(kù)的用戶名指定連接數(shù)據(jù)庫(kù)的口令如果為true,表示在程序運(yùn)行時(shí),會(huì)在控制臺(tái)輸出SQL語(yǔ)句,這有利于跟蹤Hibernate的運(yùn)行狀態(tài)。默認(rèn)為false。在應(yīng)用開發(fā)和測(cè)試階段,可以把這個(gè)屬性設(shè)為true,以便跟蹤和調(diào)試應(yīng)用程序,在應(yīng)用發(fā)布階段,應(yīng)該把這個(gè)屬性設(shè)為false,以便減少應(yīng)用的輸出信息,提高運(yùn)行性能。Hibernate能夠訪問多種關(guān)系數(shù)據(jù)庫(kù),如MySQL、Oracle和Sybase等。盡管多數(shù)關(guān)系數(shù)據(jù)庫(kù)都支持標(biāo)準(zhǔn)的SQL語(yǔ)言,但是它們往往還有各自的SQL方言,就象不同地區(qū)的人既能說標(biāo)準(zhǔn)的普通話,還能講各自的方言一樣。屬性用于指定被訪問數(shù)據(jù)庫(kù)使用的SQL方言,當(dāng)Hibernate生成SQL查詢語(yǔ)句,或者使用native對(duì)象標(biāo)識(shí)符生成策略時(shí),都會(huì)參考本地?cái)?shù)據(jù)庫(kù)的SQL方言。創(chuàng)建持久化類持久化類是指其實(shí)例需要被Hibernate持久化到數(shù)據(jù)庫(kù)中的類。持久化類通常都是域模型中的實(shí)體域類。持久化類符合JavaBean的規(guī)范,包含一些屬性,以及與之對(duì)應(yīng)的getXXX()和setXXX()方法。以下定義了一個(gè)名為Customer的持久化類。packageimportimportimportpublicclassCustomerimplementsSerializable{privateLongid;privateStringname;privateStringemail;privateStringpassword;privateintphone;privatebooleanmarried;privateStringaddress;privatecharsex;privateStringdescription;privatebyte[]image;privateDatebirthday;privateTimestampregisteredTime;publicCustomer(){}publicLonggetId(){returnid;}publicvoidsetId(Longid){=id;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){=name;}quals())的結(jié)果是true,就表示customerA和customerB對(duì)象指的是同一個(gè)客戶,它們和CUSTOMERS表中的同一條記錄對(duì)應(yīng)。Hibernate要求持久化類必須提供一個(gè)不帶參數(shù)的默認(rèn)構(gòu)造方法,在程序運(yùn)行時(shí),Hibernate運(yùn)用Java反射機(jī)制,調(diào)用方法來構(gòu)造持久化類的實(shí)例。如果對(duì)這個(gè)持久化類使用延遲檢索策略,為了使Hibernate能夠在運(yùn)行時(shí)為這個(gè)持久化類創(chuàng)建動(dòng)態(tài)代理,要求持久化類的默認(rèn)構(gòu)造方法的訪問級(jí)別必須是public或protected類型,而不能是default或private類型。在Customer類中沒有引入任何HibernateAPI,Customer類不需要繼承Hibernate的類,或?qū)崿F(xiàn)Hibernate的接口,這提高了持久化類的獨(dú)立性。如果日后要改用其他的ORM產(chǎn)品,比如由Hibernate改為OJB,不需要修改持久化類的代碼。創(chuàng)建數(shù)據(jù)庫(kù)Schema在本例中,與Customer類對(duì)應(yīng)的數(shù)據(jù)庫(kù)表名為CUSTOMERS,它在MySQL數(shù)據(jù)庫(kù)中的DDL定義如下:createtableCUSTOMERS(IDbigintnotnullprimarykey,NAMEvarchar(15)notnull,EMAILvarchar(128)notnull,PASSWORDvarchar(8)notnull,PHONEint,ADDRESSvarchar(255),SEXchar(1),IS_MARRIEDbit,DESCRIPTIONtext,IMAGEblob,BIRTHDAYdate,REGISTERED_TIMEtimestamp);CUSTOMERS表有一個(gè)ID字段,它是表的主鍵,它和Customer類的id屬性對(duì)應(yīng)。CUSTOMERS表中的字段使用了各種各樣的SQL類型,參見下表。字段名SQL類型說明IDBIGINT整數(shù),占8字節(jié),取值范圍為:-2^63~2^63-1NAMEVARCHAR變長(zhǎng)字符串,占0~255個(gè)字節(jié)SEXCHAR定長(zhǎng)字符串,占0~255個(gè)字節(jié)IS_MARRIEDBIT布爾類型DESCRIPTIONTEXT長(zhǎng)文本數(shù)據(jù),占0~65535255字節(jié)。如果字符串長(zhǎng)度小于255,可以用VARCHAR或CHAR類型來表示。如果字符串長(zhǎng)度大于255,可以定義為TEXT類型。IMAGEBLOB二進(jìn)制長(zhǎng)數(shù)據(jù),占0~65535字節(jié),BLOB是BinaryLargeObject的縮寫。IMAGE在本例中,字段用來存放圖片數(shù)據(jù)BIRTHDAYDATE代表日期,格式為“YYYY-MM-DD”REGISTERED_TIMETIMESTAMP代表日期和時(shí)間,格式為“YYYYMMDDHHMMSS”創(chuàng)建對(duì)象-關(guān)系映射文件Hibernate采用XML格式的文件來指定對(duì)象和關(guān)系數(shù)據(jù)之間的映射。在運(yùn)行時(shí),Hibernate將根據(jù)這個(gè)映射文件來生成各種SQL語(yǔ)句。在本例中,將創(chuàng)建一個(gè)名為的文件,它用于把Customer類映射到CUSTOMERS表,這個(gè)文件應(yīng)該和文件存放在同一個(gè)目錄下。以下為文件的源代碼。<xmlversion=""><!DOCTYPEhibernate-mappingPUBLIC"-java]Errorreadingresource:mypack/at把Customer持久化類映射到CUSTOMERS表文件用于映射Customer類。如果需要映射多個(gè)持久化類,那么既可以在同一個(gè)映射文件中映射所有類,也可以為每個(gè)類創(chuàng)建單獨(dú)的映射文件,映射文件和類同名,擴(kuò)展名為“”。后一種做法更值得推薦,因?yàn)樵趫F(tuán)隊(duì)開發(fā)中,這有利于管理和維護(hù)映射文件。<class>元素指定類和表的映射,它的name屬性設(shè)定類名,table屬性設(shè)定表名。以下代碼表明和Customer類對(duì)應(yīng)的表為CUSTOMERS表:<classname=""table="CUSTOMERS">如果沒有設(shè)置<class>元素的table屬性,Hibernate將直接以類名作為表名,也就是說,默認(rèn)情況下,與類對(duì)應(yīng)的表為Customer表。<class>元素包含一個(gè)<id>子元素以及多個(gè)<property>子元素。<id>子元素設(shè)定持久化類的OID和表的主鍵的映射。以下代碼表明Customer類的id屬性和CUSTOMERS表中的ID字段對(duì)應(yīng)。<idname="id"column="ID"type="long"><generatorclass="increment"/></id><id>元素的<generator>子元素指定對(duì)象標(biāo)識(shí)符生成器,它負(fù)責(zé)為OID生成惟一標(biāo)識(shí)符。<property>子元素設(shè)定類的屬性和表的字段的映射。<property>子元素主要包括name、type、column和not-null屬性。1.<property>元素的name屬性<property>元素的name屬性指定持久化類的屬性的名字。2.<property>元素的type屬性<property>元素的type屬性指定Hibernate映射類型。Hibernate映射類型是Java類型與SQL類型的橋梁。3.<property>元素的not-null屬性如果<property>元素的not-null屬性為true,表明不允許為null,默認(rèn)為false。例如以下代碼表明不允許Customer類的name屬性為null:<propertyname="name"column="NAME"type="string"not-null="true"/>Hibernate在持久化一個(gè)Customer對(duì)象時(shí),會(huì)先檢查它的name屬性是否為null,如果為null,就會(huì)拋出以下異常:not-nullpropertyreferencesanullortransientvalue:如果數(shù)據(jù)庫(kù)中CUSTOMERS表的NAME字段不允許為null,但在映射文件中沒有設(shè)置not-null屬性:<propertyname="name"column="NAME"type="string"/>那么Hibernate在持久化一個(gè)Customer對(duì)象時(shí),不會(huì)先檢查它的name屬性是否為null而是直接通過JDBCAPI向CUSTOMERS表插入相應(yīng)的數(shù)據(jù),由于CUSTOMERS表的NAME字段設(shè)置了notnull約束,因此數(shù)據(jù)庫(kù)會(huì)拋出錯(cuò)誤:708ERRORJDBCExceptionReporter:58-Generalerror,messagefromserver:"Column'NAME'cannotbenull"4.<property>元素的column屬性<property>元素的column屬性指定與類的屬性映射的表的字段名。以下代碼表明和address屬性對(duì)應(yīng)的字段為ADDRESS字段:<propertyname="address"column="ADDRESS"type="string"/>如果沒有設(shè)置<property>元素的column屬性,Hibernate將直接以類的屬性名作為字段名,也就是說,默認(rèn)情況下,與Customer類的address屬性對(duì)應(yīng)的字段為address字段。<property>元素還可以包括<column>子元素,它和<property>元素的column屬性一樣,都可以設(shè)定與類的屬性映射的表的字段名。以下兩種設(shè)置方式是等價(jià)的:<propertyname="address"column="ADDRESS"type="string"/>或者<propertyname="address"type="string"><columnname="ADDRESS"/></property><property>元素的<column>子元素比column屬性提供更多的功能,它可以更加詳細(xì)的描述表的字段。例如以下<column>子元素指定CUSTOMERS表中的NAME字段的SQL類型為varchar(15),不允許為null,并且為這個(gè)字段建立了索引:<propertyname="name"type="string"><columnname="NAME"sql-type="varchar(15)"not-null="true"index="idx_name"/></property>通過HibernateAPI操縱數(shù)據(jù)庫(kù)Hibernate對(duì)JDBC進(jìn)行了封裝,提供了更加面向?qū)ο蟮腁PI。以下兩圖對(duì)比了直接通過JDBCAPI以及通過HibernateAPI來訪問數(shù)據(jù)庫(kù)的兩種方式。以下示例的BusinessService類演示了通過HibernateAPI對(duì)Customer對(duì)象進(jìn)行持久化的操作。packageimport.*;importimportimport.*;importimportimport.*;publicclassBusinessService{publicstaticSessionFactorysessionFactory;/**初始化Hibernate,創(chuàng)建SessionFactory實(shí)例*/static{try{publicvoidsaveCustomer(Customercustomer)throwsException{……}/**按照OID加載一個(gè)Customer對(duì)象,然后修改它的屬性*/publicvoidloadAndUpdateCustomer(Longcustomer_id,Stringaddress)throwsException{……}/**刪除所有的Customer對(duì)象*/publicvoiddeleteAllCustomers()throwsException{Sessionsession=();Transactiontx=null;try{tx=();("fromCustomerasc");();}catch(Exceptione){if(tx!=null){();}throwe;}finally{();}}/**選擇向控制臺(tái)還是動(dòng)態(tài)網(wǎng)頁(yè)輸出Customer對(duì)象的信息*/privatevoidprintCustomer(ServletContextcontext,OutputStreamout,Customercustomer)throwsException{if(outinstanceofServletOutputStream)printCustomer(context,(ServletOutputStream)out,customer);elseprintCustomer((PrintStream)out,customer);}/**把Customer對(duì)象的信息輸出到控制臺(tái),如DOS控制臺(tái)*/privatevoidprintCustomer(PrintStreamout,Customercustomer)throwsException{……}/**把Customer對(duì)象的信息輸出到動(dòng)態(tài)網(wǎng)頁(yè)*/privatevoidprintCustomer(ServletContextcontext,ServletOutputStreamout,Customercustomer)throwsException{……}publicvoidtest(ServletContextcontext,OutputStreamout)throwsException{Customercustomer=newCustomer();("Tom");");("("1234");();("Shanghai");('M');("Iamveryhonest.");etResourceAsStream("");byte[]buffer=newbyte[()];(buffer);(buffer);1980-05-06Beijing();}}以上例子演示了通過HibernateAPI訪問數(shù)據(jù)庫(kù)的一般流程。首先應(yīng)該在應(yīng)用的啟動(dòng)階段對(duì)Hibernate進(jìn)行初始化,然后就可以通過Hibernate的Session接口來訪問數(shù)據(jù)庫(kù)。Hibernate的初始化BusinessService類的靜態(tài)代碼塊負(fù)責(zé)Hibernate的初始化工作,如讀取Hibernate的配置信息以及對(duì)象-關(guān)系映射信息,最后創(chuàng)建SessionFactory實(shí)例。當(dāng)JVM(Java虛擬機(jī))加載BusinessService類時(shí),會(huì)執(zhí)行該靜態(tài)代碼塊。初始化過程包括如下步驟。(1)創(chuàng)建一個(gè)Configuration類的實(shí)例,Configuration類的構(gòu)造方法把默認(rèn)文件路徑下的配置文件中的配置信息讀入到內(nèi)存:Configurationconfig=newConfiguration();(2)調(diào)用Configuration類的addClass方法:;該方法把默認(rèn)文件路徑下的文件中的映射信息讀入到內(nèi)存中。(3)調(diào)用Configuration類的buildSessionFactory()方法:sessionFactory=();該方法創(chuàng)建一個(gè)SessionFactory實(shí)例,并把Configuration對(duì)象包含的所有配置信息拷貝到SessionFactory對(duì)象的緩存中。SessionFactory代表一個(gè)數(shù)據(jù)庫(kù)存儲(chǔ)源,如果應(yīng)用只有一個(gè)數(shù)據(jù)庫(kù)存儲(chǔ)源,那么只需創(chuàng)建一個(gè)SessionFactory實(shí)例。當(dāng)SessionFactory對(duì)象創(chuàng)建后,該對(duì)象不和Configuration對(duì)象關(guān)聯(lián)。因此如果再修改Configuration對(duì)象包含的配置信息,不會(huì)對(duì)SessionFactory對(duì)象有任何影響。訪問Hibernate的Session接口初始化過程結(jié)束后,就可以調(diào)用SessionFactory實(shí)例的openSession()方法來獲得Session實(shí)例,然后通過它執(zhí)行訪問數(shù)據(jù)庫(kù)的操作。Session接口提供了操縱數(shù)據(jù)庫(kù)的各種方法,如:save()方法:把Java對(duì)象保存數(shù)據(jù)庫(kù)中。update()方法:更新數(shù)據(jù)庫(kù)中的Java對(duì)象。delete()方法:把Java對(duì)象從數(shù)據(jù)庫(kù)中刪除。load()方法:從數(shù)據(jù)庫(kù)中加載Java對(duì)象。find()方法:從數(shù)據(jù)庫(kù)中查詢Java對(duì)象。Session是一個(gè)輕量級(jí)對(duì)象。通常將每一個(gè)Session實(shí)例和一個(gè)數(shù)據(jù)庫(kù)事務(wù)綁定,也就是說,每執(zhí)行一個(gè)數(shù)據(jù)庫(kù)事務(wù),都應(yīng)該先創(chuàng)建一個(gè)新的Session實(shí)例。如果事務(wù)執(zhí)行中出現(xiàn)異常,應(yīng)該撤銷事務(wù)。不論事務(wù)執(zhí)行成功與否,最后都應(yīng)該調(diào)用Session的close()方法,從而釋放Session實(shí)例占用的資源。以下代碼演示了用Session來執(zhí)行事務(wù)的流程,其中Transaction類用來控制事務(wù)。Sessionsession=();Transactiontx;try{.Shanghai,values(1,'Tom',','1980-05-06',null)在test()方法中并沒有設(shè)置Customer對(duì)象的id屬性,Hibernate會(huì)根據(jù)映射文件的配置,采用increment標(biāo)識(shí)符生成器自動(dòng)以遞增的方式為OID賦值。在文件中相關(guān)的映射代碼如下:<idname="id"column="ID"type="long"><generatorclass="increment"/></id>在test()方法中也沒有設(shè)置Customer對(duì)象的registeredTime屬性,因此在以上insert語(yǔ)句中,REGISTERED_TIME字段的值為null。但由于REGISTERED_TIME字段的SQL類型為TIMESTAMP類型,如果insert語(yǔ)句沒有為TIMESTAMP類型的字段賦值,底層數(shù)據(jù)庫(kù)會(huì)自動(dòng)把當(dāng)前的系統(tǒng)時(shí)間賦值給TIMESTAMP類型的字段。因此,執(zhí)行完以上insert語(yǔ)句后,REGISTERED_TIME字段的值并不為null,而是插入該記錄時(shí)的系統(tǒng)時(shí)間。2.findAllCustomers()方法該方法調(diào)用Session的find()方法,查詢所有的Customer對(duì)象。tx=();Listcustomers=("fromCustomerascorderbyasc");for(Iteratorit=();();){printCustomer(context,out,(Customer)());}();Session的find()方法有好幾種重載形式,本例中傳遞的是字符串參數(shù)“fromCustomerascorderbyasc”,它使用的是Hibernate查詢語(yǔ)言。運(yùn)行()方法時(shí),Hibernate執(zhí)行以下SQL語(yǔ)句:select*fromCUSTOMERSorderbyNAMEasc;3.loadAndUpdateCustomer()方法該方法調(diào)用Session的load()方法,加載Customer對(duì)象,然后再修改Customer對(duì)象的屬性。tx=();Customerc=(Customer),customer_id);(address);();以上代碼先調(diào)用Session的load()方法,它按照參數(shù)指定的OID從數(shù)據(jù)庫(kù)中檢索出匹配的Customer對(duì)象,Hibernate會(huì)執(zhí)行以下SQL語(yǔ)句:select*fromCUSTOMERSwhereID=1;loadAndUpdateCustomer()方法接著修改Customer對(duì)象的address屬性。那么,Hibernate會(huì)不會(huì)同步更新數(shù)據(jù)庫(kù)中相應(yīng)的CUSTOMERS表的記錄呢答案是肯定的。Hibernate采用臟檢查機(jī)制,按照內(nèi)存中的Customer對(duì)象的狀態(tài)的變化,來同步更新數(shù)據(jù)庫(kù)中相關(guān)的數(shù)據(jù),Hibernate會(huì)執(zhí)行以下SQL語(yǔ)句:updateCUSTOMERSsetNAME="Tom",EMAIL=""…ADDRESS="Beijing"…盡管只有Customer對(duì)象的address屬性發(fā)生了變化,但是Hibernate執(zhí)行的update語(yǔ)句中會(huì)包含所有的字段。在BusinessService類的test()方法中按如下方式調(diào)用loadAndUpdateCustomer()方法:saveCustomer(customer);loadAndUpdateCustomer(),"Beijing");以上代碼并沒有直接給customer對(duì)象的id屬性賦值,當(dāng)執(zhí)行saveCustomer(customer)方法時(shí),Session的save()方法把customer對(duì)象持久化到數(shù)據(jù)庫(kù)中,并自動(dòng)為id屬性賦值。4.printCustome

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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)論