版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第一章 Hibernate入門 理解Hiberate原理 掌握如何搭建Hibernate開發(fā)環(huán)境 理解持久化對象的狀態(tài)與轉換 掌握Hibernate的配置 了解Hibernate的常用接口1本章指引1.1 SSH概述1.2 Hibernate簡介1.3 第一個HiBernate項目1.4 映射文件詳解1.5 配置文件詳解1.6 Hibernate持久化對象1.7 Hibernate的核心接口簡介1.8 上機實驗21.1 SSH概述 3SSH是JavaEE的 spring,struts2,Hibernate三大框架的縮寫SpringStructs2HibernateDAO層控制層提高數(shù)據(jù)庫的操作
2、效率控制程序的跳轉。使用了MVC原理以及文件上傳下載、數(shù)據(jù)驗證、眾多功能標簽等技術為類與類之間的過度依賴提供解決方案,以及方便地以AOP方式切入系統(tǒng)級業(yè)務,并且接管Hibernate的數(shù)據(jù)庫配置,事務管理等,整合了其余兩個框架。1.2 Hibernate簡介 Hibernate是當前流行的一種ORM(Object Relational Mapping,對象關系映射)框架。所謂ORM就是對象和關系型數(shù)據(jù)庫表之間的一種映射關系,可以自動把應用程序中的對象,持久化到關系型數(shù)據(jù)庫的表中,反之也可把關系型數(shù)據(jù)庫的表中的一條記錄讀取出來并轉化為程序中的一個對象。什么是ORM?有了ORM,JavaEE開發(fā)者
3、就可以使用面向對象的編程思想來操作數(shù)據(jù)庫,取代傳統(tǒng)的JDBC。通過操作Java對象,就可以完成對數(shù)據(jù)庫表的操作。1.2 Hibernate簡介 Hibernate對應三層架構開發(fā)中的數(shù)據(jù)訪問層、JDBC訪問數(shù)據(jù)庫的代碼做了輕量級封,是“全自動”的ORM框架。支持許多面向對象的特性,如組合,繼承,多態(tài)等,Java開發(fā)者可以自由地使用對象編程思維來操縱數(shù)據(jù)庫支持一對多,多對多關聯(lián),連接查詢,級聯(lián)操作,緩存等,功能強大可移植性好,可適用于多種數(shù)據(jù)庫是一種開源框架,必要時可以自行編碼進行擴展??梢宰詣由蒘QL語句并自動執(zhí)行不能使用存儲過程不太適合大規(guī)模的批處理不適合小型項目與MyBatis相比,較為
4、復雜,不易掌握。使用面向對象的HQL查詢語言,有些人使用起來不太習慣。特點缺點1.2 Hibernate簡介 /projects/hibernate/files/hibernate3/點擊圖1.2中的3.6.10.Final鏈接下載其中的hibernate-distribution-3.6.10.Final-dist.zip壓縮包解壓后文件結構如圖1.4所示下載Hiberante 1.2 Hibernate簡介 Hiberante項目必須的jar包 log4j-1.2.17.jar和slf4j-log4j12-1.7.12.jar這2個jar包用于整合Hibernate的日志系統(tǒng)log4j(這
5、兩個jar包需要另外上網(wǎng)搜索下載)1.3 第一個Hibernate項目 1.3.1 創(chuàng)建項目并導入JAR包 首先在Eclipse中創(chuàng)建一個Web項目ssh01 將表1.1中Hibernate所需10個jar包復制到項目的WEB-INF/lib目錄中 此外還需要連接MySQL數(shù)據(jù)庫,需要添加MySQL的驅動包,本書中使用的 MySQL驅動版本是mysql-connector-java-5.1.21.jar 復制好后,添加到構建路徑中1.3 第一個Hibernate項目 1.3.2 創(chuàng)建數(shù)據(jù)庫及表本書使用的數(shù)據(jù)庫為MySQL5.7.18,客戶端使用SQLyog在MySQL中創(chuàng)建一個名稱為stude
6、ntdb的數(shù)據(jù)庫,在此數(shù)據(jù)庫中創(chuàng)建一張名為student的數(shù)據(jù)表1.3 第一個Hibernate項目 1.3.3 創(chuàng)建持久化類持久化類與數(shù)據(jù)庫表相對應,持久化類的屬性名稱、個數(shù)、類型都與數(shù)據(jù)庫表的列名、個數(shù)、類型一一對應。在項目src目錄下,創(chuàng)建com.seehope.entity包,并在包中創(chuàng)建持久化類Student,類中創(chuàng)建與student數(shù)據(jù)表字段對應的屬性,以及相應的getter和setter方法1.3 第一個Hibernate項目 節(jié)點 配置持久化類的映射信息;它的name屬性對應持久化類名,table屬性對應數(shù)據(jù)庫中的表名。節(jié)點 節(jié)點下;用來定義持久化類的主鍵屬性(對應數(shù)據(jù)庫表中的
7、主鍵);name屬性對應持久化類的主鍵屬性,column屬性對應數(shù)據(jù)庫表中的主鍵列子節(jié)點 節(jié)點下;用于指定主鍵的生成策略。這里設置成“native”表示主鍵由數(shù)據(jù)庫自動生成而不是在程序中指定。節(jié)點 節(jié)點下;用于映射實體對象的普通屬性。其name屬性對應實體中的普通屬性,column屬性對應數(shù)據(jù)庫表中的普通字段(非主鍵),type屬性表示其屬性的數(shù)據(jù)類型。1.3.4 創(chuàng)建映射文件映射文件的作用是告知Hibernate,持久化類Student映射到數(shù)據(jù)庫studentdb中的哪個表,并且進一步精確地指定持久化類中的哪個屬性對應數(shù)據(jù)庫表中的哪個字段。在持久化類Student所在包中,新建一個名稱為S
8、tudent.hbm.xml的映射文件,在該文件中指定了持久化類Student與數(shù)據(jù)庫中的哪個表對應,以及類Student中的每一個屬性與數(shù)據(jù)庫student表的字段一一對應。Student.hbm.xml中的主要節(jié)點1.3 第一個Hibernate項目 1.3.5 創(chuàng)建核心配置文件Hibernate的配置文件主要用來配置數(shù)據(jù)庫連接以及Hibernate運行時所需要的各個屬性的值。在項目的src目錄下創(chuàng)建一個名稱為hibernate.cfg.xml的文件,代碼如下。該文件將會在本章1.5節(jié)詳細介紹。1.3 第一個Hibernate項目 1.3.5 創(chuàng)建核心配置文件1.3 第一個Hibernat
9、e項目 1.3.6 創(chuàng)建測試類進行增刪改查操作 在項目中新建一個名稱為com.seehope.test的包,然后創(chuàng)建Main.java文件。接下來,在該文件中創(chuàng)建4個方法分別進行增刪改查操作。 添加數(shù)據(jù):在Main類中編寫添加數(shù)據(jù)的方法insertTest(),實現(xiàn)添加一個學生的功能1.3 第一個Hibernate項目 1.3.6 創(chuàng)建測試類進行增刪改查操作1.3 第一個Hibernate項目 1.3.6 創(chuàng)建測試類進行增刪改查操作使用JUnit4測試運行insertTest()后在MySQL數(shù)據(jù)庫中查詢student表的數(shù)據(jù)從圖1.8中可以看出,student表中添加數(shù)據(jù)成功。這里添加數(shù)據(jù)的
10、關鍵方法是session.save(stu),給人感覺保存的是Student對象stu,實際結果卻是數(shù)據(jù)庫中新添加了一條記錄,這正是hibernate的重要特性,通過操作對象就能實現(xiàn)數(shù)據(jù)庫操作。1.3 第一個Hibernate項目 1.3.6 創(chuàng)建測試類進行增刪改查操作 修改數(shù)據(jù):在Main類中添加updateTest()方法,使用Hibernate來修改id為2的數(shù)據(jù)Hibernate修改數(shù)據(jù)的基本流程與其保存數(shù)據(jù)的方法大體相同,只是后面創(chuàng)建了一個對象,且該對象的id是要在數(shù)據(jù)庫表中事先存在的,其他屬性值則可以設置成與數(shù)據(jù)庫表中對應的值不同。最后通過session.update()方法執(zhí)行更
11、新操作,表面上給人感覺是更新對象,實際上數(shù)據(jù)會更新到數(shù)據(jù)庫中。1.3 第一個Hibernate項目 1.3.6 創(chuàng)建測試類進行增刪改查操作使用JUnit4測試運行updateTest()方法,其結果如圖1.9所示。發(fā)現(xiàn)id為2的記錄已由李白改成了杜甫。1.3 第一個Hibernate項目 1.3.6 創(chuàng)建測試類進行增刪改查操作 查詢單個對象數(shù)據(jù):在Main類中,添加一個名稱為getByIdTest()的查詢數(shù)據(jù)的方法,用于根據(jù)指定id查詢數(shù)據(jù)庫中的數(shù)據(jù),這里查詢id為1的學生數(shù)據(jù)。查詢操作使用了session.get()的方法,該方法有兩個參數(shù),第一個參數(shù)指定要操作的類,第二個參數(shù)id指明要查
12、找的對象的主鍵,該方法用于從數(shù)據(jù)庫中查找到指定主鍵的數(shù)據(jù)并封裝成對象數(shù)據(jù)。1.3 第一個Hibernate項目 1.3.6 創(chuàng)建測試類進行增刪改查操作使用JUnit4測試運行getByIdTest()方法后,控制臺的顯示如圖所示。圖1.10查詢結果分析:控制臺頭部出現(xiàn)了三行紅色警告信息,這是因為沒有配置log4j導致的,這里可以不必理會,接著出現(xiàn)了黑色的SQL語句信息,這是由于在hibernate.cfg.xml文件中配置了顯示SQL語句和格式化SQL的配置信息,這說明Hibernate發(fā)出了SQL語句,向數(shù)據(jù)庫查詢需要的數(shù)據(jù)。最后出現(xiàn)的是查詢結果。除了使用Session的get()方法查找指
13、定對象id的數(shù)據(jù)外,還有Session的load()方法也可實現(xiàn)同樣的功能,區(qū)別在于使用get()方法加載數(shù)據(jù)時,如果要查找的記錄不存在,則返回null,不會報錯。使用load()方法加載數(shù)據(jù)時,如果要查找的記錄不存在,則會報出ObjectNotfoundException異常。1.3 第一個Hibernate項目 1.3.6 創(chuàng)建測試類進行增刪改查操作 刪除數(shù)據(jù):在Main類中增加一個名稱為deleteByIdTest()的方法,使用Hibernate刪除一條記錄,這里刪除id為5的學生數(shù)據(jù),代碼如下所示。從圖1.11中可以看出,Student表中少了第5條,已被成功刪除了。首先通過get方
14、法獲得要刪除的對象,然后使用Session的delete方法將該對象作為參數(shù),從而在數(shù)據(jù)庫中將它刪除。1.3 映射文件詳解 Hibernate映射文件用于配置將POJO對象持久化到關系型數(shù)據(jù)庫中的相關信息,一個持久化類對應一個映射文件,映射文件的基本結構如下所示。1.3 映射文件詳解 節(jié)點用來聲明一個持久化類并且指定了Java持久化類與數(shù)據(jù)庫表之間的映射關系主要節(jié)點說明節(jié)點用來設定持久化類的OID(Object Identifier對象標識符,唯一地標識一個對象,類似表的主鍵)和數(shù)據(jù)庫表的主鍵的映射關系??蛇x的子節(jié)點:結點用于指定了主鍵的生成方式,也稱為主鍵生成策略。主鍵既可以通過程序指定,也
15、可由數(shù)據(jù)庫自動生成,但數(shù)據(jù)庫自動生成的話因不同數(shù)據(jù)庫還是有所差別,比如MySQL的主鍵可以通過自增長實現(xiàn),SQL Server通過標識列實現(xiàn),而Oracle的要通過序列才能實現(xiàn)。通過節(jié)點,就可以指定這些不同的實現(xiàn)方式。1.3 映射文件詳解 主要節(jié)點說明Hibernate提供了幾個內置的主鍵生成策略,如表所示。節(jié)點用來指定持久化類的普通屬性與數(shù)據(jù)庫表中的普通字段的映射關系。property節(jié)點的常用屬性有name、column和type三個。name用來指定持久化類中的屬性名,column用來指定數(shù)據(jù)庫表中的對應字段名,type用來指定持久化類屬性的數(shù)據(jù)類型。1.5 配置文件詳解 1.5.1 基
16、本配置hibernate.cfg.xml配置文件使用property節(jié)點來配置Hibernate連接數(shù)據(jù)庫的一些重要信息,如數(shù)據(jù)庫的方言、驅動、URL、用戶名和密碼等,并使用mapping節(jié)點來加載映射文件的信息。文件名稱固定為hibernate.cfg.xml,一般放置在src目錄下。hibernate.cfg.xml配置文件的常見配置請參見1.3.5。其常用屬性名稱及用途如表所示。1.5 配置文件詳解 1.5.2 配置c3p0連接池Hibernate中也可以使用c3p0連接池進行連接以提高數(shù)據(jù)庫連接的性能與效率。在下載的Hibernate解壓縮包的lib目錄下的子目錄optional中找到
17、C3P0的jar包c3p0-0.9.1.jar,復制到項目ssh01的WebContent/WEB-INF/lib下,并添加到構建路徑,然后在hibernate.cfg.xml中新添加如下代碼使用Junit4運行測試類Main中的insertTest()方法。查看數(shù)據(jù)庫,插入數(shù)據(jù)成功,表明C3P0連接池的配置成功。1.6 Hibernate持久化對象的狀態(tài) 1.6.1 持久化對象的狀態(tài)持久化就是指將Java運行時的對象數(shù)據(jù)永久存儲到關系型數(shù)據(jù)庫中。在Hibernate中,根據(jù)內存中的對象與數(shù)據(jù)庫表中對應記錄是否同步關聯(lián),持久化對象分為三種狀態(tài),分別是瞬時狀態(tài)、持久狀態(tài)和游離狀態(tài)。瞬時狀態(tài)(tr
18、ansient)瞬時狀態(tài)是指內存中的對象剛剛創(chuàng)建(new)出來,還沒有與Session關聯(lián),與數(shù)據(jù)庫中的數(shù)據(jù)無任何關聯(lián),在數(shù)據(jù)庫中沒有對應的記錄,在內存中孤立存在著,若無其他操作或引用,最后將會被JVM垃圾回收。瞬時對象沒有持久化標識OID。持久狀態(tài)(persistent)持久狀態(tài)的對象與session相關聯(lián),且相關聯(lián)的Session尚未關閉,在數(shù)據(jù)庫有對應的記錄,持久狀態(tài)對象有持久化標識OID。游離狀態(tài)(detached)當持久化對象相關聯(lián)的session關閉時就變成了游離狀態(tài)。雖然此時對象仍有OID,并且數(shù)據(jù)庫中有對應的記錄,但該對象沒有與session相關聯(lián),Hibernate已檢測不到
19、它的變化。1.6 Hibernate持久化對象的狀態(tài) 1.6.2 持久化對象狀態(tài)轉換Hibernate持久化對象的三種狀態(tài),是可以通過Session的一系列方法進行轉換的 瞬時狀態(tài)轉換到其他狀態(tài) 剛剛創(chuàng)建new出來是處于瞬時狀態(tài)。 瞬時狀態(tài)轉換為持久狀態(tài):執(zhí)行Session的save()或saveOrUpdate()方法。 瞬時狀態(tài)轉換為游離狀態(tài):為瞬時狀態(tài)對象設置持久化標識OID。 瞬時狀態(tài)和游離狀態(tài)都沒有Session的關聯(lián),它們的區(qū)別在于瞬時狀態(tài)沒有OID,游離狀態(tài)對象存在OID,1.6 Hibernate持久化對象的狀態(tài) 持久狀態(tài)對象轉換到其他狀態(tài) 持久化對象可以通過Session的g
20、et()、load()方法,或者Query查詢從數(shù)據(jù)庫獲得。 持久狀態(tài)轉換為瞬時狀態(tài):執(zhí)行Session的delete()方法,持久化對象被刪除后,雖然在內存中仍然存在,但不建議再使用,由JVM自行回收。 持久狀態(tài)轉換為游離狀態(tài):執(zhí)行Session的evict()、close()或clear()方法。evict()方法用于清除一級緩存中某一對象。close()方法用于關閉Session,清除一級緩存。clear()方法用于清楚一級緩存的所有對象。 游離狀態(tài)對象轉換到其他狀態(tài) 游離狀態(tài)對象不能直接獲得,只能由其他狀態(tài)對象轉換而來的。 游離狀態(tài)轉換為持久狀態(tài):執(zhí)行Session的update()、
21、saveOrUpdate()或lock()方法。 游離狀態(tài)轉換為瞬時狀態(tài):將游離狀態(tài)的的持久化標識OID設置為null。例如,在 BookTest.java中的session.close()操作后,加入代碼book.setId(null),當程序執(zhí)行完book.setId(null)代碼后,book對象由游離態(tài)轉換為瞬時狀態(tài)。1.6 Hibernate持久化對象的狀態(tài) 持久化對象的狀態(tài)實例 在ssh01項目的包com.seehope.test下新建TestState測試類上述代碼中,stu對象由new關鍵字創(chuàng)建,此時還未與Session進行關聯(lián),它的狀態(tài)為瞬時狀態(tài),在執(zhí)行了session.sa
22、ve(stu)操作后,stu對象被納入了Session的管理范圍,這時的stu對象變成了持久狀態(tài),程序執(zhí)行完了commit()操作并關閉了Session后,stu對象與Session的關聯(lián)被關閉,此時stu對象就變成了游離狀態(tài)。最后游離狀態(tài)清除了OID,又變成了瞬時狀態(tài)。1.6 Hibernate持久化對象的狀態(tài) 持久化對象的狀態(tài)實例 使用JUnit4測試運行,結果如下圖所示。從圖1.13可以看出執(zhí)行save()方法之前id值為null,這時它是屬于瞬時狀態(tài),執(zhí)行save()方法之后stu對象的id屬性有了值13(持久化標識OID),表明stu對象變成了持久狀態(tài),這也證明了瞬時狀態(tài)對象和持久狀
23、態(tài)對象的區(qū)別是:持久狀態(tài)對象OID有值并且與Session進行了關聯(lián)。當程序繼續(xù)向下執(zhí)行至session.close()時,stu對象脫離了session的管理,此時stu對象變成了游離狀態(tài),但stu對象的OID值依然存在,這也證明了游離狀態(tài)對象與持久狀態(tài)對象的相同點是都有OID值,不同點就是游離狀態(tài)對象沒有了Session關聯(lián)。1.7 Hibernate的核心接口簡介 在Hibernate中有Configuration、SessionFactory、Session、Transaction、Query、Critreia 共6個常用的核心接口。1.7.1 Configuration接口 Conf
24、iguration是最先用到的一個接口,使用Hibernate時,首先要創(chuàng)建Configuration實例才能開啟其他一系列操作。 Configuration實例主要用于啟動、加載和管理hibernate的配置文件。 Hibernate啟動時,Configuration實例會查找Hibernate配置文件hibernate.cfg.xml,讀取其相關配置,然后創(chuàng)建一個唯一的SessionFactory實例,創(chuàng)建完SessionFactory后,Configuration實例生命周期就此結束。Hibernate創(chuàng)建Configuration實例使用右述代碼這種方法默認會去src下讀取hibern
25、ate.cfg.xml配置文件。如果配置文件不是放在src下也是可以的,但需要指定其實際位置。1.7 Hibernate的核心接口簡介 1.7.2 SessionFactory接口 SessionFactory實例通過Configuration實例獲取,用于Hibernate的初始化和建立Session對象,其獲取過程如下代碼所示。 由于SessionFactory是線程安全的,它的同一個實例能同時給多個線程共享,并且它是重量級的不能隨便創(chuàng)建和銷毀它的實例,所以一個項目中一般只需要一個SessionFactory實例就行了(除非一個項目有多個數(shù)據(jù)源才需要創(chuàng)建多個SessionFactory實例
26、)。通常會抽取一個命名為HibernateUtils的工具類,在該工具類中創(chuàng)建一個靜態(tài)的SessionFactory對象,供各個方法調用,這樣各個方法就能共用同一個SessionFactory實例,HibernateUtils工具類中還提供創(chuàng)建Session實例的方法。該工具類的具體使用參見1.7.3節(jié)。1.7 Hibernate的核心接口簡介 1.7.3 Session接口 Session接口是Hibernate向應用程序提供的操作數(shù)據(jù)庫的接口,它提供了基本的保存,更新,刪除和查詢的方法。Session實例由SessionFactory實例的openSession()方法或getCurren
27、tSession方法獲得。區(qū)別是前者實例要手動關閉,后者實例在提交或回滾時自動關閉。 Session有以下特點: 它不是線程安全的,因此在軟件設計時,應該避免多個線程共享同一個Session實例。 Session實例是輕量級的,它的創(chuàng)建和銷毀不需要消耗太多的資源。這意味著在程序中可以經(jīng)常創(chuàng)建和銷毀Session對象,例如可以為每個方法單獨分配一個Session實例。 Session還有一個緩存,稱為Hibernate的一級緩存,它存放被當前工作單元加載的對象。每個Session實例都有自己的緩存,這個Sesion實例的緩存只能被當前工作單元訪問。 Session主要提供下面幾種方法。 save
28、(): 添加對象,將瞬時狀態(tài)的對象數(shù)據(jù)存入數(shù)據(jù)庫并變?yōu)槌志脿顟B(tài)。它使用映射文件指定的主鍵生成器為持久化對象分配唯一的OID。 update():修改對象,將游離狀態(tài)的對象轉變?yōu)槌志脿顟B(tài)。1.7 Hibernate的核心接口簡介 Session主要提供下面幾種方法。 saveOrUpdate():同時包含了save()與update()方法的功能,如果傳入的參數(shù)是瞬時狀態(tài)對象,調用save方法,如果參入?yún)?shù)是游離狀態(tài)對象,調用update()方法,如果傳入的是持久化對象,直接返回。 load()/get(): 兩者都是根據(jù)給定的OID從數(shù)據(jù)庫中加載一個持久化對象,區(qū)別在于,當數(shù)據(jù)庫中不存在與OI
29、D對應的記錄時,load()方法會拋出ObjectNotFoundException異常,而get()方法返回null. delete():用于從數(shù)據(jù)庫刪除一個Java對象,該方法傳入的參數(shù)既可以是持久狀態(tài)對象,也可以是游離狀態(tài)的對象。如果傳入的參數(shù)是游離狀態(tài)的對象,則會先使游離對象被當前Session關聯(lián),轉化為持久狀態(tài)對象,如果傳入的參數(shù)是持久狀態(tài)對象則沒有這一步。然后執(zhí)行SQL的delete語句,在數(shù)據(jù)庫中刪除該對象對應的記錄,最后將該對象從Session的緩存中刪除掉。 evict():從緩存中清除參數(shù)指定的持久狀態(tài)對象。 clear():清空緩存中所有持久化對象。1.7 Hibern
30、ate的核心接口簡介 使用下述案例中的HibernateUtils工具類可以完美地實現(xiàn)SessionFactory實例被多個方法(增刪改查操作各一個方法)共享,以及session實例則由各個方法獨立創(chuàng)建。并且大大簡化代碼量。項目案例:使用工具類簡化第一個項目(源碼請見本書配套資源:第1章/ssh01)。(1) src目錄新建包com.seehope.util,包下新建類HibernateUtils.java,參考代碼如下所示。有了上述HibernateUtils工具類,其他類就可以直接通過HibernateUtils.getSession()的方法獲取Session對象,從而簡化操作。1.7
31、Hibernate的核心接口簡介 (2)下面對Main類中的4個方法進行簡化。在包com.seehope.test下新建測試類Main2,簡化原來Main類的4個方法如下。1.7 Hibernate的核心接口簡介 1.7.4 Transaction接口 Transaction接口是Hibernate的數(shù)據(jù)庫事務接口,它對底層事務接口進行了封裝,底層事務接口包括:JDBC API、JTA(Java Transaction API)、CORBA(Common Object Requet Broker Architecture)APIHibernate應用可通過一致的Transaction接口來聲明
32、事務邊界,雖然應用也可以繞過Transaction接口,直接訪問底層的事務接口,但這種方法不值得推薦,因為它不利于應用在不同的環(huán)境移植。使用hibernate進行增刪改操作時,必須顯式的調用Transaction。 Transaction接口的事務對象通過Session對象開啟,其開啟方式如下面代碼所示。 在Transaction接口常用事務管理方法如下。commit()方法:提交事務。rollback()方法:撤銷事務操作。wasCommitted()方法:事務是否提交。Session進行數(shù)據(jù)庫的增刪改操作后,還要使用Transaction接口的commit()方法進行事務提交才能真正地將對
33、象數(shù)據(jù)同步到數(shù)據(jù)庫中。如果事務執(zhí)行過程中發(fā)生異常,就需要使用rollback()方法進行事務回滾,以避免數(shù)據(jù)不一致。1.8上機練習 題目:在MySQL數(shù)據(jù)中創(chuàng)建productdb數(shù)據(jù)庫,創(chuàng)建如表1.6所示的商品數(shù)據(jù)表goods,請在eclipse中創(chuàng)建一個hibernate項目。注意要使用工具類HibernateUtils。1.查詢出id為4的商品。2.添加一個新的商品。3.修改一條數(shù)據(jù)。4.刪除一條數(shù)據(jù)。第二章 HQL與Criteria查詢 掌握HQL查詢基本語法 學會在HQL中使用參數(shù)熟練掌握HQL的各種復雜查詢 了解criteria查詢40本章指引2.1 HQL查詢概述2.2 Crite
34、ria查詢2.3 上機實驗412.1 HQL 查詢概述42Hibernate查詢語言(Hibernate Query Language)簡稱HQL,是一種面向對象的查詢語句,形式上跟SQL很相似,但注意它查詢不是數(shù)據(jù)庫表,而是類(對象),查詢的結果通常是對象或對象的集合,而傳統(tǒng)的SQL查詢結果則是結構化的關系模型。2.1.1 HQL基本語法1.from子句用于查詢指定的對象集合。如:指的是查詢所有學生對象,也可用右述形式能更好地理解:上述對象用了全路徑類名,能一眼看出這是個類,而不會誤認為是數(shù)據(jù)庫表,注意HQL語句本身不區(qū)分大小寫,但相關的java包,類,屬性要區(qū)分大小寫。from Stude
35、nt這個查詢語句中student省略了包名是允許的,但Student寫成student就不行。2.Select子句通常用來選取查詢目標對象的部分屬性,如:表示查詢學生對象的姓名,年齡兩個屬性的值2.1 HQL 查詢概述433.where子句用于限定查詢條件,跟SQL類似,但where子句中用到的是對象的屬性而不是列名,注意區(qū)別,雖然很多時候屬性名跟列名同名,如:4.order by子句用于排序,升序用asc,降序用desc,默認升序,其用法與SQL一樣。5.使用表達式表達式相當于SQL中的各種函數(shù)。一般在where子句中使用表達式,例如查詢學生的姓名的大寫字母是TOM的學生:查詢出生年份是20
36、01年的學生:2.1 HQL 查詢概述442.1.2 HQL語句的執(zhí)行HQL語句的執(zhí)行流程是:首先構建HQL語句,然后創(chuàng)建Query對象,最后使用Query對象的list()方法、iterate()方法,或者uniqueResult()方法執(zhí)行查詢,獲取執(zhí)行結果(返回值)。1.使用Query對象的list()方法執(zhí)行查詢并返回值項目案例:查詢所有學生的信息并將查詢結果輸出到控制臺。(源碼請見本書配套資源:第2章/ssh02)(1)將上一章的項目復制為ssh02,創(chuàng)建測試類HQLTest,添加下面的方法:(2)運行結果如右 可見list方法可以執(zhí)行HQL語句并且返回List泛型集合。2.1 HQ
37、L 查詢概述453使用uniqueResult()方法執(zhí)行查詢返回唯一的一個對象項目案例:查詢姓名為李白的學生。(源碼請見本書配套資源:第2章/ssh02)在HQLTest類中添加以下方法。測試運行,控制臺只顯示一個學生的信息。注意這種情況下只能使用返回單個對象的HQL語句,否則會報錯。2使用Query對象的iterator()方法執(zhí)行HQL語句項目案例:查詢所有學生。(源碼請參見本書配套資源:第2章/hibernate02)在HQLTest類中添加一個方法。2.1 HQL 查詢概述463使用uniqueResult()方法執(zhí)行查詢返回唯一的一個對象項目案例:查詢姓名為李白的學生。(源碼請見本
38、書配套資源:第2章/ssh02)在HQLTest類中添加以下方法。測試運行,控制臺只顯示一個學生的信息。注意這種情況下只能使用返回單個對象的HQL語句,否則會報錯。2使用Query對象的iterator()方法執(zhí)行HQL語句項目案例:查詢所有學生。(源碼請參見本書配套資源:第2章/hibernate02)在HQLTest類中添加一個方法。2.1 HQL 查詢概述472.1.3 HQL查詢條件中使用參數(shù)1使用占位符“?”綁定參數(shù)HQL查詢條件往往需要用到外部傳入的值進行查詢,可用參數(shù)的形式接收這些外部傳入的值。在HQL語句中可以使用一個或多個“?”占位符的方式來綁定參數(shù)?!?”占位符表示此處對應
39、為一個輸入?yún)?shù),然后在執(zhí)行HQL語句之前要給這些參數(shù)賦值,使用Query對象的setXxx(參數(shù)索引,參數(shù)值)方法進行賦值,其中XXX表示參數(shù)的數(shù)據(jù)類型,與屬性的java類型一致,常見的setXxx()方法如表2.1所示。setXxx(參數(shù)索引,參數(shù)值)方法里面的第一個參數(shù)表示HQL語句中的第幾個“?”占位符,從0算起,第二個參數(shù)表示給該“?”占位符賦值。2.1 HQL 查詢概述48項目案例:查詢年齡為XX歲性別為XX的學生。(源碼請見本書配套資源:第2章/ssh02)在HQLTest類中添加以下方法:上述代碼中,query.setInteger(0, 18);表示給第一個“?”占位符賦值18
40、,值的類型的是整型,query.setString(1, 男);的意思是給第二個“?”占位符賦值“男”,這樣原始的HQL語句from Student where age=? and gender=?,將會被構建成from Student where age=18 and gender=男這樣的包含實際值的HQL語句再來執(zhí)行。2.1 HQL 查詢概述492.使用參數(shù)名稱進行綁定使用多個“?”占位符有個不方便的地方就是分別賦值時要想一想算一算是第幾個占位符,不小心就會弄錯。改用參數(shù)名稱綁定進行賦值就不會有這個問題。HQL語句中參數(shù)名稱前用“:”號來標明。賦值時使用setXxx(參數(shù)名稱,參數(shù)值)方
41、法。參數(shù)名稱的使用規(guī)則:在HQL語句中用“: ”號加參數(shù)名稱一一代替之前的“?”占位符。項目案例:查詢年齡為XX歲的性別為XX的學生,使用參數(shù)名稱綁定實現(xiàn)。(源碼請見本書配套資源:第2章/ssh02)在HQLTest類中添加以下方法。這里的HQL語句中分別用“ :age”和“ :gender”代替之前的“?”占位符。setXxx賦值時用參數(shù)名稱代替之前的索引數(shù)字。結果同上。2.1 HQL 查詢概述502.1.4 HQL給參數(shù)賦值的其他方法1.使用setParameter()方法給參數(shù)賦值給HQL中的各個參數(shù)賦值時,需要一一判斷各個參數(shù)對應的數(shù)據(jù)類型,從而調用相應的setXxx方法進行賦值,比較
42、麻煩一點,而setParameter()方法則是通用型的,參數(shù)為任意數(shù)據(jù)類型均可使用,解決了選用哪個setXxx的煩惱。語法如下:setParameter(第幾個占位符或參數(shù)名稱,參數(shù)的值)項目案例:查詢年齡為XX性別為XX的學生。(源碼請見本書配套資源:第2章/ssh02)在HQLTest類中添加以下方法。上面代碼使用了setParameter()代替了setXxx,既適用于“?”占位符的情況(見上述findStudents3()代碼),也適用于使用參數(shù)名稱的情況。測試運行輸出結果同前。2.1 HQL 查詢概述512使用setProperties()方法獲取對象的屬性值給HQL中的命名參數(shù)賦
43、值該方法需要先實例化一個對象,并且給對象中的全部或部分屬性賦值,然后調用Query的setProperties(實例化對象)方法,該方法會自動提取實例化對象的各個屬性值賦給HQL中同名的對應命名參數(shù)。注意HQL中的命名參數(shù)的名稱要與對象屬性名稱一致。項目案例:查詢年齡為XX性別為XX的學生。在HQLTest類中添加以下方法(源碼請見本書配套資源:第2章/ssh02)。上述代碼中,HQL語句中的兩個命名參數(shù),通過setProperties方法,分別由封裝好的Student對象的對應名稱的屬性進行了賦值。2.1 HQL 查詢概述522.1.5 HQL模糊查詢與動態(tài)查詢動態(tài)查詢適用于查詢條件的個數(shù)不
44、確定的情況,比如大家上網(wǎng)購物,每個人搜索商品的搜索條件數(shù)量都不相同。使用上面學習的setProperties()方法使得動態(tài)查詢變得容易。首先實例化一個持久化類的對象,根據(jù)用戶輸入的條件數(shù)量給持久化類對象動態(tài)賦值(用戶輸入多少個條件就給持久化類的多少個屬性賦值),同時動態(tài)構建HQL語句,用戶每輸入一個條件就增加一句HQL 命名參數(shù)查詢條件。最后用setProperties()給參數(shù)賦值并執(zhí)行即可。項目案例:搜索學生的條件不確定,進行動態(tài)查詢。(源碼請見本書配套資源:第2章/ssh02)運行后,可以測試多種不同查詢條件的情況。上面查詢學生姓名時用到了模糊查詢,注意模糊查詢不要直接在HQL語句中使
45、用%符號,而是在setXXX方法中使用%號。動態(tài)查詢通過動態(tài)構建HQL語句同時動態(tài)給對象賦值,并恰當?shù)乩昧藄etProperies這個方法。2.1 HQL 查詢概述532.1.6 HQL投影查詢有時候并不需要查詢一個對象的所有信息(屬性),不需要返回完整的對象。只想查詢一部分信息(屬性),這時可用到HQL投影查詢。這時要用到上面提過的select子句。投影查詢執(zhí)行后的返回結果有三種情況。1.只查詢單個屬性查詢結果封裝為泛型集合項目案例:查詢所有學生的姓名。(源碼請見本書配套資源:第2章/ssh02)在HQLTest中添加方法findStudents7()方法如下。測試運行,可發(fā)現(xiàn)所有學生姓名
46、都查出來了。這里只查詢studentName屬性,由于它是String 類型,所有返回值采用List類型,類似地如果只查詢age屬性,則返回結果采用List類型。2.1 HQL 查詢概述542查詢多個屬性的情況這時返回結果要用List類型來接收。項目案例:查詢所有學生的姓名與年齡。(源碼請見本書配套資源:第2章/ssh02)在HQLTest中添加方法findStudents8()方法如下:2.1 HQL 查詢概述553將部分屬性封裝成對象首先要在類中添加一個構造方法,比如我要查詢學生姓名和年齡,就在Student類中新增一個帶studenName和Age兩個參數(shù)的構造方法,然后再按下述案例所示
47、的形式構造HQL語句。項目案例:查詢所有學生的姓名與年齡。(源碼請見本書配套資源:第2章/ssh02)(1)持久化類Student中添加一個構造方法(2)HQLTest類中添加方法findStudents9()2.1 HQL 查詢概述562.1.7 HQL分頁查詢分頁查詢主要用到了Query對象的setFirstResult方法和setMaxResult方法,它們的作用如下。setFirstResult:設置需要返回的第一條記錄的起始下標,下標從0算起,有點類似MySQL中l(wèi)imit后的第一個參數(shù)。setMaxResult:設置最大返回結果條數(shù)。有點類似MySQL中l(wèi)imit后的第二個參數(shù)。這
48、兩個方法要用在Query對象的list()方法之前。分頁查詢一般還需要確定兩個變量,一個是想查詢第幾頁,這里(本項目)暫用變量名pageNo來表示,另一個變量就是確定一頁顯示幾條記錄,這里暫用變量名pageSize來表示。確定好變量后用表達式(pageNo-1)*pageSize作為setFirstResult()方法的參數(shù),用pageSize作為setMaxResult()方法的參數(shù)。下面示例對學生信息進行分頁查詢。2.1 HQL 查詢概述572.1.8 HQL聚合函數(shù)在HQL語句中可以運用聚合函數(shù),與SQL一致。聚合函數(shù)有count(),sum(),avg(),max(),min()五種。
49、注意由于只返回單個數(shù)據(jù),所以用Query的uniqueResult()方法來執(zhí)行HQL語句,另外整型返回結果必須是Long類型。下面示例查詢學生的人數(shù),在HQLTest類中添加方法findStudents11(),代碼如下。(源碼請見本書配套資源:第2章/ssh02)2.1 HQL 查詢概述582.1.9 HQL分組查詢HQL使用group by子句進行分組查詢,與SQL一致。下面示例查詢男女生的人數(shù)。在HQLTest類中添加方法findStudents12(),代碼如下。(源碼請見本書配套資源:第2章/ssh02)運行測試結果如下:2.1 HQL 查詢概述592.1.10 使用別名HQL語句
50、中也可以使用別名,跟SQL一樣,HQL中也是使用關鍵字as指定別名, as關鍵字也可以省略。在HQLTest類中創(chuàng)建一個名為aliasTest()的方法,該方法使用HQL別名的方式查詢數(shù)據(jù),如下所示。(源碼請見本書配套資源:第2章/ssh02)在上述代碼中,s是Student類的別名,在where條件后,使用其別名查詢studentName=”李白”的對象。本章指引2.1 HQL查詢概述2.2 Criteria查詢2.3 上機實驗602.2 Criteria查詢61Criteria接口是一個面向對象的,可擴展的條件查詢HibernateAPI,它跟HQL查詢的不同之處在于它不需要考慮數(shù)據(jù)庫底層
51、實現(xiàn),以及HQL語句如何編寫就能輕松實現(xiàn)各種查詢。Criteria實例化對象通過下列代碼實現(xiàn)??梢姡珻riteria對象仍然是由session創(chuàng)建的。2.2.1 Criteria簡單查詢創(chuàng)建好Criteria對象后,再利用Criterion對象設定查詢條件,然后使用Criteria對象的add方法添加查詢條件,最后使用list()方法或uniqueResult()執(zhí)行查詢即可實現(xiàn)簡單查詢。設定Criterion查詢條件的和添加查詢條件如下代碼所示。上面提到的Criterion是Hibernate的一個面向對象查詢條件接口,Criterion對象的通過Restrictions類來創(chuàng)建。在Rest
52、rictions類中提供了大量的靜態(tài)方法來創(chuàng)建查詢條件,其常用的方法如表2.2所示。2.2 Criteria查詢622.2 Criteria查詢63項目案例:使用Criteria查詢姓名為李白的學生。(源碼請見本書配套資源:第2章/ssh02)在項目ssh02的com.seehope.test包中新建一個名稱為CriteriaTest的類,在類中添加一個CriteriaTest1()方法,代碼如下所示。使用JUnit4測試運行,控制臺的顯示結果如圖2.1所示。2.2 Criteria查詢642.2.2 Criteria多條件查詢結合表2.2及下面案例學習多條件查詢。項目案例:查詢id=2或者s
53、tudentName=李白的學生。在類Criteriatest中建立一個名稱為criteriaTest2 ()的方法,如下所示。(源碼請見本書配套資源:第2章/ssh02)2.2 Criteria查詢652.2.2 Criteria多條件查詢結合表2.2及下面案例學習多條件查詢。項目案例:查詢id=2或者studentName=李白的學生。在類Criteriatest中建立一個名稱為criteriaTest2 ()的方法,如下所示。(源碼請見本書配套資源:第2章/ssh02)上述代碼Restrictions.or方法就相當于SQL中的or關系,Restrictions.eq方法就相當于SQL中
54、的等于。測試運行,控制臺的輸出結果如圖2.2所示。2.2 Criteria查詢662.2.3 Criteria分頁查詢Criteria同樣可以實現(xiàn)分頁查詢,它通過Citeria對象的setFirstResult(int firstResult)和setMaxResult(intmaxResult)這兩個方法共同來實現(xiàn)。其中setFirstResult(int firstResult)方法用于指定從哪個對象開始檢索,序號從0算起,setMaxResult(int maxResult)方法用于指定一次最多檢索的對象數(shù),即每頁顯示幾條記錄。在測試類CriteriaTest中編寫criteriaTes
55、t3()方法,代碼如下所示。(源碼請見本書配套資源:第2章/ssh02)上述查詢的是第1頁,每頁顯示3條,假定頁碼用pageno變量,每頁大小用pageSize變量,則通用查詢代碼是:2.2 Criteria查詢67使用JUnit4測試運行criteriaTest3()方法后,控制臺的輸出結果如圖2.3所示。上機練習題目:在上一章的商品數(shù)據(jù)庫基礎上實現(xiàn):1.查詢所有商品信息。2.查詢商品名稱包含“電”字的商品信息。3.查詢所有商品的名稱與價格。4.查詢商品的總數(shù)量。思考題1條件查詢中給參數(shù)賦值的方法有哪些?2說說HQL查詢與Criteria查詢的區(qū)別。2.3上機練習 題目:在上一章的商品數(shù)據(jù)庫
56、基礎上實現(xiàn):1.查詢所有商品信息。2.查詢商品名稱包含“電”字的商品信息。3.查詢所有商品的名稱與價格。4.查詢商品的總數(shù)量。第3章 Hibernate關聯(lián)映射掌握單向關聯(lián)與雙向關聯(lián)的概念掌握一對多關聯(lián)關系的使用掌握多對多關聯(lián)關系的使用掌握關聯(lián)關系中的反轉和級聯(lián)掌握延遲加載69本章指引3.1 實體對象的三種關聯(lián)關系3.2 關聯(lián)關系中的反轉與級聯(lián)3.3 延遲加載3.4 上機實驗703.1 實體對象的三種關聯(lián)關系數(shù)據(jù)庫中表與表之間的關系有下列三種,數(shù)據(jù)庫表之間的關系是通過外鍵來實現(xiàn)的: 一對多:班級與學生,一個班級對應多個學生。需要在多方,添加一方的主鍵作為外鍵。 多對多:例如教師與學生的關系,一
57、個教師可教多個學生,一個學生可被多個教師教。需要一張中間表,添加兩張表的主鍵作外鍵。 一對一:比如人與身份證的關系,一個人對應一個身份證。在其中一方添加另一方的主鍵作外鍵。Hibernate中數(shù)據(jù)庫對應的實體對象之間同樣有上述三種類型的關聯(lián)關系,設計持久化類時,需要在類中進行特別設置以體現(xiàn)它們之間的關聯(lián)關系,具體規(guī)則如下: 一對一:在其中一個類中定義對方類型的對象,如A類中定義B類類型的屬性b,B類中定義A類類型的屬性a。 一對多:假如是一個A類是一方,B類是多方,需要在A類以Set集合的方式引入B類型的對象,同時在B類中定義A類類型的屬性a。 多對多:在A類中定義B類類型的Set集合,在B類
58、中定義A類類型的Set集合,使用Set集合的是為了避免數(shù)據(jù)的重復(如果采用List集合則有可能有重復)。實體對象之間的三種關聯(lián)關系,除了在類中進行上述設置外,還要在映射文件中配置,具體看下面案例。注:一對一關聯(lián)關系的操作同一對多關聯(lián)關系,在此不單獨介紹。713.1 實體對象的三種關聯(lián)關系數(shù)據(jù)庫中表與表之間的關系有下列三種,數(shù)據(jù)庫表之間的關系是通過外鍵來實現(xiàn)的: 一對多:班級與學生,一個班級對應多個學生。需要在多方,添加一方的主鍵作為外鍵。 多對多:例如教師與學生的關系,一個教師可教多個學生,一個學生可被多個教師教。需要一張中間表,添加兩張表的主鍵作外鍵。 一對一:比如人與身份證的關系,一個人對
59、應一個身份證。在其中一方添加另一方的主鍵作外鍵。Hibernate中數(shù)據(jù)庫對應的實體對象之間同樣有上述三種類型的關聯(lián)關系,設計持久化類時,需要在類中進行特別設置以體現(xiàn)它們之間的關聯(lián)關系,具體規(guī)則如下: 一對一:在其中一個類中定義對方類型的對象,如A類中定義B類類型的屬性b,B類中定義A類類型的屬性a。 一對多:假如是一個A類是一方,B類是多方,需要在A類以Set集合的方式引入B類型的對象,同時在B類中定義A類類型的屬性a。 多對多:在A類中定義B類類型的Set集合,在B類中定義A類類型的Set集合,使用Set集合的是為了避免數(shù)據(jù)的重復(如果采用List集合則有可能有重復)。實體對象之間的三種關
60、聯(lián)關系,除了在類中進行上述設置外,還要在映射文件中配置,具體看下面案例。注:一對一關聯(lián)關系的操作同一對多關聯(lián)關系,在此不單獨介紹。723.1 實體對象的三種關聯(lián)關系3.1.1 單向關聯(lián)與雙向關聯(lián)以一對多為例,一個班級對應多個學生,這是典型的一對多關系,假設班級Classes類是“一方”,學生Student類是“多方”,如果“一方”Classes類中定義了“多方”Student類型的Set集合屬性,并且“多方”Student類中也定義了“一方”Classes類型的屬性,這就是雙向關聯(lián)。如果Classes類中定義了Student類型的Set集合屬性,但Student類中卻沒有定義了Classes類
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 訂艙代理協(xié)議書范文
- 關于公司合作經(jīng)營協(xié)議書范文
- 企業(yè)形象識別系統(tǒng)建設設計合同
- 佛山市汽車購買合同
- 引進人才協(xié)議書
- 噴煤協(xié)理工程師安全職責(2篇)
- 2025年企業(yè)班組年終總結(2篇)
- 2025年小學二年級語文教學總結樣本(2篇)
- 成品油卸車作業(yè)安全管理規(guī)定模版(2篇)
- 2025年圖書館工會工作總結范文(2篇)
- 2024秋期國家開放大學??啤陡叩葦?shù)學基礎》一平臺在線形考(形考任務一至四)試題及答案
- 敞開式硬巖TBM掘進操作參數(shù)的控制 方志威
- (中職)《電子商務基礎》第1套試卷試題及答案
- 汽車三維建模虛擬仿真實驗
- 無人機智慧旅游解決方案
- 行車起重作業(yè)風險分析及管控措施
- 健康管理主題PPT模板-健康管理
- 山西事業(yè)單位專業(yè)技術職務聘任管理
- 110kV及以上電力電纜敷設施工方法要點
- 國家開放大學電大??啤缎谭▽W(1)》期末題庫及答案
- 消防安全承諾書[新].doc
評論
0/150
提交評論