版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、第10章 Hibernate對持久化對象的操作,10.1 Session的常用方法,10.2 HQL查詢,10.3 Hibernate的批量操作,10.4 持久對象的生命周期,10.1 Session的常用方法,10.1.1 Session的save()方法 Session的save()方法用來對持久化對象進行保存,對應(yīng)到數(shù)據(jù)庫中就是向數(shù)據(jù)庫表中插入一條記錄。例如,在第一個Hibernate的程序中有以下代碼片段: /插入一條記錄方法 public void saveUser() Transaction t1=session.beginTransaction(); User user=new
2、User(); user.setUsername(Jack); user.setPassword(123456); session.save(user); mit(); 如果在Hibernate的核心配置文件中加入語句: true 運行程序時,就會在控制臺顯示出對應(yīng)執(zhí)行的SQL語句,該段代碼對應(yīng)顯示的SQL語句為: insert into userTable (username, password) values (?, ?),10.1.2 Session的get()和load()方法,Session的get()和load()方法都是用來加載持久化類對象的,例如: User user=(Use
3、r) session.get(User.class, 1); / 或User user=(User) session.load(User.class, 1); 用來獲取id為1的User的對象,但兩者是有區(qū)別的。 當數(shù)據(jù)庫表中不存在id為1的值時,使用get()方法返回null,而用load()方法則會拋出異常。 load()查詢會先到緩存中去查,如果沒有則返回一個代理對象(不馬上到數(shù)據(jù)庫中查找),等到后面使用這個代理對象的時候,才到數(shù)據(jù)庫中查找相應(yīng)的信息。若還是沒有找到就拋出異常。get()查詢則是先到緩存中去查,如果沒有就直接到數(shù)據(jù)庫中查詢,還沒有的話就返回null。 load()查詢支持
4、延遲加載,所謂延遲加載就是用到后才到數(shù)據(jù)庫中查詢,從上面一條的查詢方式中也可以看出,load()支持延遲加載,而get()查詢不支持。延遲加載是由映射文件中class標簽的lazy屬性控制的,默認值為true,即延遲加載,如果設(shè)置該屬性為false,即立即加載。,10.1.3 Session的delete()方法,Session的delete()方法用來對持久化對象進行刪除操作,對應(yīng)數(shù)據(jù)庫中就是刪除數(shù)據(jù)庫表的一條記錄。在進行刪除之前,必須先得到要刪除的持久化對象。例如: /刪除一條記錄 public void deleteUser() Transaction t3=session.beginT
5、ransaction(); User user = (User) session.get(User.class, 1); session.delete(user); mit(); 事務(wù)提交后,執(zhí)行SQL語句: delete from userTable where id=? 完成對數(shù)據(jù)庫表記錄的刪除操作。,10.1.4 Session的update()方法,Session的update()方法用于對持久化對象進行修改操作,對應(yīng)數(shù)據(jù)庫中就是修改數(shù)據(jù)庫表的一條記錄。在進行修改之前,必須先得到要修改的持久化對象。例如: /修改一條記錄 public void updateUser() Transac
6、tion t2=session.beginTransaction(); User user=(User) session.get(User.class, 1); user.setUsername(Jacy); session.update(user); mit(); 事務(wù)提交后,執(zhí)行SQL語句: update userTable set username=?, password=? where,10.1.5 Session的saveOrUpdate()方法,Session的saveOrUpdate()方法用于根據(jù)對象的不同情況來分別進行處理。如果指定對象是臨時建立的一個對象(new出來的對象)
7、,即數(shù)據(jù)庫中沒有相應(yīng)記錄,執(zhí)行saveOrUpdate()方法就相當于執(zhí)行save()方法;如果指定對象是游離對象,即數(shù)據(jù)庫中取出對象在數(shù)據(jù)庫中存在,執(zhí)行saveOrUpdate()方法就相當于執(zhí)行update()方法。例如: public void saveOrUpdate() Transaction t3=session.beginTransaction(); User user; user = (User) session.get(User.class, 2); if(user=null) user=new User();/如果沒有就創(chuàng)建一個新的,將被保存 user.setUsernam
8、e(yabber); user.setPassword(123456); else user.setPassword(654321);/如果有就修改密碼 session.saveOrUpdate(user); mit(); ,10.2 HQL查詢,HQL是Hibernate Query Language的縮寫。HQL的語法很像SQL的語法,但HQL是一種面向?qū)ο蟮牟樵冋Z言。SQL的操作對象是數(shù)據(jù)表和列等數(shù)據(jù)對象,而HQL的操作對象是類、實例、屬性等。HQL的查詢依賴于Query類,每個Query實例對應(yīng)一個查詢對象。例如下面的語句: Query query=session.createQuer
9、y(from User);,10.2.1 基本查詢,基本查詢是HQL中最簡單的一種查詢方式。下面以用戶信息為例說明其幾種查詢情況。 (1)查詢所有用戶信息,其代碼如下: Transaction ts=session.beginTransaction(); Query query=session.createQuery(from User); List list=query.list(); mit(); 執(zhí)行上面的代碼片段,得到一個List的對象,可遍歷該對象得出每個用戶的信息。,10.2.1 基本查詢,(2)查詢某個用戶信息,其代碼如下: . Transaction ts = session.
10、beginTransaction(); / 查詢出所有用戶,并按id排序 Query query=session.createQuery(from User order by id desc); query.setMaxResults(1); / 設(shè)置最大檢索數(shù)目為1,表示查詢1條記錄 User user=(User)query.uniqueResult(); / 裝載單個對象 mit(); . 執(zhí)行上面的代碼片段,得到單個對象“user”。 (3)查詢滿足條件的用戶信息,其代碼如下: . Transaction ts = session.beginTransaction(); / 查詢用戶名
11、為yabber的用戶信息 Query query = session.createQuery(from User where username = yabber); List list = query.list(); mit(); .,10.2.2 條件查詢, 按指定參數(shù)查詢。 . Transaction ts = session.beginTransaction(); / 根據(jù)用戶名查詢用戶信息 Query query = session.createQuery(from User where username = ?); query.setParameter(0, yabber); Lis
12、t list = query.list(); mit(); . 執(zhí)行上面的代碼片段,得到所有符合條件的List集合。 使用范圍運算查詢。 . Transaction ts = session.beginTransaction(); / 查詢這樣的用戶信息,用戶名為jack或jacy且id在110之間 Query query = session.createQuery(from User where (id between 1 and 10) and username in(jack,jacy); List list = query.list(); mit(); .,10.2.2 條件查詢, 使
13、用比較運算符查詢。 . Transaction ts = session.beginTransaction(); / 查詢id大于5且用戶名不為空的用戶信息,這里假設(shè)用戶名可以為空,實際情況當然是不存在的 Query query = session.createQuery(from User where id5 and username is not null); List list = query.list(); mit(); . 執(zhí)行上面的代碼片段,得到符合條件的用戶的List集合。,10.2.2 條件查詢, 使用字符串匹配運算查詢。 . Transaction ts = session.
14、beginTransaction(); / 查詢用戶名中包含“a”字符且密碼前面三個字符為“123”的所有用戶信息 Query query = session.createQuery(from User where username like %a% and password like 123%); List list = query.list(); mit(); . 執(zhí)行上面的代碼片段,得到符合條件的用戶的List集合。,10.2.3 分頁查詢,setMaxResults(int maxResult)方法用于指定一次最多查詢出的對象的數(shù)目,默認為所有對象。例如下面的代碼片段: . Trans
15、action ts = session.beginTransaction(); Query query = session.createQuery(from Kcb); int pageNow = 1;/ 想要顯示第幾頁 int pageSize = 5;/ 每頁顯示的條數(shù) query.setFirstResult(pageNow-1)*pageSize);/ 指定從哪一個對象開始查詢 query.setMaxResults(pageSize);/ 指定最大的對象數(shù)目 List list = query.list(); mit(); .,10.2.4 連接查詢,1內(nèi)連接查詢 利用Person與
16、Room進行內(nèi)連接查詢: . / 創(chuàng)建事務(wù)對象 Transaction ts = session.beginTransaction(); Query query=session.createQuery(from Person as p inner join p.room as r); List list=query.list(); mit(); . 在運行時,可以在“hibernate.cfg.xml”文件中加入: true,10.2.4 連接查詢,這樣在運行時,控制臺就會出現(xiàn)相應(yīng)的SQL語句。其實對對象的操作,最終還要應(yīng)用到SQL語句的操作,只是Hibernate把SQL語句封裝起來,讓程序
17、員直接應(yīng)用對象而已。執(zhí)行該段代碼出現(xiàn)的SQL語句為: select person0_.id as id0_0_, room1_.id as id1_1_, person0_.name as name0_0_, person0_.room_id as room3_0_0_, room1_.address as address1_1_ from Person person0_ inner join room room1_ on person0_.room_id=room1_.id,10.2.4 連接查詢,2左外連接查詢 利用Person與Room進行左外連接查詢: . / 創(chuàng)建事務(wù)對象 Trans
18、action ts = session.beginTransaction(); Query query=session.createQuery(from Person as p left join p.room as r); List list=query.list(); mit(); . 執(zhí)行該段代碼,出現(xiàn)的SQL語句為: select person0_.id as id0_0_, room1_.id as id1_1_, person0_.name as name0_0_, person0_.room_id as room3_0_0_, room1_.address as address1
19、_1_ from Person person0_ left outer join room room1_ on person0_.room_id=room1_.id,10.2.4 連接查詢,3右外連接查詢 利用Person與Room進行右外連接查詢: . / 創(chuàng)建事務(wù)對象 Transaction ts = session.beginTransaction(); C List list=query.list(); mit(); . 執(zhí)行該段代碼,出現(xiàn)的SQL語句為: select person0_.id as id0_0_, room1_.id as id1_1_, person0_.name
20、as name0_0_, person0_.room_id as room3_0_0_, room1_.address as address1_1_ from Person person0_ right outer join room room1_ on person0_.room_id=room1_.id,10.2.4 連接查詢,4交叉連接查詢 利用Person與Room進行交叉連接查詢: . / 創(chuàng)建事務(wù)對象 Transaction ts = session.beginTransaction(); Query query=session.createQuery(from Person as
21、 p ,Room as r); List list=query.list(); mit(); . 執(zhí)行該段代碼,出現(xiàn)的SQL語句為: select person0_.id as id0_0_, room1_.id as id1_1_, person0_.name as name0_0_, person0_.room_id as room3_0_0_, room1_.address as address1_1_ from Person person0_, room room1_ 交叉查詢會分別根據(jù)Person及Room 查詢出所有的記錄。,10.2.5 子查詢,子查詢就是在HQL語句中嵌套子查詢
22、,用法與SQL語句差不多,這里舉一個簡單的例子說明: . Transaction ts = session.beginTransaction(); /查詢出有2人或以上居住的地址信息 Query query=session.createQuery(from Room as r where (select count(*) from r.person)1); List list=query.list(); .,10.2.6 SQL查詢,除了上面的幾種查詢,Hibernate還支持原生態(tài)的SQL查詢,SQL查詢是通過SQL Query接口來表示的。SQL Query接口是Query接口的子接口,所
23、以它可以調(diào)用Query接口的方法,例如: setFirstResult():設(shè)置返回結(jié)果集的起始點。 setMaxResult():設(shè)置查詢獲取的最大記錄。 list():返回查詢到的結(jié)果集。 除此之外,SQL查詢還提供了自已的兩個方法: addEntity():將查詢到的記錄與指定的實體關(guān)聯(lián)。 addScalar():指定返回的記錄及類型。,10.2.6 SQL查詢,例如,選擇要查詢前面用例中的“Person”表中的所有記錄,然后關(guān)聯(lián)成程序中的“Person”類,代碼應(yīng)為: . Transaction ts=session.beginTransaction(); SQLQuery sqlqu
24、ery=session.createSQLQuery(select * from Person as p where id1); sqlquery.addEntity(p, Person.class); List list=sqlquery.list(); mit(); session.close(); Iterator it=list.iterator(); while(it.hasNext() Person person=(Person)it.next(); System.out.print(person.getId()+ ); System.out.println(person.getN
25、ame(); .,10.2.6 SQL查詢,上面代碼是應(yīng)用程序中的主要代碼部分,功能是查詢“id1”的Person對象,運行應(yīng)用程序,控制臺輸出查詢結(jié)果及SQL語句,如圖10.1所示。,圖10.1 運行后控制臺輸出,10.2.6 SQL查詢,如果要查詢“id1”的Person的第一個對象,則可以應(yīng)用Query接口中提供的方法實現(xiàn)為: . Transaction ts=session.beginTransaction(); SQLQuery sqlquery=session.createSQLQuery(select * from Person as p where id1); sqlquery
26、.addEntity(p, Person.class); sqlquery.setMaxResults(1); Person person=(Person)sqlquery.uniqueResult(); mit(); session.close(); System.out.print(person.getId()+ ); System.out.println(person.getName(); .,10.2.6 SQL查詢,運行結(jié)果如圖10.2所示。,圖10.2 運行后控制臺輸出,10.2.6 SQL查詢,應(yīng)用addScalar()方法定義返回值及返回值類型,輸出時要用數(shù)組類型: . imp
27、ort org.hibernate.Hibernate; Transaction ts=session.beginTransaction(); SQLQuery sqlquery=session.createSQLQuery(select * from Person as p where id1); sqlquery.addScalar(id, Hibernate.INTEGER); sqlquery.addScalar(name, Hibernate.STRING); List list=sqlquery.list(); mit(); session.close(); Iterator it
28、=list.iterator(); while(it.hasNext() Object obj=(Object)it.next(); System.out.println(id:+obj0); System.out.println(name:+obj1); .,10.2.6 SQL查詢,運行程序,控制臺輸出如圖10.3所示。,圖10.3 控制臺輸出,10.2.6 SQL查詢,Hibernate調(diào)用存儲過程有兩種方法,一種是通過配置文件“*.hbm.xml”進行配置,然后在程序中調(diào)用,另一種是繞過Hibernate,直接操作JDBC進行調(diào)用。 在SQL Server數(shù)據(jù)庫中對student表建立
29、存儲過程如下: create procedure selectAllStudent as select * from student; 通過配置文件進行配置,然后在程序中調(diào)用。 假如項目中有student表(應(yīng)用前面的student表)對應(yīng)的類Student.java,選擇對其映射文件Student.hbm.xml進行配置。,10.2.6 SQL查詢,代碼中的黑體部分是對存儲過程的配置,只需要多出這簡單的配置即可,下面看其在程序中調(diào)用: . Transaction ts=session.beginTransaction(); List list=session.getNamedQuery(se
30、lectStudent).list(); mit(); session.close(); Iterator it=list.iterator(); while(it.hasNext() Student stu=(Student)it.next(); System.out.println(stu.getSname(); .,10.2.6 SQL查詢,運行后查看控制臺輸出,如圖10.4所示。,圖10.4 程序運行后的控制臺輸出,10.2.6 SQL查詢, 繞過Hibernate直接使用JDBC調(diào)用。 應(yīng)用該種方法,映射文件不用加入“存儲過程的配置”,可以直接在程序中做如下調(diào)用: try Conne
31、ction conn=session.connection(); CallableStatement cstmt=conn.prepareCall(call selectAllStudent); Transaction ts=session.beginTransaction(); ResultSet rs=cstmt.executeQuery(); while(rs.next() System.out.println(rs.getString(3); mit(); session.close(); catch(Exception e) e.printStackTrace(); ,10.2.6
32、SQL查詢,運行程序,控制臺輸出結(jié)果如圖10.5所示。,圖10.5 程序運行后的控制臺輸出,10.3 Hibernate的批量操作,10.3.1 批量插入 通過Hibernate的緩存進行批量插入。 使用這種方法時,首先要在Hibernate的配置文件hibernate.cfg.xml中設(shè)置批量尺寸屬性“hibernate.jdbc.batch_size”,且最好關(guān)閉Hibernate的二級緩存以提高效率。例如: 50 / 設(shè)置批量尺寸 false / 關(guān)閉二級緩存 ,10.3.1 批量插入,本例以對9.3.2節(jié)多對多關(guān)系的student關(guān)系表進行批量插入為例,說明批量操作的具體過程,這里假設(shè)
33、批量插入500個學(xué)生到數(shù)據(jù)庫中: Transaction ts=session.beginTransaction(); for(int i=0;i500;i+) Student stu=new Student(); / 這里設(shè)置學(xué)號為“0811”+i,在實際應(yīng)用中應(yīng)該是被插入的學(xué)生對象 / 已經(jīng)放在集合中或數(shù)組中,這里只要取出 stu.setSnumber(0811+i); session.save(stu); if(i%50=0) / 以50個學(xué)生為一個批次向數(shù)據(jù)庫中提交,此值應(yīng)與配置的批量尺寸一致 session.flush(); / 將該批量數(shù)據(jù)立即插入數(shù)據(jù)庫中 session.clea
34、r(); / 清空緩存區(qū),釋放內(nèi)存供下批數(shù)據(jù)使用 mit();,10.3.1 批量插入, 繞過Hibernate直接調(diào)用JDBC進行插入。 由于Hibernate只是對JDBC進行了輕量級的封裝,因此完全可以繞過Hibernate直接調(diào)用JDBC進行批量插入。因此,上例就可以改成如下代碼: Transaction ts=session.beginTransaction(); Connection conn=session.connection(); try PreparedStatement stmt=conn.prepareStatement(insert into student(SNUM
35、BER) values(?); for (int i = 0; i 500; i+) stmt.setString(1, 0811+i); stmt.addBatch(); / 添加到批處理命令中 stmt.executeBatch(); / 執(zhí)行批處理任務(wù) catch (SQLException e) e.printStackTrace(); mit();,10.3.2 批量更新, 由Hibernate直接進行批量更新。 為了使Hibernate的HQL直接支持update/delete的批量更新語法,首先要在Hibernate的配置文件hibernate.cfg.xml中設(shè)置HQL/SQL
36、查詢翻譯器屬性“hibernate.query.factory_class”。設(shè)置如下: org.hibernate.hql.ast.ASTQueryTranslatorFactory 下面使用HQL批量更新把student表中的SAGE修改為20。由于這里是用Hibernate操作,故HQL要用類對象及其屬性。 Transaction ts=session.beginTransaction(); /在HQL查詢中使用update進行批量更新 Query query=session.createQuery(update Student set sage=20); query.executeUp
37、date(); mit();,10.3.2 批量更新, 繞過Hibernate調(diào)用JDBC進行批量更新。 由于這里是直接操作數(shù)據(jù)庫,故要操作對應(yīng)的表,而不是類。 Transaction ts=session.beginTransaction(); Connection conn=session.connection(); try Statement stmt=conn.createStatement(); /調(diào)用JDBC的update進行批量更新 stmt.executeUpdate(update student set SAGE=30); catch (SQLException e) e.p
38、rintStackTrace(); mit();,10.3.3 批量刪除, 由Hibernate直接進行批量刪除。 同批量更新一樣,為了使Hibernate的HQL直接支持update/delete的批量刪除語法,首先要在Hibernate的配置文件hibernate.cfg.xml中設(shè)置HQL/SQL查詢翻譯器屬性“hibernate.query.factory_class”,如下: org.hibernate.hql.ast.ASTQueryTranslatorFactory 下面將使用HQL批量刪除student表中ID號大于300的學(xué)生。 Transaction ts=session.beginTransaction(); /在HQL查詢中使用delete進行批量刪除 Query query=session.createQuery(delete Student where id300); query.executeUpdate(); mit();,10.3.3 批量刪
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026寧波前灣新區(qū)衛(wèi)生系統(tǒng)事業(yè)單位招聘高層次人才42人筆試備考試題及答案解析
- 2026年潤含公司招聘2名勞務(wù)派遣員工筆試備考試題及答案解析
- 2026湖南長沙市雨花湘一外國語中學(xué)春季合同制教師招聘考試備考試題及答案解析
- 2026江蘇南京大學(xué)哲學(xué)學(xué)院博士后招聘1人筆試備考題庫及答案解析
- 2026湖北交通投資集團有限公司招聘14人考試參考題庫及答案解析
- 2026年學(xué)生心理健康輔導(dǎo)技巧課程
- 2026首都經(jīng)濟貿(mào)易大學(xué)招聘103人考試參考題庫及答案解析
- 2026年甘肅省金昌市金川路街道社區(qū)衛(wèi)生服務(wù)中心招聘(聘用制)專業(yè)技術(shù)人員筆試模擬試題及答案解析
- 北京市大興區(qū)魏善莊鎮(zhèn)社區(qū)衛(wèi)生服務(wù)中心招聘勞務(wù)派遣人員1人(行政技能輔助崗)筆試參考題庫及答案解析
- 2026上半年貴州事業(yè)單位聯(lián)考綏陽縣招聘73人筆試參考題庫及答案解析
- 復(fù)發(fā)性叢集性頭痛
- 宮頸息肉個案護理
- 新生兒感染護理查房
- 2026屆高考語文專題復(fù)習(xí)-哲理詩
- (二調(diào))武漢市2025屆高中畢業(yè)生二月調(diào)研考試 生物試卷(含標準答案)
- 2024-2025學(xué)年天津市和平區(qū)高三上學(xué)期1月期末英語試題(解析版)
- 管理人員應(yīng)懂財務(wù)知識
- ISO9001-2015質(zhì)量管理體系版標準
- 翻建房屋四鄰協(xié)議書范本
- 打樁承包合同
- 輸煤棧橋彩鋼板更換施工方案
評論
0/150
提交評論