撰寫本文的時候,Hibernate最新的版本是3.1,請連接至 Hibernate的官方網站 進行檔案的下載。
下載zip檔案並解壓縮之後,在解開的目錄下就有Hibernate3.jar,這是Hibernate 3所需要的API之封裝,可以在doc目錄中找到API說明或相關參考文件,在lib 目錄中的則是您可能會用到的相依檔案。
對於將撰寫的第一個Hibernate程式,所需要的.jar檔案除了hibernate3.jar之外,您還需要:
- antlr-2.7.6rc1.jar
- asm.jar
- cglib-2.1.3.jar
- commons-collections-2.1.1.jar
- commons-logging-1.0.4.jar
- dom4j-1.6.1.jar、ehcache-1.1.jar
- jta.jar
- log4j-1.2.11.jar
Hibernate在底層仍是使用JDBC,所以您也必須要有JDBC的驅動程式的jar檔案。
接來撰寫個專案,示範一下Hibernate的功能與使用方式,在這個示範中暫時不使用到Spring的功能,稍後會再來改寫它,以了解Spring與
Hibernate整合之後的方便性。同樣的,先設計一個User類別,這個User類別將對應至demo資料庫中的一個user表格:
package onlyfun.caterpillar;
public class User { private Integer id; private String name; private Integer age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
User類別必須有一個id屬性,用來作為物件於程式中唯一性的識別,這個id值可以由Hibernate為您產生。
在這邊使用的MySQL資料庫,表格建立時是使用以下的SQL:
CREATE TABLE user (
id INT(11) NOT NULL auto_increment PRIMARY KEY,
name VARCHAR(100) NOT NULL default '',
age INT
) TYPE = InnoDB;
User類別與user表格之間要建立對映關係,實際上是靠一個映射文件來完成,映射文件可以使用XML來撰寫,通當命名為.hbm.xml,例如設計一個User.hbm.xml映射文件:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/ → hibernate-mapping-3.0.dtd">
<hibernate-mapping> <class name="onlyfun.caterpillar.User" table="user">
<id name="id" column="id"> <generator class="native"/> </id>
<property name="name" column="name"/>
<property name="age" column="age"/>
</class> </hibernate-mapping>
在映射文件中,<class>標籤用來定義類別與表格的對映,"name"屬性用來設定類別名稱,"table"屬性用來設定表格名稱;
<id>標籤中"name"屬性用來設定物件的唯一性識別id,通常對應至資料表中的主鍵欄位,也就是"column"屬性所設定的對應欄
位;<generator>的"class"用來設定主鍵的產生方式,設定為"native"表示依資料庫自己的主鍵生成方式來生成主鍵值,
例如我的user表格在建立時,主鍵設定為auto_increment,所以會每加入一筆資料後都自動遞增主鍵值。
接下來的<property>標籤則設定User物件的每一個屬性(由"name"屬性設定),分別對應至資料庫中user表格的哪一個欄位(由"column"屬性設定)。
接著同樣的,設計一個IUserDAO介面,讓應用程式在存取資料庫時,依賴於抽象的介面而非實際的類別實作,如下所示:
package onlyfun.caterpillar;
public interface IUserDAO { public void insert(User user); public User find(Integer id); }
然後由UserDAO類別來實作IUserDAO介面,這次實作時使用Hibernate的API,需要注入一個org.hibernate.SessionFactory物件:
package onlyfun.caterpillar;
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction;
public class UserDAO implements IUserDAO { private SessionFactory sessionFactory; public UserDAO() { } public UserDAO(SessionFactory sessionFactory) { this.setSessionFactory(sessionFactory); } public void setSessionFactory( SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public void insert(User user) { // 取得Session Session session = sessionFactory.openSession(); // 開啟交易 Transaction tx= session.beginTransaction(); // 直接儲存物件 session.save(user); // 送出交易 tx.commit(); session.close(); }
public User find(Integer id) { Session session = sessionFactory.openSession(); User user = (User) session.get(User.class, id); session.close(); return user; } }
在Hibernate中,SessionFactory是用來管理org.hibernate.Session,Session的作用類似於JDBC中
Connection的作用,在Hibernate中每次進行資料存取之前都必須開啟Session,在進行資料變更或儲存時,則必須開啟交易,在儲存資
料的時候,您可以使用Session的save()方法直接將物件儲存,在org.hibernate.Transaction執行commit()方法
之後,Hibernate會根據映射文件,將物件中的各個屬性資料轉換並儲存至user表格中對應的欄位。
在不使用資料庫連線的時候,要記得使用close()方法關閉Session,關閉Session並不等於關閉Connection,在
Hibernate中如果您有使用連接池(Connection
pool),在Session的close()方法執行完畢後,會將Connection置回連接池之中,而不是直接關閉。
而在UserDAO的find()方法實作中,您可以直接使用Session的get()方法,指定資料的id值與要封裝資料的類別型態,接著查詢回來的物件中就包括了相對應的資料,將之轉換回User型態,您就可以操作User物件上各種方法來取得資料。
在使用Hibernate時,還必須定義一個設定檔,告知資料庫名稱、使用者名稱、密碼、映射文件位置等,可以使用XML檔案來定義,檔名為hibernate.cfg.xml,如下所示:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/ → hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="show_sql"> true </property>
<property name="dialect"> org.hibernate.dialect.MySQLDialect </property>
<property name="connection.driver_class"> com.mysql.jdbc.Driver </property>
<property name="connection.url"> jdbc:mysql://localhost/demo </property>
<property name="connection.username"> caterpillar </property>
<property name="connection.password"> 123456 </property>
<!-- 以下設置物件與資料庫表格映射文件 --> <mapping resource="onlyfun/caterpillar/User.hbm.xml"/> </session-factory> </hibernate-configuration>
在<session-factory>的設定中,"show_sql"被設定為true,表示在執行資料庫存取動作時顯示Hibernate
所生成、使用的SQL語法;Hibernate可以使用許多不同的資料庫,不同的資料庫在SQL或操作上會有所差別,可以設定"dialect"來表示將
使用哪一種資料庫適用的語句操作,由於這邊所使用的是MySQL資料庫,所以設定為
org.hibernate.dialect.MySQLDialect;接著來的"connection.driver_class"、
"connection.url"、"connection.username"、"connection.password"分別用以設定JDBC驅動
程式類別、URL、使用者名稱與密碼。
在<mapping>中的"resource"設定的是物件與資料庫表格的映射文件位置,在上面的設定為
onlyfun/caterpillar/User.hbm.xml,表示檔案在Classpath路徑下的onlyfun資料夾的
caterpillar資料夾下,通常hbm.xml建議與對應的Java類別放置在一起。
接著就是建立org.hibernate.cfg.Configuration物件來讀取設定檔,它是hibernate.cfg.xml中相關設定的具
體代表物件,Configuration物件建立之後就不會變動,如果您修改了設定檔案的內容,則必須另外再產生新的Configuration物件,新
的變更才會被再次讀取。
直接來看一個簡單的程式,了解如何使用以上設計的程式進行資料的儲存與查詢:
package onlyfun.caterpillar;
import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration;
public class HibernateDemo { public static void main(String[] args) { // Configuration 負責管理 Hibernate 配置訊息 Configuration config = new Configuration().configure(); // 根據 config 建立 SessionFactory // SessionFactory 將用於建立 Session SessionFactory sessionFactory = config.buildSessionFactory(); // 建立DAO物件 IUserDAO userDAO = new UserDAO(sessionFactory); User user = new User(); user.setName("caterpillar"); user.setAge(new Integer(30)); userDAO.insert(user); user = userDAO.find(new Integer(1)); System.out.println("name: " + user.getName()); } }
在建立Configuration物件之後,就可以使用它當中所包括的資訊來建立SessionFactory物件,接著在建立UserDAO時將SessionFactory的實例指定給它,然後您就可以操作UserDAO物件來進行資料的儲存了。
有關於Hibernate更詳盡的介紹,可以參考 Hibernate。
|