這邊以一個簡單的單機程式來示範Hibernate的配置與功能,首先作資料庫的準備工作,在MySQL中新增一個demo資料庫,並建立user表格:
id bigint not null auto_increment,
name varchar(255),
age bigint,
primary key (id)
)
對於這個表格,您有一個User類別與之對應,表格中的每一個欄位將對應至User實例上的Field成員。
- User.java
package onlyfun.caterpillar; public class User { private Long id; private String name; private Long age; // 必須要有一個預設的建構方法 // 以使得Hibernate可以使用Constructor.newInstance()建立物件 public User() { } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getAge() { return age; } public void setAge(Long age) { this.age = age; } }
其中id是個特殊的屬性,Hibernate會使用它來作為主鍵識別,您可以定義主鍵產生的方式,這是在XML映射文件中完成,為了告訴 Hibernate您所定義的User實例如何映射至資料庫表格,您撰寫一個XML映射文件檔名是User.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="T_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>中 column屬性指定了表格欄位,而 type屬性指定了User實例的中的id之型態。<id>中主鍵的產生方式在這邊設定為"native",表示主鍵的生成方式由Hibernate根據資料庫Dialect 的定義來決定,之後還會介紹其它主鍵的生成方式。
同樣的,<property>標籤中的column與type都各自指明了表格中欄位與物件中屬性的對應。
建議將映射文件與編譯出來的User.class放在同一個資料夾之中。
接著必須在Hibernate配置文件hibernate.cfg.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>
....
<!-- 物件與資料庫表格映射文件 -->
<mapping resource="onlyfun/caterpillar/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
在使用Hibernate之前,必須先讀入hibernate.cfg.xml文件訊息,配置文件訊息在 Hibernate中對應的代表物件是Configuration物件,當中包括了配置文件訊息,您可以從Configuration中建立 SessionFactory物件,顧名思義,SessionFactory是用來建立Session物件,其作用類似於JDBC中的 Connection物件,不過負責更多關於一次資料庫操作會話的功能。
一個應用程式當中通常只需要一個SessionFactory實例,為了方便整個應用取得同一個SessionFactory實例,可以撰寫一個HibernateUtil類別:
- HibernateUtil.java
package onlyfun.caterpillar; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static SessionFactory sessionFactory; static { try { sessionFactory = new Configuration().configure() .buildSessionFactory(); } catch (Throwable ex) { throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } public static void shutdown() { getSessionFactory().close(); } }
HibernateUtil類別在載入JVM後就會新建Configuration、讀入hibernate.cfg.xml,而後建立SessionFactory實例,您可以藉由其所提供的兩個static方法來取得SessionFactory物件。
接下來撰寫一個測試的程式,這個程式直接以Java程式設計人員熟悉的語法方式來操作物件,而實際上也直接完成對資料庫的操作,程式將會將一筆資料存入表 格之中:
- HibernateDemo.java
package onlyfun.caterpillar; import org.hibernate.Session; import org.hibernate.Transaction; public class HibernateDemo { public static void main(String[] args) { User user = new User(); user.setName("caterpillar"); user.setAge(new Long(30)); // 開啟Session,相當於開啟JDBC的Connection Session session = HibernateUtil.getSessionFactory().openSession(); // Transaction表示一組會話操作 Transaction tx= session.beginTransaction(); // 將物件映射至資料庫表格中儲存 session.save(user); tx.commit(); session.close(); System.out.println("新增資料OK!請先用MySQL觀看結果!"); HibernateUtil.shutdown(); } }
如您所看到的,程式中只需要直接操作User物件,並進行Session與Transaction的相關操作,Hibernate就會自動完成對資料庫的 操作,您看不到任何一行JDBC或SQL的陳述。
接著可以開始運行程式,結果如下:
Hibernate:
insert
into
T_USER
(name, age)
values
(?, ?)
新增資料OK!請先用MySQL觀看結果!
執行結果中顯示了Hibernate所實際使用的SQL,由於這個程式還沒有查詢功能,所以要進入MySQL中看看新增的資料,如下:
mysql> SELECT * FROM T_USER; +----+-------------+------+ | id | name | age | +----+-------------+------+ | 1 | caterpillar | 30 | +----+-------------+------+ 1 row in set (0.03 sec) |