就業(yè)培訓(xùn)教材_第1頁(yè)
就業(yè)培訓(xùn)教材_第2頁(yè)
就業(yè)培訓(xùn)教材_第3頁(yè)
就業(yè)培訓(xùn)教材_第4頁(yè)
就業(yè)培訓(xùn)教材_第5頁(yè)
已閱讀5頁(yè),還剩7頁(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)介

1、第三十四章: 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)部封裝了通過(guò) 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) 通過(guò) Hibernate API編寫訪

2、問數(shù)據(jù)庫(kù)的代碼。建立簡(jiǎn)單的 Hibernate應(yīng)用本章通過(guò)一個(gè)簡(jiǎn)單的例子 customerApp 應(yīng)用,演示如何運(yùn)用 Hibernate 來(lái)訪問關(guān)系數(shù)據(jù)庫(kù)。 customerApp 應(yīng)用的功能非常簡(jiǎn)單:通過(guò) Hibernate 保存、更新、刪除、加載以及查詢 Customer 對(duì)象。創(chuàng)建 Hibernate的配置文件Hibernate從其配置文件中讀取和數(shù)據(jù)庫(kù)連接有關(guān)的信息,這個(gè)配置文件應(yīng)該位于應(yīng)用的 classpath中。 Hibernate的配置文件有兩種形式:一種是XML 格式的文件;還有一種是 Java 屬性文件,采用“健 =值”的形式。 下面介紹如何以 Java 屬性文件的格式來(lái)創(chuàng)建

3、 Hibernate 的配置文件。這種配置文件的默認(rèn)文件名為。的內(nèi)容如下 :=true以上文件包含了一系列屬性及其屬性值, Hibernate 將根據(jù)這些屬性來(lái)連接數(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è)

4、為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ū)的人既能說(shuō)標(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í)體域類。持久化類符合 Jav

5、aBean 的規(guī)范,包含一些屬性,以及與之對(duì)應(yīng)的 getXXX() 和 setXXX() 方法。以下定義了一個(gè)名為 Customer 的持久化類。packageimportimportimportpublic class Customer implements Serializableprivate Long id;private String name;private String email;private String password;private int phone;private boolean married;private String address;private cha

6、r sex;private String description;private byte image;private Date birthday;private Timestamp registeredTime;public Customer()public Long getId()return id;public void setId(Long id)= id;public String getName()return name;public void setName(String name)=name;quals()的結(jié)果是 true ,就表示 customerA和 customerB對(duì)

7、象指的是同一個(gè)客戶,它們和 CUSTOMERS表中的同一條記錄對(duì)應(yīng)。Hibernate要求持久化類必須提供一個(gè)不帶參數(shù)的默認(rèn)構(gòu)造方法,在程序運(yùn)行時(shí),Hibernate運(yùn)用 Java 反射機(jī)制,調(diào)用方法來(lái)構(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 類中沒有引入任何 Hibernate API ,Customer 類不需要繼承 Hibernate 的類,或?qū)崿F(xiàn)

8、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定義如下:create table CUSTOMERS(ID bigint not null primary key,NAME varchar(15) not null,EMAIL varchar(128) not null,PASSWORD varchar(8) not null,PHONE int ,AD

9、DRESS varchar(255),SEX char(1) ,IS_MARRIED bit,DESCRIPTION text,IMAGE blob,BIRTHDAY date,REGISTERED_TIME timestamp);CUSTOMERS表有一個(gè) ID字段,它是表的主鍵,它和Customer類的 id屬性對(duì)應(yīng)。 CUSTOMERS表中的字段使用了各種各樣的SQL 類型,參見下表。字段名SQL類型說(shuō)明IDBIGINT整數(shù),占 8 字節(jié),取值范圍為: -263 263-1NAMEVARCHAR變長(zhǎng)字符串,占0 255 個(gè)字節(jié)SEXCHAR定長(zhǎng)字符串,占0 255個(gè)字節(jié)IS_MARRIE

