Hibernate 配置详解(6)

hibernate.default_entity_mode:

用于设置hibernate默认情况下实体对象的类型。可以选择org.hibernate.EntityMode枚举中的可选值,即pojodynamic-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,怎么通过mapgetput方法设置值等。

常用的Tuplizer有两类,EntityTuplizerComponentTuplizer,前者用于实体结构的映射,后者用于组件结构的映射,内建的EntityTuplizerComponentTuplizer都分为PojoDynamicMap两类,对于组件类型来说,在类中使用<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类全限定名即可。



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值