版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、第4章 Hibernate應用,4.1 Hibernate概述,4.2 Hibernate應用基礎,4.3 Hibernate關系映射,4.4 Hibernate高級功能,4.5 Hibernate與Struts 2整合應用,4.1 Hibernate概述,1. ORM簡介 對象/關系映射ORM(Object-Relation Mapping)是用于將對象與對象之間的關系對應到數(shù)據(jù)庫表與表之間的關系的一種模式。簡單地說,ORM是通過使用描述對象和數(shù)據(jù)庫之間映射的元數(shù)據(jù),將Java程序中的對象自動持久化到關系數(shù)據(jù)庫中。對象和關系數(shù)據(jù)是業(yè)務實現(xiàn)的兩種表現(xiàn)形式,業(yè)務實體在內(nèi)存中表現(xiàn)為對象,在數(shù)據(jù)庫中
2、表現(xiàn)為關系數(shù)據(jù)。內(nèi)存中的對象之間存在著關聯(lián)和繼承關系。而在數(shù)據(jù)庫中,關系數(shù)據(jù)無法直接表達多對多關聯(lián)和繼承關系。因此,ORM系統(tǒng)一般以中間件的形式存在,主要實現(xiàn)程序?qū)ο蟮疥P系數(shù)據(jù)庫數(shù)據(jù)的映射。一般的ORM包括四個部分:對持久類對象進行CRUD操作的API、用來規(guī)定類和類屬性相關查詢的語言或API、規(guī)定mapping metadata的工具,以及可以讓ORM實現(xiàn)同事務對象一起進行dirty checking、lazy association fetching和其他優(yōu)化操作的技術。,4.1 Hibernate概述,2. Hibernate體系結(jié)構(gòu) Hibernate作為模型層/數(shù)據(jù)訪問層。它通過配置
3、文件(hibernate.cfg.xml或perties)和映射文件(*.hbm.xml)把Java對象或持久化對象(Persistent Object,PO)映射到數(shù)據(jù)庫中的數(shù)據(jù)表,然后通過操作PO,對數(shù)據(jù)庫中的表進行各種操作,其中PO就是POJO(普通Java對象)加映射文件。Hibernate的體系結(jié)構(gòu)如圖4.1所示。,圖4.1 Hibernate體系結(jié)構(gòu),4.2 Hibernate應用基礎,4.2.1 Hibernate應用實例開發(fā) 開發(fā)Hibernate項目的步驟如下。 1建立數(shù)據(jù)庫及表 本書使用SQL Server 2005數(shù)據(jù)庫。在XSCJ數(shù)據(jù)庫中建立K
4、CB表,其表結(jié)構(gòu)如附錄A.2所示。 2在MyEclipse中創(chuàng)建對SQL Server 的連接 啟動MyEclipse,選擇【W(wǎng)indow】【Open Perspective】【MyEclipse Database Explorer】菜單項,打開MyEclipse Database瀏覽器,右擊菜單,如圖4.2所示,選擇【New】菜單項,出現(xiàn)如圖4.3所示的對話框,編輯數(shù)據(jù)庫連接驅(qū)動。,4.2.1 Hibernate應用實例開發(fā),圖4.2 MyEclipse Database瀏覽器, 創(chuàng)建一個新的連接,圖4.3 編輯數(shù)據(jù)庫連接驅(qū)動,4.2.1 Hibernate應用實例開發(fā),編輯完成以后,在My
5、Eclipse Database瀏覽器中,右擊剛才創(chuàng)建的MyConn數(shù)據(jù)庫連接,選擇“Open connection”菜單項,打開名為“MyConn”的數(shù)據(jù)連接,如圖4.4所示。,圖4.4 打開數(shù)據(jù)庫連接,4.2.1 Hibernate應用實例開發(fā),3創(chuàng)建Web項目,命名為“HibernateTest” 4添加Hibernate開發(fā)能力 右擊項目名HibernateTest,選擇【MyEclipse】【Add Hibernate Capabilites】菜單項,出現(xiàn)如圖4.5所示的對話框,選擇Hibernate框架應用版本及所需要的類庫。,圖4.5 選擇Hibernate版本及所需Jar包,4
6、.2.1 Hibernate應用實例開發(fā),單擊【Next】按鈕,進入如圖4.6所示界面。創(chuàng)建Hibernate配置文件hibernate.cfg.xml,將該文件放在src文件夾下,后面會詳細介紹該文件內(nèi)容。這里先說明添加Hibernate開發(fā)功能的步驟。,圖4.6 創(chuàng)建配置文件hibernate.cfg.xml,4.2.1 Hibernate應用實例開發(fā),單擊【Next】按鈕,進入如圖4.7所示界面,指定Hibernate數(shù)據(jù)庫連接細節(jié)。由于在前面已經(jīng)配置一個名為MyConn的數(shù)據(jù)庫連接,所以這里只需要選擇DB Driver為“MyConn”即可。,圖4.7 指定hibernate數(shù)據(jù)庫連接
7、,4.2.1 Hibernate應用實例開發(fā),單擊【Next】按鈕,出現(xiàn)如圖4.8所示界面。Hibernate中有一個與數(shù)據(jù)庫打交道重要的類Session。而這個類是由工廠SessionFactory創(chuàng)建的。這個界面詢問是否需要創(chuàng)建SessionFactory類。如果需要創(chuàng)建,還需要指定創(chuàng)建的位置和類名。這些接口都會在后面詳細介紹。單擊【Finish】按鈕,完成Hibernate的配置。,圖4.8 創(chuàng)建SessionFactory類來簡化Hibernate會話處理,4.2.1 Hibernate應用實例開發(fā),5. 生成數(shù)據(jù)庫表對應的Java類對象和映射文件 首先在MyEclispse下創(chuàng)建一個
8、名為“org.model”的包,這個包將用來存放與數(shù)據(jù)庫表對應的Java類POJO。 從主菜單欄,選擇【W(wǎng)indows】【Open Perspective】【Other】【MyEclipse Database Explorer】菜單項,打開MyEclipse Database Explorer視圖。打開前面創(chuàng)建的MyConn數(shù)據(jù)連接,選擇【XSCJ】【dbo】【TABLE】菜單項,右擊KCB表,選擇【Hibernate Reverse Engineering】菜單項,如圖4.9所示,將啟動Hibernate Reverse Engineering向?qū)В撓驅(qū)в糜谕瓿蓮囊延械臄?shù)據(jù)庫表生成對應的J
9、ava類和相關映像文件的配置工作。,圖4.9 Hibernate反向工程菜單,4.2.1 Hibernate應用實例開發(fā),首先,選擇生成的Java類和映像文件所在的位置,如圖4.10所示。POJO(Plain Old Java Object,簡單的Java對象),通常也稱為VO(Value Object,值對象)。,圖4.10 生成Hibernate映射文件和Java類,4.2.1 Hibernate應用實例開發(fā),使用POJO名稱是為了避免和EJB混淆起來,其中有一些屬性及getter、setter方法。當然,如果有一個簡單的運算屬性也是可以的,但不允許有業(yè)務方法。單擊【Next】按鈕,進入如
10、圖4.11所示的界面,選擇主鍵生成策略。,圖4.11 配置反向工程細節(jié),4.2.1 Hibernate應用實例開發(fā),6. 創(chuàng)建測試類 在src文件夾下創(chuàng)建包test,在該包下建立測試類,命名為Test.java,其代碼。 7. 運行 因為該程序為Java Application,所以可以直接運行。運行程序,控制臺就會打印出“機電”。在完全沒有操作數(shù)據(jù)庫的情況下,就完成了對數(shù)據(jù)的插入。下面將詳細講解各文件的作用。,4.2.2 Hibernate各種文件的作用,1. POJO類和其映射配置文件 POJO類如下: package org.model; public class Kcb impleme
11、nts java.io.Serializable private String kch; / 對應表中KCH字段 private String kcm; / 對應表中KCM字段 private Short kxxq; / 對應表中KXXQ字段 private Integer xs; / 對應表中XS字段 private Integer xf; / 對應表中XF字段 public Kcb() / 上述屬性的getter和setter方法 可以發(fā)現(xiàn),該類中的屬性和表中的字段是一一對應的。那么通過什么方法把它們一一映射起來呢?就是前面提到的*.hbm.xml映射文件。這里當然就是Kcb.hbm.xm
12、l,其代碼。,4.2.2 Hibernate各種文件的作用,該配置文件大致分為3個部分: (1)類、表映射配置 name屬性指定POJO類為org.model.Kcb,table屬性指定當前類對應數(shù)據(jù)庫表KCB。 (2)id映射配置 Hibernate的主鍵生成策略分為三大類:Hibernate對主鍵id賦值、應用程序自身對id賦值、由數(shù)據(jù)庫對id賦值。 assigned:應用程序自身對id賦值。當設置時,應用程序自身需要負責主鍵id的賦值。例如下述代碼: Kcb kc=new Kcb(); / 創(chuàng)建POJO類對象 kc.setKch(198); / 設置課程號 kc.setKcm(機電);
13、/ 設置課程名 kc.setKxxq(new Integer(5).shortValue(); / 設置開學學期 kc.setXf(new Integer(4).shortValue(); / 設置學分 kc.setXs(new Integer(59).shortValue(); / 設置學時,4.2.2 Hibernate各種文件的作用,native:由數(shù)據(jù)庫對id賦值。當設置時,數(shù)據(jù)庫負責主鍵id的賦值,最常見的是int型的自增型主鍵。 hilo:通過hi/lo算法實現(xiàn)的主鍵生成機制,需要額外的數(shù)據(jù)庫表保存主鍵生成歷史狀態(tài)。 seqhilo:與hi/lo類似,通過hi/lo算法實現(xiàn)的主鍵生
14、成機制,只是主鍵歷史狀態(tài)保存在sequence中,適用于支持sequence的數(shù)據(jù)庫,如Oracle。 increment:主鍵按數(shù)值順序遞增。此方式的實現(xiàn)機制為在當前應用實例中維持一個變量,以保存當前的最大值,之后每次需要生成主鍵的時候?qū)⒋酥导?作為主鍵。 identity:采用數(shù)據(jù)庫提供的主鍵生成機制,如SQL Server、MySQL中的自增主鍵生成機制。 sequence:采用數(shù)據(jù)庫提供的sequence機制生成主鍵,如Oracle sequence。 uuid.hex:由Hibernate基于128位唯一值產(chǎn)生算法,根據(jù)當前設備IP、時間、JVM啟動時間、內(nèi)部自增量等4個參數(shù)生成十六
15、進制數(shù)值(編碼后長度為32位的字符串表示)作為主鍵。即使是在多實例并發(fā)運行的情況下,這種算法在最大程度上保證了產(chǎn)生id的唯一性。當然,重復的概率在理論上依然存在,只是概率比較小。 uuid.string:與uuid.hex類似,只是對生成的主鍵進行編碼(長度16位)。 foreign:使用外部表的字段作為主鍵。 select:Hibernate 3新引入的主鍵生成機制,主要針對遺留系統(tǒng)的改造工程。,4.2.2 Hibernate各種文件的作用,(3)屬性、字段映射配置 屬性、字段映射將映射類屬性與庫表字段相關聯(lián)。 name=kcm 指定映像類中的屬性名為“kcm”,此屬性將被映像到指定的庫表字
16、段KCM。type=java.lang.String指定映像字段的數(shù)據(jù)類型。column name=KCM指定類的kcm屬性映射KCB表中的KCM字段。,4.2.2 Hibernate各種文件的作用,2. hibernate.cfg.xml文件 該文件是Hibernate重要的配置文件,配置該文件主要是配置SessionFractory類。其主要代碼及解釋。 3. HibernateSessionFactory HibernateSessionFactory類是自定義的SessionFactory,名字可以根據(jù)自己的喜好來決定。這里用的是HibernateSessionFactory,其內(nèi)容及
17、解釋。 在Hibernate中,Session負責完成對象持久化操作。該文件負責創(chuàng)建Session對象,以及關閉Session對象。從該文件可以看出,Session對象的創(chuàng)建大致需要以下3個步驟: 初始化Hibernate配置管理類Configuration。 通過Configuration類實例創(chuàng)建Session的工廠類SessionFactory。 通過SessionFactory得到Session實例。,4.2.3 Hibernate核心接口,1. Configuration接口 Configuration負責管理Hibernate的配置信息。Hibernate運行時需要一些底層實現(xiàn)的基
18、本信息。這些信息包括:數(shù)據(jù)庫URL、數(shù)據(jù)庫用戶名、數(shù)據(jù)庫用戶密碼、數(shù)據(jù)庫JDBC驅(qū)動類、數(shù)據(jù)庫dialect。用于對特定數(shù)據(jù)庫提供支持,其中包含了針對特定數(shù)據(jù)庫特性的實現(xiàn),如Hibernate數(shù)據(jù)庫類型到特定數(shù)據(jù)庫數(shù)據(jù)類型的映射等。 使用Hibernate必須首先提供這些基礎信息以完成初始化工作,為后續(xù)操作做好準備。這些屬性在Hibernate配置文件hibernate.cfg.xml中加以設定,當調(diào)用: Configuration config=new Configuration().configure(); 時,Hibernate會自動在目錄下搜索hibernate.cfg.xml文件,并
19、將其讀取到內(nèi)存中作為后續(xù)操作的基礎配置。,4.2.3 Hibernate核心接口,2. SessionFactory接口 SessionFactory負責創(chuàng)建Session實例,可以通過Configuration實例構(gòu)建SessionFactory。 Configuration config=new Configuration().configure(); SessionFactory sessionFactory=config.buildSessionFactory(); Configuration實例config會根據(jù)當前的數(shù)據(jù)庫配置信息,構(gòu)造SessionFacory實例并返回。Sess
20、ionFactory一旦構(gòu)造完畢,即被賦予特定的配置信息。也就是說,之后config的任何變更將不會影響到已經(jīng)創(chuàng)建的SessionFactory實例sessionFactory。如果需要使用基于變更后的config實例的SessionFactory,需要從config重新構(gòu)建一個SessionFactory實例。 SessionFactory保存了對應當前數(shù)據(jù)庫配置的所有映射關系,同時也負責維護當前的二級數(shù)據(jù)緩存和Statement Pool。由此可見,SessionFactory的創(chuàng)建過程非常復雜、代價高昂。這也意味著,在系統(tǒng)設計中充分考慮到SessionFactory的重用策略。由于Ses
21、sionFactory采用了線程安全的設計,可由多個線程并發(fā)調(diào)用。,4.2.3 Hibernate核心接口,3. Session接口 Session是Hibernate持久化操作的基礎,提供了眾多持久化方法,如save、update、delete等。通過這些方法,透明地完成對象的增加、刪除、修改、查找等操作。 同時,值得注意的是,Hibernate Session的設計是非線程安全的,即一個Session實例同時只可由一個線程使用。同一個Session實例的多線程并發(fā)調(diào)用將導致難以預知的錯誤。 Session實例由SessionFactory構(gòu)建: Configuration config=n
22、ew Configuration().configure(); SessionFactory sessionFactory=config.buldSessionFactory(); Session session=sessionFactory.openSession(); 4. Transaction接口 Transaction是Hibernate中進行事務操作的接口,Transaction 接口是對實際事務實現(xiàn)的一個抽象,這些實現(xiàn)包括JDBC的事務、JTA 中的UserTransaction,甚至可以是CORBA 事務。之所以這樣設計是可以讓開發(fā)者能夠使用一個統(tǒng)一的操作界面,使得自己的項目可
23、以在不同的環(huán)境和容器之間方便地移值。事務對象通過Session創(chuàng)建。例如以下語句: Transaction ts=session.beginTransaction();,4.2.3 Hibernate核心接口,5. Query接口 在Hibernate 2.x中,find()方法用于執(zhí)行HQL語句。Hibernate 3.x廢除了find()方法,取而代之的是Query接口,它們都用于執(zhí)行HQL語句。Query和HQL是分不開的。 Query query=session.createQuery(“from Kcb where kch=198”); 例如以下語句: Query query=ses
24、sion.createQuery(from Kcb where kch=?); 就要在后面設置其值: Query.setString(0, 要設置的值); 上面的方法是通過“?”來設置參數(shù),還可以用“:”后跟變量的方法來設置參數(shù),如上例可以改為: Query query=session.createQuery(from Kcb where kch=:kchValue); Query.setString(kchValue,要設置的課程號值); 其使用方法是相同的,例如: Query.setParameter(0, 要設置的值); Query還有一個list()方法,用于取得一個List集合的示例
25、,此示例中包括可能是一個Object集合,也可能是Object數(shù)組集合。例如: Query query=session.createQuery(from Kcb where kch=198); List list=query.list();,4.2.4 HQL查詢,下面介紹HQL的幾種常用的查詢方式。 1. 基本查詢 基本查詢是HQL中最簡單的一種查詢方式。下面以課程信息為例說明其幾種查詢情況。 (1)查詢所有課程信息 Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransa
26、ction(); Query query=session.createQuery(from Kcb); List list=query.list(); mit(); HibernateSessionFactory.closeSession(); ,4.2.4 HQL查詢,(2)查詢某門課程信息 . Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); / 查詢一門學時最長的課程 Query query=session.createQuery(from Kc
27、b order by xs desc); query.setMaxResults(1);/ 設置最大檢索數(shù)目為1 / 裝載單個對象 Kcb kc=(Kcb)query.uniqueResult(); mit(); HibernateSessionFactory.closeSession(); .,4.2.4 HQL查詢,(3)查詢滿足條件的課程信息 . Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); / 查詢課程號為001的課程信息 Query qu
28、ery=session.createQuery(from Kcb where kch=001); List list=query.list(); mit(); HibernateSessionFactory.closeSession(); .,4.2.4 HQL查詢,2. 條件查詢 查詢的條件有幾種情況,下面舉例說明。 (1)按指定參數(shù)查詢 . Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); / 查詢課程名為計算機基礎的課程信息 Query quer
29、y=session.createQuery(from Kcb where kcm=?); query.setParameter(0, 計算機基礎); List list=query.list(); mit(); HibernateSessionFactory.closeSession(); .,4.2.4 HQL查詢,(2)使用范圍運算查詢 . Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); / 查詢這樣的課程信息,課程名為計算機基礎或數(shù)據(jù)結(jié)構(gòu),且學
30、時在4060之間 Query query=session.createQuery(from Kcb where (xs between 40 and 60) and kcm in(計算機基礎,數(shù)據(jù)結(jié)構(gòu)); List list=query.list(); mit(); HibernateSessionFactory.closeSession(); .,4.2.4 HQL查詢,(3)使用比較運算符查詢 . Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction();
31、/ 查詢學時大于51且課程名不為空的課程信息 Query query=session.createQuery(from Kcb where xs51 and kcm is not null); List list=query.list(); mit(); HibernateSessionFactory.closeSession(); .,4.2.4 HQL查詢,(4)使用字符串匹配運算查詢 . Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); / 查詢
32、課程號中包含“001”字符串且課程名前面三個字為計算機的所有課程信息 Query query=session.createQuery(from Kcb where kch like %001% and kcm like 計算機%); List list=query.list(); mit(); HibernateSessionFactory.closeSession(); .,4.2.4 HQL查詢,3. 分頁查詢 為了滿足分頁查詢的需要,Hibernate的Query實例提供了兩個有用的方法:setFirstResult(int firstResult)和setMaxResults(int
33、maxResult)。其中setFirstResult(int firstResult)方法用于指定從哪一個對象開始查詢(序號從0開始),默認為第1個對象,也就是序號0。SetMaxResults(int maxResult)方法用于指定一次最多查詢出的對象的數(shù)目,默認為所有對象。如下面的代碼片段: . Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); Query query=session.createQuery(from Kcb); int pag
34、eNow=1;/ 想要顯示第幾頁 int pageSize=5;/ 每頁顯示的條數(shù) query.setFirstResult(pageNow-1)*pageSize);/ 指定從哪一個對象開始查詢 query.setMaxResults(pageSize);/ 指定最大的對象數(shù)目 List list=query.list(); mit(); HibernateSessionFactory.closeSession(); .,4.3 Hibernate關系映射,4.3.1 一對一關聯(lián) 1. 共享主鍵方式 在注冊某個論壇會員的時候,往往不但要填寫登錄賬號和密碼,還要填寫其他的詳細信息,這兩部分信息
35、通常會放在不同的表中,如表4.1、表4.2所示。,表4.1 登錄表Login,表4.2 詳細信息表Detail,4.3.1 一對一關聯(lián),登錄表和詳細信息表屬于典型的一對一關聯(lián)關系,可按共享主鍵方式進行。步驟如下: 創(chuàng)建Java項目,命名為“Hibernate_mapping”。 添加Hibernate開發(fā)能力,步驟同4.2.1節(jié)第4步。HibernateSessionFactory類同樣位于org.util包下。 編寫生成數(shù)據(jù)庫表對應的Java類對象和映射文件。 Login表對應的POJO類Login.java: package org.model; public class Login im
36、plements java.io.Serializable private int id; / ID號 private String username; / 登錄賬號 private String password; / 密碼 private Detail detail; / 詳細信息 / 省略上述各屬性的getter和setter方法 ,4.3.1 一對一關聯(lián),Detail表對應的Detail.java: package org.model; public class Detail implements java.io.Serializable private int id; / ID號 p
37、rivate String trueName; / 真實姓名 private String email; / 電子郵件 private Login login; / 登錄信息 / 省略上述各屬性的getter和setter方法 Login表與Login類的ORM映射文件Login.hbm.xml。 Detail表與Detail類的ORM映射文件Detail.hbm.xml:,4.3.1 一對一關聯(lián), 在hibernate.cfg.xml文件中加入配置映射文件的語句。 創(chuàng)建測試類。 在src文件夾下創(chuàng)建包test,在該包下建立測試類,命名為“Test.java”。其代碼。 運行程序,測試結(jié)果。
38、因為該程序為Java Application,所以可以直接運行。在完全沒有操作數(shù)據(jù)庫的情況下,程序就完成了對數(shù)據(jù)的插入。插入數(shù)據(jù)后,Login表和Detail表的內(nèi)容如圖4.12、圖4.13所示。,圖4.12 Login表 圖4.13 Detail表,4.3.1 一對一關聯(lián),2. 唯一外鍵方式 唯一外鍵的情況很多,例如,每個人對應一個房間。其實在很多情況下,可以是幾個人住在同一個房間里面,就是多對一的關系。但是如果把這個多變成唯一,也就是說讓一個人住一個房間,就變成了一對一的關系了,這就是前面說的一對一的關系其實是多對一關聯(lián)關系的一種特殊情況。對應的Person表和Room表如表4.3、表4.
39、4所示。,表4.3 Person表,表4.4 Room表,4.3.1 一對一關聯(lián),步驟如下: 在項目Hibernate_mapping的org.model包下編寫生成數(shù)據(jù)庫表對應的Java類對象和映射文件。 Person表對應的POJO類Person.java: package org.model; public class Person implements java.io.Serializable private Integer id; private String name; private Room room; / 省略上述各屬性的getter和setter方法 Room表對應的POJ
40、O類Room.java: package org.model; public class Room implements java.io.Serializable private int id; private String address; private Person person; / 省略上述各屬性的getter和setter方法 ,4.3.1 一對一關聯(lián),Person表與Person類的ORM映射文件Person.hbm.xml: / 唯一性約束,實現(xiàn)一對一 ,4.3.1 一對一關聯(lián),Room表與Room類的ORM映射文件Room.hbm.xml: / 指定關聯(lián)類的屬性名 ,4.3.
41、1 一對一關聯(lián), 在hibernate.cfg.xml文件中加入如下的配置映射文件的語句。 編寫測試代碼。 在src文件夾下的包test的Test類中加入如下代碼: Person person=new Person(); person.setName(liumin); Room room=new Room(); room.setAddress(NJ-S1-328); person.setRoom(room); session.save(person); ,4.3.1 一對一關聯(lián), 運行程序,測試結(jié)果。 因為該程序為Java Application,所以可以直接運行。在完全沒有操作數(shù)據(jù)庫的情況下
42、,程序就完成了對數(shù)據(jù)的插入。插入數(shù)據(jù)后,Person表和Room表的內(nèi)容如圖4.14、圖4.15所示。,圖4.14 Person表 圖4.15 Room表,4.3.2 多對一單向關聯(lián),只要把上例中的一對一的唯一外鍵關聯(lián)實例稍微修改就可以變成多對一。步驟如下: 在項目Hibernate_mapping的org.model包下編寫生成數(shù)據(jù)庫表對應的Java類對象和映射文件。 其對應表不變,Person表對應的類也不變,對應的Person.hbm.xml文件修改如下: / 主控類所有操作,對關聯(lián)類也執(zhí)行同樣操作 ,4.3.2 多對一單向關聯(lián),而Room表不變,對應的POJO類如下: package
43、org.model; public class Room implements java.io.Serializable private int id; private String address; / 省略上述各屬性的getter和setter方法 Room表與Room類的ORM映射文件Room.hbm.xml如下: ,4.3.2 多對一單向關聯(lián), 編寫測試代碼。 在src文件夾下的包test的Test類中加入如下代碼: Room room=new Room(); room.setAddress(NJ-S1-328); Person person=new Person(); person.
44、setName(liuyanmin); person.setRoom(room); session.save(person); ,4.3.2 多對一單向關聯(lián), 運行程序,測試結(jié)果。 因為該程序為Java Application,所以可以直接運行。在完全沒有操作數(shù)據(jù)庫的情況下,程序就完成了對數(shù)據(jù)的插入。插入數(shù)據(jù)后,Person表和Room表的內(nèi)容如圖4.16、圖4.17所示。,圖4.16 Person表 圖4.17 Room表,4.3.3 一對多雙向關聯(lián),下面通過修改4.3.2節(jié)的例子來完成雙向多對一的實現(xiàn)。步驟如下: 在項目Hibernate_mapping的org.model包下編寫生成數(shù)據(jù)
45、庫表對應的Java類對象和映射文件。 Person表對應的POJO及其映射文件不用改變,現(xiàn)在來修改Room表對應的POJO類及其映射文件。對應的POJO類Room.java。 Room表與Room類的ORM映射文件Room.hbm.xml。 該配置文件中cascade配置的是級聯(lián)程度,它有以下幾種取值: all:表示所有操作句在關聯(lián)層級上進行連鎖操作。 save-update:表示只有save和update操作進行連鎖操作。 delete:表示只有delete操作進行連鎖操作。 all-delete-orphan:在刪除當前持久化對象時,它相當于delete;在保存或更新當前持久化對象時,它相
46、當于save-update。另外它還可以刪除與當前持久化對象斷開關聯(lián)關系的其他持久化對象。,4.3.3 一對多雙向關聯(lián), 編寫測試代碼。 在src文件夾下的包test的Test類中加入如下代碼: Person person1=new Person(); Person person2=new Person(); Room room=new Room(); room.setAddress(NJ-S1-328); person1.setName(李方方); person2.setName(王艷); person1.setRoom(room); person2.setRoom(room); /這樣完成
47、后就可以通過Session對象 /調(diào)用session.save(person1)和session.save(person) /會自動保存room session.save(person1); session.save(person2); ,4.3.3 一對多雙向關聯(lián), 運行程序,測試結(jié)果。 因為該程序為Java Application,所以可以直接運行。在完全沒有操作數(shù)據(jù)庫的情況下,程序就完成了對數(shù)據(jù)的插入。插入數(shù)據(jù)后,Person表和Room表的內(nèi)容如圖4.18、圖4.19所示。,圖4.18 Person表 圖4.19 Room表,4.3.3 一對多雙向關聯(lián),由于是雙向的,當然也可以從Roo
48、m的一方來保存Person,在Test.java中加入如下代碼: . Person person1=new Person(); Person person2=new Person(); Room room=new Room(); person1.setName(李方方); person2.setName(王艷); Set persons=new HashSet(); persons.add(person1); persons.add(person2); room.setAddress(NJ-S1-328); room.setPerson(persons); /這樣完成后,就可以通過Sessio
49、n對象 /調(diào)用session.save(room) /會自動保存person1和person2 .,4.3.3 一對多雙向關聯(lián),運行程序,插入數(shù)據(jù)后,Person表和Room表的內(nèi)容如圖4.20、圖4.21所示。,圖4.20 Person表 圖4.21 Room表,4.3.4 多對多關聯(lián),1. 多對多單向關聯(lián) 學生和課程就是多對多的關系,一個學生可以選擇多門課程,而一門課程又可以被多個學生選擇。多對多關系在關系數(shù)據(jù)庫中不能直接實現(xiàn),還必須依賴一張連接表。如表4.6、表4.7和表4.8所示。,表4.6 學生表student,表4.7 課程表course,表4.8 連接表stu_cour,4.3.
50、4 多對多關聯(lián),由于是單向的,也就是說從一方可以知道另一方,反之不行。這里以從學生知道選擇了哪些課程為例實現(xiàn)多對多單向關聯(lián)。步驟如下: 在項目Hibernate_mapping的org.model包下編寫生成數(shù)據(jù)庫表對應的Java類對象和映射文件。 student表對應的POJO類如下: package org.model; import java.util.HashSet; import java.util.Set; public class Student implements java.io.Serializable private int id; private String snum
51、ber; private String sname; private int sage; private Set courses=new HashSet(); /省略上述各屬性的getter和setter方法 student表與Student類的ORM映射文件Student.hbm.xml。,4.3.4 多對多關聯(lián),course表對應的POJO如下: package org.model; public class Course implements java.io.Serializable private int id; private String cnumber; private Stri
52、ng cname; /省略上述各屬性的getter和setter方法。 course表與Course類的ORM映射文件Course.hbm.xml。 在hibernate.cfg.xml文件中加入如下的配置映射文件的語句。 編寫測試代碼。 在src文件夾下的包test的Test類中加入如下代碼。,4.3.4 多對多關聯(lián), 運行程序,測試結(jié)果。 因為該程序為Java Application,所以可以直接運行。在完全沒有操作數(shù)據(jù)庫的情況下,程序就完成了對數(shù)據(jù)的插入。插入數(shù)據(jù)后,student表、course表及連接表stu_cour表的內(nèi)容如圖4.22、圖4.23、圖4.24所示。,圖4.22 s
53、tudent表,圖4.23 course表 圖4.24 stu_cour表,4.3.4 多對多關聯(lián),2. 多對多雙向關聯(lián) 首先將其Course表所對應的POJO對象修改成如下代碼: package org.model; import java.util.HashSet; import java.util.Set; public class Course implements java.io.Serializable private int id; private String cnumber; private String cname; private Set stus=new HashSet
54、(); /省略上述各屬性的getter和setter方法 Course表與Course類的ORM映射文件Course.hbm.xml:,4.4 Hibernate高級功能,4.4.1 Hibernate批量處理 1. 批量插入 (1)通過Hibernate的緩存進行批量插入 使用這種方法時,首先要在Hibernate的配置文件hibernate.cfg.xml中設置批量尺寸屬性hibernate.jdbc.batch_size,且最好關閉Hibernate的二級緩存以提高效率。 例如: 50 / 設置批量尺寸 false / 關閉二級緩存 ,4.4.1 Hibernate批量處理,下面以4.2
55、.1節(jié)的例子中的課程進行批量插入為例,說明批量插入操作的具體過程,這里假設批量插入500個課程到數(shù)據(jù)中: Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); for(int i=0;i500;i+) Kcb kcb=new Kcb(); / 這里設置課程號為i,在實際應用中應該是被插入的課程對象 / 已經(jīng)放在集合或數(shù)組中,這里只要取出 kcb.setKch(i+); session.save(kcb); if(i%50=0) / 以50個課程為一個批次向
56、數(shù)據(jù)庫提交,此值應與配置的批量尺寸一致 session.flush(); / 將該批量數(shù)據(jù)立即插入數(shù)據(jù)庫中 session.clear(); / 清空緩存區(qū),釋放內(nèi)存供下批數(shù)據(jù)使用 mit(); HibernateSessionFactory.closeSession();,4.4.1 Hibernate批量處理,(2)繞過Hibernate直接調(diào)用JDBC進行插入 由于Hibernate只是對JDBC進行了輕量級的封裝,因此完全可以繞過Hibernate直接調(diào)用JDBC進行批量插入。因此上例可以改成如下代碼: Session session=HibernateSessionFactory.g
57、etSession(); Transaction ts=session.beginTransaction(); Connection conn=session.connection(); try PreparedStatement stmt=conn.prepareStatement(insert into KCB(KCH) values(?); for (int i=0; i 500; i+) stmt.setString(1, i+); stmt.addBatch(); / 添加到批處理命令中 stmt.executeBatch(); / 執(zhí)行批處理任務 catch (SQLExcepti
58、on e) e.printStackTrace(); mit(); HibernateSessionFactory.closeSession();,4.4.1 Hibernate批量處理,2. 批量更新 (1)由Hibernate直接進行批量更新 為了使Hibernate的HQL直接支持update/delete的批量更新語法,首先要在Hibernate的配置文件hibernate.cfg.xml中設置HQL/SQL查詢翻譯器屬性hibernate.query.factory_class。 org.hibernate.hql.ast.ASTQueryTranslatorFactory ,4.4
59、.1 Hibernate批量處理,下面使用HQL批量更新把課程表中的XS修改為30。由于這里是用Hibernate操作,故HQL要用類對象及其屬性。 Session session=HibernateSessionFactory.getSession(); Transaction ts=session.beginTransaction(); /在HQL查詢中使用update進行批量更新 Query query=session.createQuery(update Kcb set xs=30); query.executeUpdate(); mit(); HibernateSessionFactor
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 共享藥箱活動策劃方案(3篇)
- 舒膚佳活動促銷策劃方案(3篇)
- 梅州水貼施工方案(3篇)
- 2025年物流運輸管理與服務操作手冊
- 2025年大學大三(應急技術與管理)應急演練組織試題及答案
- 2025年中職(寵物醫(yī)療技術)寵物疾病診療試題及答案
- 2025年大學大一(機械電子工程)機械設計基礎試題及答案
- 2025年中職(市場營銷)產(chǎn)品推銷技巧階段測試試題及答案
- 2026年注冊土木工程師(水工結(jié)構(gòu))(專業(yè)知識考試上)試題及答案
- 2025年大學大三(生態(tài)學)海洋生態(tài)學階段測試題及答案
- 2026年及未來5年中國鍛造件行業(yè)市場深度分析及發(fā)展前景預測報告
- 2025年荊楚理工學院馬克思主義基本原理概論期末考試真題匯編
- 2026年恒豐銀行廣州分行社會招聘備考題庫帶答案詳解
- 紋繡風險協(xié)議書
- 【語文】湖南省長沙市雨花區(qū)桂花樹小學小學一年級上冊期末試卷(含答案)
- 貴港市利恒投資集團有限公司關于公開招聘工作人員備考題庫附答案
- 2026年及未來5年市場數(shù)據(jù)中國大型鑄鍛件行業(yè)市場深度分析及投資戰(zhàn)略數(shù)據(jù)分析研究報告
- 冬季防靜電安全注意事項
- 2025版煤礦安全規(guī)程題庫
- 2025寧夏旅游投資集團有限公司招聘16人(第二批)筆試歷年參考題庫附帶答案詳解
- 村委會工作人員招聘面試常見問題及解答
評論
0/150
提交評論