2.7  使用MyEclipse可視化開(kāi)發(fā)Hibernate實(shí)例

2.7節(jié)的例子源代碼在配套光盤(pán)sourcecode/workspace目錄的chapter02_first項(xiàng)目中。

這個(gè)實(shí)例主要演示如何使用MyEclipse的可視化開(kāi)發(fā)工具開(kāi)發(fā)Hibernate應(yīng)用,利用MyEclipse可以提高我們開(kāi)發(fā)Java EE應(yīng)用的效率。操作的數(shù)據(jù)庫(kù)表還是guestbook表,所使用MyEclipse的版本為7.0,不同的MyEclipse版本之間對(duì)于開(kāi)發(fā)Hibernate應(yīng)用差異不大。

在7.0版本中,內(nèi)置了對(duì)Hibernate 2.x、3.0、3.1和3.2等Hibernate版本的支持,沒(méi)有提供對(duì)3.3版本的支持。我們可以修改MyEclipse的設(shè)置,把對(duì)Hibernate 3.2的支持,修改為對(duì)Hibernate 3.3的支持。為此啟動(dòng)Eclipse后,選中菜單欄的"Windows"→"Preference"→"MyEclipse Enterprise Workbench"→"Project Capabilities"→"Hibernate"→"Hibernate 3.2"選項(xiàng),在Library Modules下拉列表框中選中Hibernate 3.2 Core Libray選項(xiàng),把類(lèi)庫(kù)文件替換為Hibernate 3.3的類(lèi)庫(kù)文件。如圖2 2所示。

 

  
圖2 2  修改MyEclipse中Hibernate 3.2的類(lèi)庫(kù)文件

 

 

2.7.1  設(shè)置MyEclipse連接Oracle數(shù)據(jù)庫(kù)

為在MyEclipse中設(shè)置連接Oracle數(shù)據(jù)庫(kù),在Eclipse中選擇Window→Show View→Other→MyEclipse Database→DB Browser選項(xiàng)。右擊DB Browser視圖的空白部分,選擇New選項(xiàng),如圖2 3所示。

 

 
圖2 3  選擇New選項(xiàng)

 

在彈出的窗口中,輸入連接Oracle數(shù)據(jù)庫(kù)所需要的相應(yīng)參數(shù),以及Oracle驅(qū)動(dòng)類(lèi)庫(kù)的文件名與位置。單擊Next按鈕,如圖2 4所示。

 

 
圖2 4  輸入連接Oracle數(shù)據(jù)庫(kù)的參數(shù)

 

在Schema Details窗口中,選中Display Selected單選按鈕。單擊"Add"按鈕,在彈出的Selection Needed窗口中選中SCOTT復(fù)選框。單擊"OK"按鈕,如圖2 5所示。單擊"Finish"按鈕,關(guān)閉Schema Details窗口。

 

 
圖2 5  選擇SCOTT復(fù)選框

 

2.7.2  新建項(xiàng)目并增加Hibernate開(kāi)發(fā)支持

在Eclipse中新建一個(gè)Java項(xiàng)目,名為"chapter02_first"。單擊MyEclipse→Project Capabilities→Add Hibernate Capabilites選項(xiàng),增加Hibernate的開(kāi)發(fā)支持,如圖2 6所示。

 

 
圖2 6  增加Hibernate的開(kāi)發(fā)支持

 

彈出Hibernate Support for MyEclipse窗口,在Hibernate Specification選項(xiàng)組中選中Hibernate 3.2單選按鈕,選擇MyEclipse Libraries和Hibernate 3.2 Core Libaries-<MyEclipse-Library>復(fù)選框選項(xiàng),如圖2 7所示,單擊Next按鈕。

 

 
圖2 7  選擇Hibernate類(lèi)庫(kù)的版本

 

其中的選項(xiàng)說(shuō)明如表2-3所示。

表2-3  選項(xiàng)說(shuō)明

選項(xiàng)

描述

Hibernate Specification

要添加到項(xiàng)目中的Hibernate具體版本,推薦選擇Hibernate 3.2