10、DBIT布爾類型DESCRIPTIONTEXT長(zhǎng)文本數(shù)據(jù),占0 65535 255 字節(jié)。如果字符串長(zhǎng)度小于255 ,可以用 VARCHAR或 CHAR類型來(lái)表示。 如果字符串長(zhǎng)度大于255 ,可以定義為 TEXT類型。IMAGEBLOB二進(jìn)制長(zhǎng)數(shù)據(jù),占0 65535字節(jié), BLOB是Binary Large Object的縮寫。 IMAGE在本例BIRTHDAY DATE REGISTERED_TIMETIMESTAMP中, 字段用來(lái)存放圖片數(shù)據(jù)代表日期,格式為“ YYYY-MM-DD”代表日期和時(shí)間,格式為“YYYYMMDDHHMMSS”創(chuàng)建對(duì)象 - 關(guān)系映射文件Hibernate 采用

11、XML格式的文件來(lái)指定對(duì)象和關(guān)系數(shù)據(jù)之間的映射。在運(yùn)行時(shí), Hibernate 將根據(jù)這個(gè)映射文件來(lái)生成各種 SQL 語(yǔ)句。在本例中,將創(chuàng)建一個(gè)名為 的文件,它用于把 Customer 類映射到 CUSTOMERS表,這個(gè)文件應(yīng)該和 文件存放在同一個(gè)目錄下。以下為文件的源代碼。!DOCTYPE hibernate-mapping PUBLIC -java Error reading resource: mypack/at把 Customer 持久化類映射到CUSTOMERS表文件用于映射 Customer 類。如果需要映射多個(gè)持久化類,那么既可以在同一個(gè)映射文件中映射所有類,也可以為每個(gè)類創(chuàng)建

12、單獨(dú)的映射文件,映射文件和類同名,擴(kuò)展名為“”。后一種做法更值得推薦,因?yàn)樵趫F(tuán)隊(duì)開發(fā)中,這有利于管理和維護(hù)映射文件。 元素指定類和表的映射, 它的 name屬性設(shè)定類名, table 屬性設(shè)定表名。以下代碼表明和 Customer 類對(duì)應(yīng)的表為 CUSTOMERS表:如果沒有設(shè)置 元素的 table 屬性, Hibernate 將直接以類名作為表名,也就是說(shuō),默認(rèn)情況下,與 類對(duì)應(yīng)的表為 Customer 表。 元素包含一個(gè) 子元素以及多個(gè) 子元素。 子元素設(shè)定持久化類的 OID 和表的主鍵的映射。以下代碼表明 Customer類的 id屬性和 CUSTOMERS表中的 ID 字段對(duì)應(yīng)。 元素

13、的 子元素指定對(duì)象標(biāo)識(shí)符生成器,它負(fù)責(zé)為OID 生成惟一標(biāo)識(shí)符。 子元素設(shè)定類的屬性和表的字段的映射。 子元素主要包括 name、 type 、 column 和 not-null屬性。1 元素的 name屬性 元素的 name屬性指定持久化類的屬性的名字。2 元素的 type 屬性 元素的type 屬性指定 Hibernate映射類型。 Hibernate映射類型是Java 類型與 SQL 類型的橋梁。3 元素的 not-null如果 元素的not-nullfalse 。例如以下代碼表明不允許屬性屬性為 true,表明不允許為Customer 類的 name屬性為 nullnull :,默認(rèn)

14、為Hibernate在持久化一個(gè)Customer對(duì)象時(shí),會(huì)先檢查它的null ,如果為 null ,就會(huì)拋出以下異常:name屬性是否為not-null property referencesa null or transient value:如果數(shù)據(jù)庫(kù)中 CUSTOMERS表的 NAME 字段不允許為 null,但在映射文件中沒有設(shè)置 not-null 屬性:那么 Hibernate 在持久化一個(gè) Customer 對(duì)象時(shí),不會(huì)先檢查它的name 屬性是否為 null而是直接通過(guò)JDBC API向CUSTOMERS表的 NAME字段設(shè)置了 not nullCUSTOMERS表插入相應(yīng)的數(shù)據(jù),

