Java语言按内存地址来识别或区分同一个类的不同对象,关系数据库表按主键(一般为代理主键)来识别或区分同一个表的不同记录,Hiberante根据对象标识符(OID,还是叫主键吧)来维持Java对象和数据库表中记录的对应关系。
Hibernate常用的三种生成策略:
1、increment
increment表示由Hibernate以递增的方式生成代理主键,例如在下面的Customer.hbm.xml文件中使用increment方式生成主键:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.xieyuyan.Customer" table="CUSTOMERS">
<id name="id" column="ID" type="int">
<generator class="increment"/>
</id>
<property name="name" column="NAME" type="string" not-null="true"/>
</class>
</hibernate-mapping>
运行hbm2ddl工具(通过*.hbm.xml配置文件生成对应的数据库表),查看生成数据表的语句如下:
2、identity
Identity表示由底层数据库来负责生成代理主键,它要求底层数据库把主键定义为自动增长字段类型,如下使用identity方式生成代理主键:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.xieyuyan.Customer" table="CUSTOMERS">
<id name="id" column="ID" type="int">
<generator class="identity"/>
</id>
<property name="name" column="NAME" type="string" not-null="true"/>
</class>
</hibernate-mapping>
运行hbm2ddl工具,查看生成数据表的语句如下:
可以看到ID属性被定义为auto_increment,因为Hibernate使用identity主键生成策略,即由数据库负责生成主键
3、hilo
Hilo表示由Hibernate按照一种high/low算法(高低位算法)来生成主键,它从数据库的特定表中获取high的值,下面采用hilo方式生成Hiberante主键:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.xieyuyan.Customer" table="CUSTOMERS">
<id name="id" column="ID" type="int">
<meta attribute=”scope-set”>private</meta>
<generator class="hilo">
<param name=”table”>hile_value</param> //指定保存hi值的表名
<param name=”column”>next_value</param> //指定保存hi值的列名
<param name=”max_lo”>100</param> //指定低位的最大值
</generator>
</id>
<property name="name" column="NAME" type="string" not-null="true"/>
</class>
</hibernate-mapping>
hilo生成主键的过程如下:
① 获取hi值:读取数据表hile_value中next_hilo的值,数据表中next_hilo的值+1保存
② 获取lo值:从0到max_lo中循环取值,间隔为1,当lo为max_lo时,重新读取hi的值,lo再从0到max_lo中循环取值
③ 计算主键:根据hi * (max_lo + 1) + lo计算生成主键值
注:当hi值是0的时候,那么第一个值不是0*(max_lo+1)+0=0,而是lo跳过0从1开始
4、native
native表示依据底层数据库对自动生成主键的支持能力,来选择使用identity、sequence、hile生成主键,它能自动判断底层数据库提供的生成主键的机制。例如如果使用mysql,就会选择identity生成主键,如果使用oracle,就会使用sequence生成主键,如下所示:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.xieyuyan.Customer" table="CUSTOMERS">
<id name="id" column="ID" type="int">
<meta attribute=”scope-set”>private</meta>
<generator class="native"/>
</id>
<property name="name" column="NAME" type="string" not-null="true"/>
</class>
</hibernate-mapping>
运行hbm2ddl工具,查看创建数据库表的语句为:
这里,笔者使用的是mysql数据库,故底层数据库选择identity生成主键