Enable Hibernate Annotations Support

是否需要Hibernate Annotations的支持

MyEclipse Libraries/User Libraries

選擇顯示哪個(gè)位置的類(lèi)庫(kù)

Add checked Libraries to project build-path

選中的類(lèi)庫(kù)將會(huì)添加當(dāng)前項(xiàng)目的構(gòu)建路徑中,但是相應(yīng)的Jar文件將不會(huì)復(fù)制到項(xiàng)目中,這些Jar文件會(huì)在項(xiàng)目部署時(shí)復(fù)制

Copy checked Library Jars to project folder and add to build-path

選中的類(lèi)庫(kù)中的Jar文件將會(huì)被復(fù)制到項(xiàng)目并添加到構(gòu)建路徑中

Library Folder

一個(gè)相對(duì)于當(dāng)前項(xiàng)目的路徑,類(lèi)庫(kù)中的Jar會(huì)被復(fù)制到其中

 


 

在接下來(lái)的窗口中輸入MyEclipse產(chǎn)生的Hibernate配置文件名及其路徑。使用hibernate.cfg.xml文件名,路徑保留默認(rèn)值,如圖2 8所示。

 

 
圖2 8  設(shè)置生成hibernate.cfg.xml文件的名稱(chēng)及其路徑

 

單擊Next按鈕,在DB Driver下拉列表框中選中已設(shè)置的oracledriver選項(xiàng),其他選項(xiàng)保留默認(rèn)值,如圖2 9所示。

 

 
圖2 9  選擇要使用的數(shù)據(jù)庫(kù)

 

單擊"Next"按鈕,清除"Create SessionFactory Class"復(fù)選框,如圖2 10所示,單擊Finish按鈕結(jié)束設(shè)置。

 

 
圖2 10  清除Create SessionFactory Class復(fù)選框

 

 


 

執(zhí)行上述操作后,MyEclipse會(huì)在項(xiàng)目的構(gòu)建路徑中增加Hibernate的相關(guān)類(lèi)庫(kù)和Oracle的驅(qū)動(dòng)類(lèi)庫(kù)。同時(shí)生成了開(kāi)發(fā)Hibernate應(yīng)用所需的hibernate.cfg.xml文件,整個(gè)項(xiàng)目的所有類(lèi)庫(kù)文件和配置文件如圖2 11所示。

 

 
圖2 11  整個(gè)項(xiàng)目的所有類(lèi)庫(kù)文件和配置文件

 

還需要修改MyEclipse自動(dòng)生成的hibernate.cfg.xml文件,增加一些新的配置項(xiàng)并修改Oracle數(shù)據(jù)庫(kù)方言類(lèi)的名稱(chēng)。修改后的hibernate.cfg.xml的內(nèi)容如下所示(加粗顯示部分為需要修改處)。

  1. SRC 2 2  hibernate.cfg.xml  
  2. <?xml version='1.0' encoding='UTF-8'?>  
  3. <!DOCTYPE hibernate-configuration PUBLIC  
  4. "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
  5. "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
  6. <hibernate-configuration>  
  7.     <session-factory>  
  8.         <property name=  
  9. "dialect">org.hibernate.dialect.Oracle9iDialect</property>  
  10.         <property name=  
  11. "connection.url">jdbc:oracle:thin:@localhost:1521:ora9</property>  
  12. <property name="connection.username">scott</property>  
  13. <property name="connection.password">tiger</property>  
  14. <property name=  
  15. "connection.driver_class">oracle.jdbc.driver.OracleDriver</property>  
  16. <property name="myeclipse.connection.profile">oracledriver</property>  
  17. <property name="current_session_context_class">thread</property>  
  18.         <property name="show_sql">true</property>  
  19. <property name="format_sql">true</property>  
  20.     </session-factory>  
  21. </hibernate-configuration> 

 

 

2.7.3  自動(dòng)生成Guestbook類(lèi)與映射文件

