Hibernate深入浅出(十一)-----读深入浅出hibernate有感
class属性有一下几种类型:
1、Assiged:主键由应用逻辑产生,数据交由Hibernate保存时,主键值已经设置完毕,无需Hibernate干预。
2、hilo:通过hi/lo算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。
3、与hilo类似,通过hi/lo算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适用于支持Sequence的数据库。
4、incremaent:主键按数值顺序递增。此方式的实现机制为在当前应用中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。如果同一数据库有多个实例访问,此方式必须避免使用。
5、identity:采用数据库提供的主键生成机制.
6、sequence:采用数据库提供的sequence机制生成主键
7、native:由Hibernate根据数据库适配器中的定义,自动采用identity、hilo、sequence的其中一种作为主键生成方式。
8、uuid.hex:这种主键生成机制在最大程度上保证了产生ID的唯一性。
9、uuid.string:与uuid.hex类似。
10、foreign:使用外部表的字段作为主键。
由于常用的数据库,如SQLServer、MySql等,都提供了易用的主键生成机制。我们可以在数据库提供的主键生成机制上,采用generator-class=native的主键生成方式。
不过,值得注意的是,一些数据库提供的主键生成机制在效率上未必最佳,大量并发insert数据时可能会引起表之间的互锁。
数据库提供的主键生成机制,往往是通过在一个内部表中保存当前主键状态,之后每次插入数据会读取这个最大值,然后加上递增量作为新记录的主键值,之后再把这个新的最大值更新回内部表中,这样,一次Insert操作可能导致数据库内部多次表读写操作,同时伴随的还有数据的加锁解锁操作,这对性能产生了很大影响。
另外,对于借用Sequence作为主键产生机制的数据库而言,如Oracle,如果采用<generator class="sequence">设定,那么插入一条新的数据之前,Hibernate必须首先向数据库发起一条select sequence操作以获取主键值。
这样,一次保存操作实际上包含了2个过程,首先查询sequence获得主键,其次执行Insert插入记录,无疑操作效率相对较低。
大多数情况下,如果逻辑允许,可以考虑使用uuid.hex主键生成方式。
Hibernate3同时还提供了另一种与实体类型无关的映射方式:动态模型(Dynamic Model),所谓动态模型,即通过通用数据容器(Map)对库表记录进行表达。
<?
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 = " DynamicUserMap " table = " T_User " >
< id name = " id " column = " id " type = " java.lang.Integer " >
< generator class = " native " />
</ id >
< property name = " name " type = " java.lang.String " column = " name " />
< property name = " age " type = " java.lang.Integer " column = " age " />
</ class >
</ hibernate - mapping >
<! 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 = " DynamicUserMap " table = " T_User " >
< id name = " id " column = " id " type = " java.lang.Integer " >
< generator class = " native " />
</ id >
< property name = " name " type = " java.lang.String " column = " name " />
< property name = " age " type = " java.lang.Integer " column = " age " />
</ class >
</ hibernate - mapping >
操作示例:
session
=
sessionFactory.openSession().getSession(EntityMode.MAP);
Map userMap = new HashMap();
userMap.put( " name " , " ken " );
userMap.put( " age " , new Integer( 25 ));
Transaction tx = session.beginTransaction();
session.save( " DynamicUserMap " ,userMap);
tx.commit();
Map userMap = new HashMap();
userMap.put( " name " , " ken " );
userMap.put( " age " , new Integer( 25 ));
Transaction tx = session.beginTransaction();
session.save( " DynamicUserMap " ,userMap);
tx.commit();
首先,我们以EntityMode.MAP模式获取Session实例,以此表明Session操作的对象并非普通的实体类,而是Map类型数据。
其次,在执行实体操作时,须指明要操作的实体名:
session.save("DynamicUserMap",userMap);