15、由于約束,因此數(shù)據(jù)庫(kù)會(huì)拋出錯(cuò)誤:708 ERRORJDBCExceptionReporter:58- General error, messagefrom server:Column NAME cannot be null4 元素的column 屬性 元素的 column 屬性指定與類的屬性映射的表的字段名。以下代碼表明和 address 屬性對(duì)應(yīng)的字段為 ADDRESS字段:如果沒有設(shè)置 元素的 column 屬性, Hibernate 將直接以類的屬性名作為字段名,也就是說(shuō),默認(rèn)情況下,與 Customer 類的 address 屬性對(duì)應(yīng)的字段為 address 字 段 。 元素還 可以

16、包括 子 元素 ,它 和 元素的 column 屬性一樣,都可以設(shè)定與類的屬性映射的表的字段名。以下兩種設(shè)置方式是等價(jià)的: 或者 元素的 子元素比 column 屬性提供更多的功能,它可以更加詳細(xì)的描述表的字段。例如以下 子元素指定 CUSTOMERS表中的 NAME 字段的 SQL 類型為 varchar(15) ,不允許為 null ,并且為這個(gè)字段建立了索引:通過(guò) Hibernate API操縱數(shù)據(jù)庫(kù)Hibernate對(duì) JDBC進(jìn)行了封裝,提供了更加面向?qū)ο蟮腁PI 。以下兩圖對(duì)比了直接通過(guò) JDBC API以及通過(guò) Hibernate API來(lái)訪問數(shù)據(jù)庫(kù)的兩種方式。以下示例的 Bus

17、inessService行持久化的操作。類演示了通過(guò)Hibernate API對(duì)Customer對(duì)象進(jìn)packageimport .*;importimportimport .*;importimportimport .*;public class BusinessServicepublic static SessionFactory sessionFactory;/*初始化Hibernate,創(chuàng)建SessionFactory實(shí)例*/statictrypublic void saveCustomer(Customer customer) throws Exception/*按照 OID 加載一

18、個(gè) Customer 對(duì)象,然后修改它的屬性*/publicvoidloadAndUpdateCustomer(Longcustomer_id,Stringthrows Exception address)/* 刪除所有的 Customer 對(duì)象 */public void deleteAllCustomers() throws ExceptionSession session = ();Transaction tx = null;try tx = ();(from Customer as c);();catch (Exception e) if (tx != null) ();throw e

19、; finally ();/*選擇向控制臺(tái)還是動(dòng)態(tài)網(wǎng)頁(yè)輸出Customer 對(duì)象的信息 */privatevoidprintCustomer(ServletContextcontext,OutputStreamout,Customer customer)throws Exceptionif(out instanceof ServletOutputStream)printCustomer(context,(ServletOutputStream) out,customer);elseprintCustomer(PrintStream) out,customer);/*把 Customer 對(duì)象的

20、信息輸出到控制臺(tái),如DOS控制臺(tái) */privatevoidprintCustomer(PrintStreamout,Customercustomer)throwsException /*把 Customer 對(duì)象的信息輸出到動(dòng)態(tài)網(wǎng)頁(yè)privatevoidprintCustomer(ServletContextout,Customer customer)throws Exception */context,ServletOutputStreampublicvoidtest(ServletContextcontext,OutputStreamout)throwsExceptionCustomer