在Eclipse的DB Browser視圖中,右擊設(shè)置的oracledriver名。選擇Open connection選項(xiàng),如圖2 12所示彈出Open Database Connection窗口,輸入用戶(hù)名及密碼,如圖2 13所示,單擊OK按鈕。

 

 
圖2 12  選澤Open Database Connection選項(xiàng)

 
圖2 13  輸入用戶(hù)名與密碼

 

右擊DB Browser視圖中的guestbook表,選中"Hibernate Reverse Engineering"選項(xiàng)。如圖2 14所示。

 

 
圖2 14  選擇Hibernate Reverse Engineering選項(xiàng)

 

 



 

彈出"Hibernate Mapping and Application Generation"窗口,輸入與生成持久化類(lèi)(POJO)有關(guān)的參數(shù)值。在Java src folder文本框中輸入生成持久化類(lèi)的保存路徑,在Java package文本框中輸入持久化類(lèi)所使用的包名。選擇"Create POJO<>DB Table mapping information、Create a Hibernate mapping file (*.hbm.xml) for each database table"及"Java Data Object (POJO<> DB Table)"復(fù)選框,清除"Create abstract class"復(fù)選框,如圖2 15所示。

 
圖2 15  設(shè)置生成POJO類(lèi)與映射文件

 

單擊Next按鈕,在打開(kāi)窗口中的Id Generator下拉列表框中選中sequence選項(xiàng),其他選項(xiàng)保留默認(rèn)值,如圖2 16所示。

 

 
圖2 16  選擇主鍵生成策略

 

 


 

單擊"Next"按鈕,在打開(kāi)如圖2 17所示的窗口中單擊"Finish"按鈕。

  
圖2 17  設(shè)置逆向工程的細(xì)節(jié)

 

經(jīng)過(guò)上面的操作之后,MyEclipse會(huì)自動(dòng)生成Guestbook.java和Guestbook.hbm.xml兩個(gè)文件。Guestbook.hbm.xml文件的內(nèi)容如下所示,需要修改008行~第010行的內(nèi)容用來(lái)設(shè)置序列名。

  1. SRC 2 3  Guestbook.hbm.xml  
  2. 001 <?xml version="1.0" encoding="utf-8"?>  
  3. 002 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate   
  4. Mapping DTD 3.0//EN"  
  5. 003 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  6. 004 <hibernate-mapping>  
  7. 005 <class name="com.v512.examples.Guestbook" table="GUESTBOOK"   
  8. schema="SCOTT">  
  9. 006 <id name="id" type="java.lang.Integer">  
  10. 007     <column name="ID" precision="8" scale="0" />  
  11. 008     <generator class="sequence">  
  12. 009     <param name="sequence">gb_seq</param>  
  13. 010             </generator>  
  14. 011</id>  
  15. 012<property name="name" type="java.lang.String">  
  16. 013 <column name="NAME" length="20" not-null="true" />  
  17. 014</property>  
  18. 015<property name="phone" type="java.lang.String">  
  19. 016 <column name="PHONE" length="20" />  
  20. 017</property>  
  21. 018<property name="email" type="java.lang.String">  
  22. 019 <column name="EMAIL" length="40" />  
  23. 020</property>  
  24. 021<property name="title" type="java.lang.String">  
  25. 022 <column name="TITLE" length="80" not-null="true" />  
  26. 023</property>  
  27. 024<property name="content" type="java.lang.String">  
  28. 025 <column name="CONTENT" length="2000" />  
  29. 026</property>  
  30. 027<property name="createdTime" type="java.util.Date">  
  31. 028 <column name="CREATED_TIME" not-null="true" />  
  32. 029</property>  
  33. 030     </class>  
  34. 031 </hibernate-mapping> 

第005行中<class>標(biāo)簽的schema屬性設(shè)置當(dāng)前表屬于哪個(gè)schema,第007行和第013行中<column>標(biāo)簽的precision、scale及l(fā)ength屬性設(shè)置表中字段的精度、小數(shù)點(diǎn)位數(shù)和長(zhǎng)度,not-null屬性設(shè)置該字段是否不允許為空。

2.7.4  編寫(xiě)HibernateSessionFactoryUtil.java文件

