4.4. 动态模型(Dynamic models)
注意,以下特性在当前处于试验阶段,将来可能会有变化。
运行期的持久化实体没有必要一定表示为像POJO类或JavaBean对象那样的形式。Hibernate也支持动态模型 (在运行期使用Map
的Map
)和象DOM4J的树模型那 样的实体表示。使用这种方法,你不用写持久化类,只写映射文件就行了。
Hibernate默认工作在普通POJO模式。你可以使用配置选项default_entity_mode
, 对特定的SessionFactory
,设置一个默认的实体表示模式。 (参见表 3.3 “ Hibernate配置属性 ”。)
下面是用Map
来表示的例子。首先,在映射文件中,要声明 entity-name
来代替一个类名(或作为一种附属)。
<hibernate-mapping>
<class entity-name="Customer">
<id name="id"
type="long"
column="ID">
<generator class="sequence"/>
</id>
<property name="name"
column="NAME"
type="string"/>
<property name="address"
column="ADDRESS"
type="string"/>
<many-to-one name="organization"
column="ORGANIZATION_ID"
class="Organization"/>
<bag name="orders"
inverse="true"
lazy="false"
cascade="all">
<key column="CUSTOMER_ID"/>
<one-to-many class="Order"/>
</bag>
</class>
</hibernate-mapping>
注意,虽然是用目标类名来声明关联的,但是关联的目标类型除了是POJO之外,也可以 是一个动态的实体。
在使用dynamic-map
为SessionFactory
设置了默认的实体模式之后,可以在运行期使用Map
的 Map
。
Session s = openSession();
Transaction tx = s.beginTransaction();
Session s = openSession();
// Create a customer
Map david = new HashMap();
david.put("name", "David");
// Create an organization
Map foobar = new HashMap();
foobar.put("name", "Foobar Inc.");
// Link both
david.put("organization", foobar);
// Save both
s.save("Customer", david);
s.save("Organization", foobar);
tx.commit();
s.close();
动态映射的好处是,变化所需要的时间少了,因为原型不需要实现实体类。然而,你无法进行 编译期的类型检查,并可能由此会处理很多的运行期异常。幸亏有了Hibernate映射,它使得数 据库的schema能容易的规格化和合理化,并允许稍后在此之上添加合适的领域模型实现。
实体表示模式也能在每个Session
的基础上设置:
Session dynamicSession = pojoSession.getSession(EntityMode.MAP);
// Create a customer
Map david = new HashMap();
david.put("name", "David");
dynamicSession.save("Customer", david);
...
dynamicSession.flush();
dynamicSession.close()
...
// Continue on pojoSession
请注意,用EntityMode
调用getSession()
是在 Session
的API中,而不是SessionFactory
。 这样,新的Session
共享底层的JDBC连接,事务,和其他的上下文信 息。这意味着,你不需要在第二个Session
中调用 flush()
和close()
,同样的,把事务和连接的处理 交给原来的工作单元。
关于XML表示能力的更多信息可以在第 18 章 XML映射中找到。