在構造系統原型(Prototype)階段時,由於需求尚未確定,應用程式模型中的Java物件會有相當大的變動,在Hibernate 3中引入了動態模式,可以使用物件容器充當Java物件,在構造系統原型時靈活變化,而不必實際定義Java物件。
假設您建立了以下的表格:
create table T_USER (
id bigint not null auto_increment,
name varchar(255),
age bigint,
primary key (id)
)
id bigint not null auto_increment,
name varchar(255),
age bigint,
primary key (id)
)
使用動態模式來作映射時,無需定義Java物件,直接在映射文件的<class>標籤上使用entity-name屬性:
- 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 entity-name="UserEntity"
table="T_USER">
<id name="id" column="id" type="long">
<generator class="native"/>
</id>
<property name="name"
column="name"
type="string"/>
<property name="age"
column="age"
type="long"/>
</class>
</hibernate-mapping>
entity-name屬性設定的名稱將在儲存或載入時使用,例如可以如下儲存資料:
Map user = new HashMap();
user.put("name", "caterpillar");
user.put("age", new Long(30));
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx= session.beginTransaction();
session.save("UserEntity", user);
tx.commit();
session.close();
user.put("name", "caterpillar");
user.put("age", new Long(30));
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx= session.beginTransaction();
session.save("UserEntity", user);
tx.commit();
session.close();
Map容器的key用來表示屬性名稱,而value用來表示儲存之物件,它們將對應至資料表中的欄位與值,上面的程式片段儲存資料後,資料表內容如下:
mysql> select *
from user;
+----+-------------+------+
| id | name | age |
+----+-------------+------+
| 1 | caterpillar | 30 |
+----+-------------+------+
1 row in set (0.00 sec)
+----+-------------+------+
| id | name | age |
+----+-------------+------+
| 1 | caterpillar | 30 |
+----+-------------+------+
1 row in set (0.00 sec)
如果要載入資料,則一個範例如下所示:
Session session = HibernateUtil.getSessionFactory().openSession();
Map userMap = (Map) session.load("UserEntity", new Long(1));
System.out.println(userMap.get("name") + "\t" + userMap.get("age"));
session.close();
Map userMap = (Map) session.load("UserEntity", new Long(1));
System.out.println(userMap.get("name") + "\t" + userMap.get("age"));
session.close();
如果查詢出來代表T_USER的Map物件中有了屬性的相對應修改,如果是在開啟Transaction的情況下,在Transaction commit之後,Map中的變更也會反應至表格。
使用HQL查詢的話,查詢的對象可以指定entity-name的名稱,一個例子如下:
List users = session.createQuery("from UserEntity").list();
for(int i = 0; i < users.size(); i++) {
Map user = (Map) users.get(i);
System.out.println(user.get("name") + "\t" + user.get("age"));
}
for(int i = 0; i < users.size(); i++) {
Map user = (Map) users.get(i);
System.out.println(user.get("name") + "\t" + user.get("age"));
}
Hibernate 3引入動態模型的目的,在於更靈活的構造原型系統,在系統架構與物件模式確定之後,仍是要設計專用的Java物件,以獲得編譯時期的型態檢查等好處。