動態模型(Dynamic Model)


在構造系統原型(Prototype)階段時,由於需求尚未確定,應用程式模型中的Java物件會有相當大的變動,在Hibernate 3中引入了動態模式,可以使用物件容器充當Java物件,在構造系統原型時靈活變化,而不必實際定義Java物件。

假設您建立了以下的表格:
create table T_USER (
    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();

            
Map容器的key用來表示屬性名稱,而value用來表示儲存之物件,它們將對應至資料表中的欄位與值,上面的程式片段儲存資料後,資料表內容如下:
mysql> select * from user;
+----+-------------+------+
| 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();

如果查詢出來代表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"));
}

Hibernate 3引入動態模型的目的,在於更靈活的構造原型系統,在系統架構與物件模式確定之後,仍是要設計專用的Java物件,以獲得編譯時期的型態檢查等好處。