在Hibernate應(yīng)用中,如果只使用一個(gè)數(shù)據(jù)庫(kù),則通常只需要一個(gè)SessionFactory對(duì)象。為了方便整個(gè)應(yīng)用取得同一個(gè)SessionFactory對(duì)象,我們應(yīng)用設(shè)計(jì)模式中的單態(tài)模式。編寫(xiě)一個(gè)SessionFactory的工具類(lèi)HibernateSessionFactoryUtil,HibernateSessionFactoryUtil.java文件的內(nèi)容如下:

  1. SRC 2 4  HibernateSessionFactoryUtil.java  
  2. 001 package com.v512.util;  
  3. 002   
  4. 003 import org.hibernate.SessionFactory;  
  5. 004 import org.hibernate.cfg.Configuration;  
  6. 005   
  7. 006 public class HibernateSessionFactoryUtil {  
  8. 007     private static final SessionFactory sessionFactory;  
  9. 008     static {  
  10. 009         try {  
  11. 010             sessionFactory = new Configuration().configure().
    buildSessionFactory();  
  12. 011         } catch (Throwable ex) {  
  13. 012             /*  
  14. 013              * 需要 捕獲Throwable對(duì)象,   
  15. 014 * 否則捕獲不到 Error及其子類(lèi),以及NoClassDefFoundError類(lèi)型的錯(cuò)誤  
  16. 015              */ 
  17. 016             throw new ExceptionInInitializerError(ex);  
  18. 017         }  
  19. 018     }  
  20. 019   
  21. 020     private HibernateSessionFactoryUtil() {  
  22. 021   
  23. 022     }  
  24. 023   
  25. 024     public static SessionFactory getSessionFactory() {  
  26. 025         return sessionFactory;  
  27. 026     }  
  28. 027 } 

HibernateSessionFactoryUtil類(lèi)在載入JVM后新建Configuration對(duì)象,讀取hibernate.cfg.xml文件,創(chuàng)建SessionFactory對(duì)象,通過(guò)HibernateSessionFactoryUtil類(lèi)所提供的getSessionFactory()靜態(tài)方法獲取SessionFactory對(duì)象。

2.7.5  編寫(xiě)HibernateTest.java

