hibernate.default_entity_mode:
用于设置hibernate默认情况下实体对象的类型。可以选择org.hibernate.EntityMode枚举中的可选值,即pojo和dynamic-map,一般默认选择pojo即可。这个选项在hibernate4.2版本之后没有直接的用处了,但是还是需要简单了解一下这个选项中两种模式的含义。一种是pojo,简单说就是我们经常用到的Java实体类,这也是我们最常用到的,而dynamic-map指的是hibernate提供的动态模型的映射,即将Map作为映射对象,下面是一个dynamic-map的映射小例子:
<hibernate-mapping>
<class entity-name="cd.itcast.dynamic.Department">
<id name="id" column="id" type="java.lang.Long">
<generator class="native" />
</id>
<property name="name" column="name" type="string" />
<property name="sn" column="sn" type="string" />
</class>
</hibernate-mapping>
那么在使用这个映射的时候,只需要使用entity-name+Map就可以了。注意一下的是OID和属性的映射必须添加type指定类型,否则会报错:
Caused by: org.hibernate.MappingException: you must specify types for a dynamic entity: name
at org.hibernate.mapping.SimpleValue.setTypeUsingReflection(SimpleValue.java:322)
.. 29 more
在使用的时候,只需要在对应方法save,update,delete上再加上动态模型的名字即可:
public void testSave(){
Map<String,Object> m=new HashMap<String,Object>();
m.put("name", "itcast");
m.put("sn", "001");
Session session=sf.openSession();
session.beginTransaction();
session.save("cd.itcast.dynamic.Department",m);
session.getTransaction().commit();
session.close();
}
public void testGet(){
Session session=sf.openSession();
Map dept=(Map)session.get("cd.itcast.dynamic.Department", 1L);
session.close();
}
public void testDelete(){
Session session=sf.openSession();
session.beginTransaction();
Map<String,Object> dept=new HashMap<String,Object>();
dept.put("id", 1L);
session.delete("cd.itcast.dynamic.Department", dept);
session.getTransaction().commit();
session.close();
}
另外,动态模型映射还可以使用在组件上:
<class entity-name="cd.itcast.dynamic.Department">
<id name="id" column="id" type="java.lang.Long">
<generator class="native" />
</id>
<property name="name" column="name" type="string" />
<property name="sn" column="sn" type="string" />
<dynamic-component name="address">
<property name="city" type="string" />
<property name="province" type="string" />
</dynamic-component>
</class>
使用也很简单,也是直接把Map作为组件对象即可:
public void testSave(){
Map<String,Object> m=new HashMap<String,Object>();
m.put("name", "itcast");
m.put("sn", "001");
Map<String,String> address=new HashMap<String,String>();
address.put("city", "成都");
address.put("province", "四川");
m.put("address", address);
Session session=sf.openSession();
session.beginTransaction();
session.save("cd.itcast.dynamic.Department",m);
session.getTransaction().commit();
session.close();
}
动态模型的使用是恨简单的,他有一个最大的好处就是因为使用的是Map作为实体的承载者,不需要具体的POJO,所以当需求变化时,只需要修改映射文件即可。所以,当项目前期,做DEMO时,使用动态模型映射是非常简单和方便修改的,但是使用Map,没有属性的强制命名,没有类型的检查等,所以,当项目稳定时,还是需要用POJO。在Hibernate4.2文档中已经提到,这个功能之后是可能被移除的(The following features are currently considered experimental and may change in the near future)
主要下面要看一下org.hibernate.tuple.Tuplizer,这个类才是真正隐藏在entity-mode后面的东东。Tuplizer简单理解为规定了怎么把数据库中的数据放到特定的结构中。比如,如果是普通的POJO,那么对应的PojoEntityTuplizer就会知道怎么实例化一个POJO对象,怎么通过getter/setter设置值等,如果是dynamic-map,对应的DynamicMapEntityTuplizer就会知道怎么实例化一个Map,怎么通过map的get和put方法设置值等。
常用的Tuplizer有两类,EntityTuplizer和ComponentTuplizer,前者用于实体结构的映射,后者用于组件结构的映射,内建的EntityTuplizer和ComponentTuplizer都分为Pojo和DynamicMap两类,对于组件类型来说,在类中使用<component>元素,就相当于规定了使用PojoComponentTuplizer,在类中使用<dynamic-component>元素,就相当于规定使用DynamicComponentTuplizer。而对于实体类来说,除了使用<class name=””>来规定使用PojoEntityTuplizer,使用<class entity-name=””>规定使用DynamicMapEntityTuplizer之外,还可以在<class>元素内使用<tuplizer>元素来自定义使用的Tuplizer:
<class entity-name="cd.itcast.dynamic.Department">
<tuplizer class="org.hibernate.tuple.entity.DynamicMapEntityTuplizer"/>
<!--省略-->
</class>
有了这个机制,我们就可以通过实现Tuplizer接口或者EntityTuplizer,或者继承AbstractEntityTuplizer来完成我们自定的Tuplizer,只需要在<tuplizer class=””>中配置自定义的Tuplizer类全限定名即可。