21、 customer=new Customer();(Tom););(1234);();(Shanghai);(M);(I am very honest.);etResourceAsStream();byte buffer = new byte();(buffer);(buffer);1980-05-06Beijingest(null,;();以上例子演示了通過(guò) Hibernate API 訪問數(shù)據(jù)庫(kù)的一般流程。首先應(yīng)該在應(yīng)用的啟動(dòng)階段對(duì) Hibernate 進(jìn)行初始化,然后就可以通過(guò) Hibernate 的 Session 接口來(lái)訪問數(shù)據(jù)庫(kù)。Hibernate的初始化BusinessServi

22、ce 類的靜 態(tài)代 碼塊負(fù)責(zé) Hibernate 的 初始化工作, 如讀 取 Hibernate 的配置信息以及對(duì)象 - 關(guān)系映射信息,最后創(chuàng)建 SessionFactory 實(shí)例。當(dāng) JVM(Java 虛擬機(jī))加載 BusinessService 類時(shí),會(huì)執(zhí)行該靜態(tài)代碼塊。初始化過(guò)程包括如下步驟。(1)創(chuàng)建一個(gè) Configuration 類的實(shí)例, Configuration 類的構(gòu)造方法把默認(rèn)文件路徑下的配置文件中的配置信息讀入到內(nèi)存:Configuration config = new Configuration();(2)調(diào)用 Configuration類的 addClass 方法:

23、;該方法把默認(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)。因此如果再修改 Confi

24、guration對(duì)象包含的配置信息,不會(huì)對(duì)SessionFactory對(duì)象有任何影響。訪問 Hibernate 的 Session 接口初始化過(guò)程結(jié)束后,就可以調(diào)用 SessionFactory 實(shí)例的 openSession()方法來(lái)獲得 Session 實(shí)例,然后通過(guò)它執(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ù)中查

25、詢Java 對(duì)象。Session 是一個(gè)輕量級(jí)對(duì)象。通常將每一個(gè)Session 實(shí)例和一個(gè)數(shù)據(jù)庫(kù)事務(wù)綁定,也就是說(shuō),每執(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 來(lái)執(zhí)行事務(wù)的流程,其中 Transaction 類用來(lái)控制事務(wù)。Session session = ();Transaction tx;try .Shanghai,values(1,Tom,1980-05-06,null)在

26、 test() 方法中并沒有設(shè)置 Customer 對(duì)象的 id 屬性, Hibernate 會(huì)根據(jù)映射文件的配置,采用 increment 標(biāo)識(shí)符生成器自動(dòng)以遞增的方式為 OID 賦值。在 文件中相關(guān)的映射代碼如下: 在 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í)間賦值給TIM

27、ESTAMP類型的字段。因此,執(zhí)行完以上insert語(yǔ)句后, REGISTERED_TIME字段的值并不為null,而是插入該記錄時(shí)的系統(tǒng)時(shí)間。2 findAllCustomers()方法該方法調(diào)用 Session 的 find()方法,查詢所有的Customer 對(duì)象。tx = ();List customers=(from Customer as c order by asc); for (Iterator it = (); ();) printCustomer(context,out,(Customer) ();();Session的 find()方法有好幾種重載形式,本例中傳遞的是字符

28、串參數(shù)“fromCustomer as c order by asc ”,它使用的是 Hibernate 查詢語(yǔ)言。運(yùn)行 () 方法時(shí), Hibernate 執(zhí)行以下 SQL語(yǔ)句:select * from CUSTOMERS order by NAME asc;3 loadAndUpdateCustomer ()方法該方法調(diào)用 Session 的 load() 方法,加載 Customer 對(duì)象,然后再修改 Customer 對(duì)象的屬性。tx = ();Customer c=(Customer),customer_id);(address);();以上代碼先調(diào)用 Session 的 load

29、() 方法,它按照參數(shù)指定的 OID 從數(shù)據(jù)庫(kù)中檢索出匹配的 Customer 對(duì)象, Hibernate 會(huì)執(zhí)行以下 SQL 語(yǔ)句:select * from CUSTOMERS where ID=1;loadAndUpdateCustomer() 方法接著修改 Customer 對(duì)象的 address 屬性。那么, Hibernate 會(huì)不會(huì)同步更新數(shù)據(jù)庫(kù)中相應(yīng)的 CUSTOMERS表的記錄呢答案是肯定的。 Hibernate 采用臟檢查機(jī)制,按照內(nèi)存中的 Customer 對(duì)象的狀態(tài)的變化,來(lái)同步更新數(shù)據(jù)庫(kù)中相關(guān)的數(shù)據(jù),Hibernate會(huì)執(zhí)行以下 SQL語(yǔ)句:update CUSTOM

30、ERS set NAME=Tom,EMAIL= ADDRESS=Beijing盡管只有Customer 對(duì)象的address屬性發(fā)生了變化,但是update 語(yǔ)句中會(huì)包含所有的字段。在 BusinessService類的Hibernate執(zhí)行的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. printCustomer()方法該方法打印 Customer對(duì)象的信息,它有三種重載形式。當(dāng)helloapp應(yīng)用作為獨(dú)立 應(yīng)用 程序 運(yùn)行 時(shí), 將調(diào) 用printCustomer(PrintStreamout,Customercustomer) 方法

溫馨提示

  • 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ù)覽,若沒有圖紙預(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)論