編寫(xiě)一個(gè)測(cè)試的HibernateTest.java文件,通過(guò)Hibernate實(shí)現(xiàn)對(duì)guestbook表中數(shù)據(jù)的CRUD操作,在其中定義addGuestbook()、updateGuestbook()、getGuestbook()、getGuestbooks()、deleteGuestbook()和printGuestbook()方法。該文件的內(nèi)容如下:

  1. SRC 2 5  HibernateTest.javaa  
  2. 001 package com.v512.examples;  
  3. 002   
  4. 003 import java.util.List;  
  5. 004 import org.hibernate.Query;  
  6. 005 import org.hibernate.Session;  
  7. 006 import org.hibernate.Transaction;  
  8. 007 import com.v512.util.HibernateSessionFactoryUtil;  
  9. 008   
  10. 009 public class HibernateTest {  
  11. 010     public void addGuestbook(Guestbook gb) {  
  12. 011Session session = HibernateSessionFactoryUtil.
  13. getSessionFactory().  
  14. getCurrentSession();  
  15. 012         Transaction tx = session.beginTransaction();  
  16. 013         session.save(gb);  
  17. 014         tx.commit();  
  18. 015     }  
  19. 016   
  20. 017     public Guestbook getGuestbook(Integer id) {  
  21. 018         Session session = HibernateSessionFactoryUtil.
  22. getSessionFactory().  
  23. getCurrentSession();  
  24. 019         Transaction tx = session.beginTransaction();  
  25. 020         Guestbook gb = (Guestbook) session.get
  26. (Guestbook.class, id);  
  27. 021         tx.commit();  
  28. 022         return gb;  
  29. 023     }  
  30. 024   
  31. 025     public List<Guestbook> getGuestbooks() {  
  32. 026         Session session = HibernateSessionFactoryUtil.
  33. getSessionFactory().  
  34. getCurrentSession();  
  35. 027         Transaction tx = session.beginTransaction();  
  36. 028         Query query = session.createQuery("from Guestbook");  
  37. 029         List<Guestbook> list = query.list();  
  38. 030         tx.commit();  
  39. 031         return list;  
  40. 032     }  
  41. 033   
  42. 034     public void updateGuestbook(Guestbook gb) {  
  43. 035         Session session = HibernateSessionFactoryUtil.
  44. getSessionFactory().  
  45. getCurrentSession();  
  46. 036         Transaction tx = session.beginTransaction();  
  47. 037         session.saveOrUpdate(gb);  
  48. 038         tx.commit();  
  49. 039     }  
  50. 040   
  51. 041     public void deleteGuestbook(Integer id) {  
  52. 042         Guestbook gb = getGuestbook(id);  
  53. 043         Session session = HibernateSessionFactoryUtil.
  54. getSessionFactory().  
  55. getCurrentSession();  
  56. 044         Transaction tx = session.beginTransaction();  
  57. 045         session.delete(gb);  
  58. 046         tx.commit();  
  59. 047     }  
  60. 048   
  61. 049     public void printGuestbook(Guestbook gb) {  
  62. 050         System.out.print("id:" + gb.getId() + "\t");  
  63. 051         System.out.print("name:" + gb.getName() + "\t");  
  64. 052         System.out.print("title:" + gb.getTitle() + "\t");  
  65. 053         System.out.print("content:" + gb.getContent() + "\t");  
  66. 054         System.out.println("createdTime:" + gb.getCreatedTime());  
  67. 055     }  
  68. 056   
  69. 057     public static void main(String[] args) {  
  70. 058         HibernateTest test = new HibernateTest();  
  71. 059         Guestbook gb = test.getGuestbook(new Integer(1));  
  72. 060   
  73. 061         System.out.println("-------------------------
  74. 讀取單一記錄-----------------------------");  
  75. 062         test.printGuestbook(gb);  
  76. 063   
  77. 064         System.out.println("-------------------------
  78. 讀取所有記錄-----------------------------");  
  79. 065         List<Guestbook> list = test.getGuestbooks();  
  80. 066         for (Guestbook g : list) {  
  81. 067             test.printGuestbook(g);  
  82. 068         }  
  83. 069   
  84. 070         System.out.println("-------------------------
  85. 更新記錄---------------------------------");  
  86. 071         gb.setName("關(guān)羽");  
  87. 072         test.updateGuestbook(gb);  
  88. 073         test.printGuestbook(gb);  
  89. 074   
  90. 075         System.out.println("-------------------------
  91. 刪除記錄---------------------------------");  
  92. 076         test.deleteGuestbook(new Integer(1));  
  93. 077   
  94. 078 HibernateSessionFactoryUtil.getSessionFactory().close();  
  95. 079     }  
  96. 080 } 

當(dāng)使用HibernateTest類(lèi)中g(shù)etGuestbook()方法根據(jù)id值獲取一條記錄時(shí),Hibernate找到數(shù)據(jù)庫(kù)中這條記錄,然后再生成這條記錄所對(duì)應(yīng)的持久化對(duì)象返回。updateGuestbook()方法更新一條記錄時(shí)首先找到這條記錄所對(duì)應(yīng)的持久化對(duì)象,然后調(diào)用這個(gè)對(duì)象的setter方法修改屬性值,并通過(guò)Hibernate完成數(shù)據(jù)庫(kù)中數(shù)據(jù)的更新;deleteGuestbook()方法刪除一條記錄時(shí)首先找到這條記錄所對(duì)應(yīng)的持久化對(duì)象,然后通過(guò)Hibernate刪除持久化對(duì)象刪除進(jìn)而數(shù)據(jù)庫(kù)中所對(duì)應(yīng)的數(shù)據(jù)。

2.7.6  程序運(yùn)行結(jié)果

這個(gè)實(shí)例使用Hibernate完成對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的CRUD操作,借助MyEclipse的幫助開(kāi)發(fā)Hibernate應(yīng)用,不需要手工編寫(xiě)持久化(POJO)類(lèi)、Hibernate的配置和映射文件。Hibernate通過(guò)操作持久化對(duì)象完成對(duì)數(shù)據(jù)庫(kù)數(shù)據(jù)的CRUD操作, HibernateTest.java運(yùn)行結(jié)果如下:

  1. -------------------------讀取單一記錄-----------------------------  
  2. id:1    name:劉偉 title:大家好     
  3. content:歡迎大家學(xué)習(xí)Hibernate技術(shù)。  
  4.         createdTime: 2009-03-12 06:17:59.0 
  5. -------------------------讀取所有記錄-----------------------------  
  6. id:1    name:劉偉 title:大家好     
  7. content:歡迎大家學(xué)習(xí)Hibernate技術(shù)。  
  8.         createdTime: 2009-03-12 06:17:59.0 
  9. -------------------------更新記錄---------------------------------  
  10. id:1    name:關(guān)羽 title:大家好     
  11. content:歡迎大家學(xué)習(xí)Hibernate技術(shù)。  
  12.         createdTime: 2009-03-12 06:17:59.0 
  13. -------------------------刪除記錄--------------------------------- 

 

 

2.7.7  使用 HQL 編輯器調(diào)試HQL語(yǔ)句

MyEclipse中包含一個(gè)Hibernate編輯器和多個(gè)相關(guān)視圖,允許根據(jù)當(dāng)前項(xiàng)目的配置來(lái)調(diào)試HQL語(yǔ)句。"Hibernate Dynamic Query Translator"視圖顯示當(dāng)前HQL語(yǔ)句所對(duì)應(yīng)的SQL語(yǔ)句;"Hibernate Query Result"視圖查看HQL語(yǔ)句的執(zhí)行結(jié)果,返回的持久化對(duì)象的屬性值通過(guò)"Properties"視圖顯示;"Query Parameters"視圖可以為調(diào)試的HQL語(yǔ)句輸入需要的參數(shù)值。

右擊Package Explorer視圖中的chapter02_first項(xiàng)目,選中快捷菜單中的"MyEclipse→Open HQL Editor"選項(xiàng),如圖2 18所示。

 

 
圖2-18  MyEclipse→Open HQL Editor選項(xiàng)

 

打開(kāi)HQL編輯器,輸入"from Guestbook"。單擊運(yùn)行圖標(biāo)執(zhí)行查詢(xún),并且通過(guò)相關(guān)視圖查看查詢(xún)結(jié)果,如圖2 19所示。

 

 
圖2 19  在HQL編輯器中執(zhí)行HQL查詢(xún)并查看結(jié)果

 

還可以使用"Query Parameters視圖輸入需要綁定參數(shù)的HQL查詢(xún)語(yǔ)句,如圖2 20所示。

 

 
圖2 20  使用Query Parameters 視圖輸入需要綁定參數(shù)的HQL查詢(xún)語(yǔ)句

 

 

2.8  Hibernate應(yīng)用的開(kāi)發(fā)方式

2.8.1  自底向上,從數(shù)據(jù)庫(kù)表到持久化類(lèi)

采用自底向上的開(kāi)發(fā)方式,采用手工或者M(jìn)yEclipse等開(kāi)發(fā)工具直接根據(jù)數(shù)據(jù)庫(kù)中表的結(jié)構(gòu)生成對(duì)應(yīng)的映射文件和持久化類(lèi)。這是實(shí)際開(kāi)發(fā)中最常用的一種方式,也是本書(shū)所推薦的方式。通過(guò)這種方式最小化了手工編碼,降低了出錯(cuò)的可能性。

2.8.2  自上向下,持久化類(lèi)到數(shù)據(jù)庫(kù)表

首先編寫(xiě)持久化類(lèi),然后根據(jù)持久化類(lèi)的代碼手工編寫(xiě)或者采用工具生成映射文件,進(jìn)而生成數(shù)據(jù)庫(kù)表結(jié)構(gòu)。這種方式在實(shí)際開(kāi)發(fā)中也經(jīng)常使用,可能出現(xiàn)的問(wèn)題是生成的數(shù)據(jù)庫(kù)表結(jié)構(gòu)與實(shí)際需要的數(shù)據(jù)庫(kù)表結(jié)構(gòu)之間的差異,需要手工調(diào)整。

2.8.3  從中間出發(fā),向上與向下發(fā)展

首先編寫(xiě)持久化類(lèi)與數(shù)據(jù)庫(kù)表的映射文件,然后根據(jù)映射文件手工編碼或者采用工具向上生成持久化類(lèi),向下生成數(shù)據(jù)庫(kù)表結(jié)構(gòu)。

2.9  設(shè)置Hibernate使用連接池

Hibernate默認(rèn)使用一個(gè)功能簡(jiǎn)單的連接池,通常只用于開(kāi)發(fā)階段測(cè)試之用。為了更高效地使用Hibernate,可以設(shè)置Hibernate使用第三方C3P0或者應(yīng)用服務(wù)器(容器)所帶的數(shù)據(jù)庫(kù)連接池。

2.9.1  設(shè)置使用Tomcat中的連接池

如果開(kāi)發(fā)運(yùn)行在應(yīng)用服務(wù)器中的程序,建議其中配置的連接池,如允許Hibernate使用通過(guò)在Tomcat中所配置的連接池。為此修改Tomcat中的context.xml文件,該文件位于tomcat安裝目錄的conf子目錄中,同時(shí)還需要將Oracle數(shù)據(jù)庫(kù)的驅(qū)動(dòng)類(lèi)庫(kù)ojdbc6.jar或者ojdbc14.jar添加到tomcat的lib目錄下。修改后的context.xml文件內(nèi)容如下:

  1. SRC 2 6  context.xml  
  2. <Context reloadable="true">  
  3.     <WatchedResource>WEB-INF/web.xml</WatchedResource>  
  4.     <Resource name="jdbc/oracleds" auth="Container"   
  5.     type="javax.sql.DataSource" maxActive="100"   
  6. maxIdle="30" maxWait="10 000" username="scott" password="tiger"   
  7.         driverClassName="oracle.jdbc.OracleDriver" url=
    "jdbc:oracle:thin:@localhost:1521:ora9" />  
  8. </Context> 

設(shè)置Tomcat提供的連接池之后,要在Hibernate的配置文件(hibernate.cfg.xml)中添加connection.datasource屬性,如下面的代碼所示:

  1. <property name="connection.datasource">  
  2. java:comp/env/jdbc/oracleds</property> 

其中的java:comp/env/jdbc/oracleds是Tomcat中設(shè)置的數(shù)據(jù)源對(duì)象的JNDI名稱(chēng)。

2.9.2  使用C3P0連接池

如果讓Hibernate使用第三方C3P0連接池,則在Hibernate的配置文件中添加如下的配置信息,還需要把C3P0類(lèi)庫(kù)添加到當(dāng)前項(xiàng)目的構(gòu)建路徑下。

  1. <property name="connection.provider_class">  
  2.         org.hibernate.connection.C3P0ConnectionProvider  
  3. </property>  
  4. <property name="hibernate.c3p0.min_size">5</property>  
  5. <property name="hibernate.c3p0.max_size">10</property>  
  6. <property name="hibernate.c3p0.max_statements">50</property>  
  7. <property name="hibernate.c3p0.timeout">3600</property>  
  8. <property name="hibernate.c3p0.idle_test_period">120</property>  
  9. <property name="hibernate.c3p0.acquire_increment">2</property> 

- hibernate.c3p0.min_size:設(shè)置連接池的最小連接數(shù)。

- hibernate.c3p0.max_siz:設(shè)置連接池的最大連接數(shù)。

- hibernate.c3p0.timeout:設(shè)置連接池中的連接的最大空閑時(shí)間,超時(shí)后會(huì)被刪除,單位為秒。

- hibernate.c3p0.max_statements:設(shè)置連接池中Statement對(duì)象的最大數(shù)量。

- hibernate.c3p0.idle_test_period:設(shè)置檢查連接池中空閑連接的間隔時(shí)間,單位為秒。

- hibernate.c3p0.acquire_increment:設(shè)置連接池的連接用完后每次新建連接的數(shù)量。

2.9.3  使用自定義連接池

在Hibernate應(yīng)用中還可以使用定義連接池,該連接池需要實(shí)現(xiàn)org.hibernate.connection.ConnectionProvider接口,并在Hibernate配置文件中設(shè)置hibernate.connection.provider_class屬性,其值為這個(gè)實(shí)現(xiàn)類(lèi)的名稱(chēng)。

2.10  使用C3P0連接池

2.10節(jié)的例子源代碼在配套光盤(pán)sourcecode/workspace目錄的chapter02_first項(xiàng)目中。

2.10.1  創(chuàng)建chapter02_c3p0項(xiàng)目

在這個(gè)實(shí)例中讓Hibernate使用第三方C3P0連接池獲取操作數(shù)據(jù)庫(kù)的連接對(duì)象,通過(guò)復(fù)制chapter02_first項(xiàng)目創(chuàng)建chapter02_c3p0項(xiàng)目。同時(shí)還需要把C3P0連接池的類(lèi)庫(kù)(c3p0-*.*.*.jar)添加到當(dāng)前項(xiàng)目的構(gòu)建目錄下。當(dāng)前項(xiàng)目構(gòu)建路徑中的類(lèi)庫(kù)如圖2 21所示。

 

 
圖2 21  chapter02_c3p0項(xiàng)目構(gòu)建路徑中的類(lèi)庫(kù)

 

 

 


 

2.10.2  編輯hibernate.cfg.xml文件

當(dāng)前項(xiàng)目使用了C3P0的連接池技術(shù),修改hibernate.cfg.xml文件以配置相應(yīng)的參數(shù),其內(nèi)容如下:

  1. SRC 2 7  hibernate.cfg.xml  
  2. <?xml version='1.0' encoding='UTF-8'?>  
  3. <!DOCTYPE hibernate-configuration PUBLIC  
  4.           "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
  5.           "http://hibernate.sourceforge.net  
  6.           /hibernate-configuration-3.0.dtd">  
  7. <hibernate-configuration>  
  8.     <session-factory>  
  9. <property name="connection.driver_class">oracle.jdbc.driver.  
  10. OracleDriver</property>  
  11. <property name="connection.url">jdbc:oracle:thin:@localhost:  
  12. 1521:ora9</property>  
  13. <property name="dialect">org.hibernate.dialect.  
  14. Oracle9iDialect</property>  
  15. <property name="connection.username">scott</property>  
  16. <property name="connection.password">tiger</property>  
  17. <!-- C3P0 連接池的配置 -->  
  18. <property name="connection.provider_class">  
  19.         org.hibernate.connection.C3P0ConnectionProvider  
  20. </property>  
  21. <property name="hibernate.c3p0.min_size">5</property>  
  22. <property name="hibernate.c3p0.max_size">10</property>  
  23. <property name="hibernate.c3p0.max_statements">50</property>  
  24. <property name="hibernate.c3p0.timeout">3600</property>  
  25. <property name="hibernate.c3p0.idle_test_period">120</property>  
  26. <property name="hibernate.c3p0.acquire_increment">2</property>  
  27. <property name="current_session_context_class">thread</property>  
  28. <property name="show_sql">true</property>  
  29. <property name="format_sql">true</property>  
  30. <mapping resource="com/v512/examples/Guestbook.hbm.xml" />  
  31.     </session-factory>  
  32. </hibernate-configuration> 

 

 

 

2.10.3  chapter02_c3p0項(xiàng)目的運(yùn)行與輸出

chapter02_c3p0項(xiàng)目中,其他文件都不需要修改,運(yùn)行HibernateTest類(lèi)輸出的結(jié)果chapter02_first項(xiàng)目運(yùn)行輸出結(jié)果完全一樣。