混用靜態模型與動態模型


接續 動 態模型(Dynamic Model) 的內容,有時為了設計上的彈性,動態模型也可以與靜態的POJO模型混用,例如預設您會使用POJO,但有時您可能使用Map收集一些資料,然後存入資料表中,或者是用一個POJO來映射多個表格,但有時藉由entity name來指定要取出哪個表格的資料。

要混用靜態模型與動態模型,基本上是同時在HBM上設定name與entity-name屬性,例如:
...
<hibernate-mapping>
    <class name="onlyfun.caterpillar.User"
           entity-name="UserEntity"
           table="T_USER">
    ...
</hibernate-mapping>

如上設定之後,在進行資料儲存時,可以如下進行:
User user = new User();
user.setName("caterpillar");
user.setAge(new Long(30));

Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx= session.beginTransaction();
session.save("UserEntity", user);
tx.commit();
session.close();

特別注意,必須指定entity-name,方可進行儲存,而在查詢資料時,可以如下所示:
Session session = HibernateUtil.getSessionFactory().openSession();
       
List users = session.createQuery("from UserEntity").list();
       
for(int i = 0; i < users.size(); i++) {
    User user = (User) users.get(i);
    System.out.println(user.getName() + "\t" + user.getAge());
}

可以看到,預設是採用POJO來進行儲存,查詢也是以POJO傳回資料,如果現在程式需要以動態模型的方式來進行儲存,則可以如下:
Map user = new HashMap();
user.put("name", "caterpillar");
user.put("age", new Long(30));

Session session = HibernateUtil.getSessionFactory().openSession();

       
Session dynamicSession = session.getSession(EntityMode.MAP);
Transaction tx= dynamicSession.beginTransaction();
dynamicSession.save("UserEntity", user);
tx.commit();
       
session.close();

注意不需要特別關閉使用getSession()方法取得的Session,它會隨著父Session而關閉,如果是查詢資料的話,道理也是相同:
Session session = HibernateUtil.getSessionFactory()
                     .openSession().getSession(EntityMode.MAP);
       
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"));
}
       
session.close();

除了以程式動態改變模型設定之外,您還可以在hibernate.cfg.xml中設定default_entity_mode為dynamic-map,表示全部採用動態模式,不過這會影響整個程式,並不建議使用。
<property name="default_entity_mode">dynamic-map</property>