HIbernate如何设置java自定义主键生成器器

温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
&&& 注释方式
&& @GeneratedValue(generator = "ud")
&& @GenericGenerator(name = "ud", strategy = "assigned")
&&& “ud”是自定义的策略名,人为起的名字,后面均用“ud”表示。
&&& 特点:可以跨数据库,人为控制主键生成,应尽量避免。
、increment
由Hibernate从数据库中取出主键的最大值(每个session只取1次),以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的数据库,因此可以跨数据库。
&& &id name="id" column="id"&
&&&&& &generator class="increment" /&
Hibernate调用org.hibernate.id.IncrementGenerator类里面的generate()方法,使用select max(idColumnName) from tableName语句获取主键最大值。该方法被声明成了synchronized,所以在一个独立的Java虚拟机内部是没有问题的,然而,在多个JVM同时并发访问数据库select max时就可能取出相同的值,再insert就会发生Dumplicate entry的错误。所以只能有一个Hibernate应用进程访问数据库,否则就可能产生主键冲突,所以不适合多进程并发更新数据库,适合单一进程访问数据库,不能用于群集环境。
官方文档:只有在没有其他进程往同一张表中插入数据时才能使用,在集群下不要使用。
&&& 注释方式
&& @GeneratedValue(generator = "ud")
&& @GenericGenerator(name = "ud", strategy = "increment")
&&& 特点:跨数据库,不适合多进程并发更新数据库,适合单一进程访问数据库,不能用于群集环境。
hilo(高低位方式high low)是hibernate中最常用的一种生成方式,需要一张额外的表保存hi的值。保存hi值的表至少有一条记录(只与第一条记录有关),否则会出现错误。可以跨数据库。
&& &id name="id" column="id"&
&&&&& &generator class="hilo"&
&&&&&&&& &param name="table"&hibernate_hilo&/param&
&&&&&&&& &param name="column"&next_hi&/param&
&&&&&&&& &param name="max_lo"&100&/param&
&&&&& &/generator&
&param name="table"&hibernate_hilo&/param&& 指定保存hi值的表名
&param name="column"&next_hi&/param&&&&&&&& 指定保存hi值的列名
&param name="max_lo"&100&/param&& &&&&&&&& 指定低位的最大值
也可以省略table和column配置,其默认的表为hibernate_unique_key,列为next_hi
&& &id name="id" column="id"&
&&&&& &generator class="hilo"&
&&&&&&&& &param name="max_lo"&100&/param&
&&&&& &/generator&
hilo生成器生成主键的过程(以hibernate_unique_key表,next_hi列为例):
1. 获得hi值:读取并记录数据库的hibernate_unique_key表中next_hi字段的值,数据库中此字段值加1保存。
2. 获得lo值:从0到max_lo循环取值,差值为1,当值为max_lo值时,重新获取hi值,然后lo值继续从0到max_lo循环。
&&& 3. 根据公式 hi * (max_lo + 1) + lo计算生成主键值。
注意:当hi值是0的时候,那么第一个值不是0*(max_lo+1)+0=0,而是lo跳过0从1开始,直接是1、2、3……
那max_lo配置多大合适呢?
这要根据具体情况而定,如果系统一般不重启,而且需要用此表建立大量的主键,可以吧max_lo配置大一点,这样可以减少读取数据表的次数,提高效率;反之,如果服务器经常重启,可以吧max_lo配置小一点,可以避免每次重启主键之间的间隔太大,造成主键值主键不连贯。
&&& 注释方式
&& @GeneratedValue(generator = "ud")
&& @GenericGenerator(name = "ud", strategy = "hilo", parameters = {
&&&&&&&& @Parameter(name = "table", value = "hibernate_hilo"),
&&&&&&&& @Parameter(name = "column", value = "next_hi"),
&&&&&&&& @Parameter(name = "max_lo", value = "100")})
&&& 特点:跨数据库,hilo算法生成的标志只能在一个数据库中保证唯一。
与hilo类似,通过hi/lo算法实现的主键生成机制,只是将hilo中的数据表换成了序列sequence,需要数据库中先创建sequence,适用于支持sequence的数据库,如oracle。
&& &id name="id" column="id"&
&&&&& &generator class="seqhilo"&
&&&&&&&& &param name="sequence"&hibernate_seq&/param&
&&&&&&&& &param name="max_lo"&100&/param&
&&&&& &/generator&
&&& 注释方式
&& @GeneratedValue(generator = "ud")
&& @GenericGenerator(name = "ud", strategy = "seqhilo", parameters = {
&&&&&&&& @Parameter(name = "sequence", value = "hibernate_hilo"),
&&&&&&&& @Parameter(name = "max_lo", value = "100") })
特点:与hilo类似,只能在支持序列的数据库中使用。
、sequence
采用数据库提供的sequence机制生成主键,需要数据库支持sequence。如oralce、DB、SAP DB、PostgerSQL、McKoi中的sequence。MySQL这种不支持sequence的数据库则不行(可以使用identity)。
&&& &generator class="sequence"&
&&&&&& &param name="sequence"&hibernate_id&/param&
&&& &/generator&
&param name="sequence"&hibernate_id&/param&&&&&& 指定sequence的名称
Hibernate生成主键时,查找sequence并赋给主键值,主键值由数据库生成,Hibernate不负责维护,使用时必须先创建一个sequence,如果不指定sequence名称,则使用Hibernate默认的sequence,名称为hibernate_sequence,前提要在数据库中创建该sequence。
&&& 注释方式
&& @GeneratedValue(generator = "ud")
&& @GenericGenerator(name = "ud", strategy = "sequence",
&&&&&&&& parameters = { @Parameter(name = "sequence",
&&&&&&&&&&&&&&&&&& value = "hibernate_seq") })
&&& 特点:只能在支持序列的数据库中使用,如Oracle。
、identity
identity由底层数据库生成标识符。identity是由数据库自己生成的,但这个主键必须设置为自增长,使用identity的前提条件是底层数据库支持自动增长字段类型,如DB2、SQL Server、MySQL、Sybase和HypersonicSQL等,Oracle这类没有自增字段的则不支持。
&&& &id name="id" column="id"&
&&&&&& &generator class="identity" /&
例:如果使用MySQL数据库,则主键字段必须设置成auto_increment。
id int(11) primary key auto_increment
&&& 注释方式
&& @GeneratedValue(generator = "ud")
&& @GenericGenerator(name = "ud", strategy = "identity")
&&& 特点:只能用在支持自动增长的字段数据库中使用,如MySQL。
native由hibernate根据使用的数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式,灵活性很强。如果能支持identity则使用identity,如果支持sequence则使用sequence。
&& &id name="id" column="id"&
&&&&& &generator class="native" /&
例如MySQL使用identity,Oracle使用sequence
注意:如果Hibernate自动选择sequence或者hilo,则所有的表的主键都会从Hibernate默认的sequence或hilo表中取。并且,有的数据库对于默认情况主键生成测试的支持,效率并不是很高。
使用sequence或hilo时,可以加入参数,指定sequence名称或hi值表名称等,如
&param name="sequence"&hibernate_id&/param&
&&& 注释方式
&& @GeneratedValue(generator = "ud")
&& @GenericGenerator(name = "ud", strategy = "native")
特点:根据数据库自动选择,项目中如果用到多个数据库时,可以使用这种方式,使用时需要设置表的自增字段或建立序列,建立表等。
UUID:Universally Unique Identifier,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字,标准的UUID格式为:
xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx (8-4-4-4-12)
其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。
&& &id name="id" column="id"&
&&&&& &generator class="uuid" /&
Hibernate在保存对象时,生成一个UUID字符串作为主键,保证了唯一性,但其并无任何业务逻辑意义,只能作为主键,唯一缺点长度较大,32位(Hibernate将UUID中间的“-”删除了)的字符串,占用存储空间大,但是有两个很重要的优点,Hibernate在维护主键时,不用去数据库查询,从而提高效率,而且它是跨数据库的,以后切换数据库极其方便。
&&& 注释方式
&& @GeneratedValue(generator = "ud")
&& @GenericGenerator(name = "ud", strategy = "uuid")
&&& 特点:uuid长度大,占用空间大,跨数据库,不用访问数据库就生成主键值,所以效率高且能保证唯一性,移植非常方便,推荐使用。
GUID:Globally Unique Identifier全球唯一标识符,也称作 UUID,是一个128位长的数字,用16进制表示。算法的核心思想是结合机器的网卡、当地时间、一个随即数来生成GUID。从理论上讲,如果一台机器每秒产生个GUID,则可以保证(概率意义上)3240年不重复。
&& &id name="id" column="id"&
&&&&& &generator class="guid" /&
Hibernate在维护主键时,先查询数据库,获得一个uuid字符串,该字符串就是主键值,该值唯一,缺点长度较大,支持数据库有限,优点同uuid,跨数据库,但是仍然需要访问数据库。
注意:长度因数据库不同而不同
MySQL中使用select uuid()语句获得的为36位(包含标准格式的“-”)
Oracle中,使用select rawtohex(sys_guid()) from dual语句获得的为32位(不包含“-”)
&&& 注释方式
&& @GeneratedValue(generator = "ud")
&& @GenericGenerator(name = "ud", strategy = "guid")
&&& 特点:需要数据库支持查询uuid,生成时需要查询数据库,效率没有uuid高,推荐使用uuid。
使用另外一个相关联的对象的主键作为该对象主键。主要用于一对一关系中。
&& &id name="id" column="id"&
&&&&& &generator class="foreign"&
&&&&&&&& &param name="property"&user&/param&
&&&&& &/generator&
&& &one-to-one name="user" class="domain.User" constrained="true" /&
&&& 该例使用domain.User的主键作为本类映射的主键。
&&& 注释方式
&& @GeneratedValue(generator = "ud")
&& @GenericGenerator(name = "ud", strategy = "foreign",
&&&&&&&& parameters = { @Parameter(name = "property", value = "user") })
&&& @OneToOne
&& @PrimaryKeyJoinColumn
&&& 特点:很少使用,大多用在一对一关系中。
&&& 使用触发器生成主键,主要用于早期的数据库主键生成机制,能用到的地方非常少。
、其他注释方式配置
&&& 注释方式与配置文件底层实现方式相同,只是配置的方式换成了注释方式
&&& 自动增长,适用于支持自增字段的数据库
&& @GeneratedValue(strategy = GenerationType.IDENTITY)
&&& 根据底层数据库自动选择方式,需要底层数据库的设置
如MySQL,会使用自增字段,需要将主键设置成auto_increment。
&& @GeneratedValue(strategy = GenerationType.AUTO)
&&& 使用表存储生成的主键,可以跨数据库。
每次需要主键值时,查询名为"hibernate_table"的表,查找主键列"gen_pk"值为"2"记录,得到这条记录的"gen_val"值,根据这个值,和allocationSize的值生成主键值。
&& @GeneratedValue(strategy = GenerationType.TABLE, generator = "ud")
&& @TableGenerator(name = "ud",
&&&&&&&& table = "hibernate_table",
&&&&&&&& pkColumnName = "gen_pk",
&&&&&&&& pkColumnValue = "2",
&&&&&&&& valueColumnName = "gen_val",
&&&&&&&& initialValue = 2,
&&&&&&&& allocationSize = 5)
&&&&&& 使用序列存储主键值
&& @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ud")
&& @SequenceGenerator(name = "ud",
&&&&&&&& sequenceName = "hibernate_seq",
&&&&&&&& allocationSize = 1,
&&&&&&&& initialValue = 2)
&&& 1、为了保证对象标识符的唯一性与不可变性,应该让Hibernate来为主键赋值,而不是程序。
&&& 2、正常使用Hibernate维护主键,最好将主键的setter方法设置成private,从而避免人为或程序修改主键,而使用assigned方式,就不能用private,否则无法给主键赋值。
&&& 2、Hibernate中唯一一种最简单通用的主键生成器就是uuid。虽然是个32位难读的长字符串,但是它没有跨数据库的问题,将来切换数据库极其简单方便,推荐使用!
&&& 3、自动增长字段类型与序列
&&& 4、关于hilo机制注意:
&&& hilo算法生成的标志只能在一个数据库中保证唯一。
当用户为Hibernate自行提供连接,或者Hibernate通过JTA,从应用服务器的数据源获取数据库连接时,无法使用hilo,因为这不能保证hilo单独在新的数据库连接的事务中访问hi值表,这种情况,如果数据库支持序列,可以使用seqhilo。
&&& 5、使用identity、native、GenerationType.AUTO等方式生成主键时,只要用到自增字段,数据库表的字段必须设置成自动增加的,否则出错。
&&& 6、还有一些方法未列出来,例如uuid.hex,sequence-identity等,这些方法不是很常用,且已被其他方法代替,如uuid.hex,官方文档里建议不使用,而直接使用uuid方法。
&&& 7、Hibernate的各版本主键生成策略配置有略微差别,但实现基本相同。如,有的版本默认sequence不指定序列名,则使用名为hibernate_sequence的序列,有的版本则必须指定序列名。
&&& 8、还可以自定义主键生成策略,这里暂时不讨论,只讨论官方自带生成策略。
阅读(2990)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'Hibernate各种主键生成策略与配置详解(转)',
blogAbstract:'Hibernate各种主键生成策略与配置详解(转)
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}hibernate 自动生成主键方式,怎么在手动给主键赋值?
[问题点数:50分,结帖人79bo]
hibernate 自动生成主键方式,怎么在手动给主键赋值?
[问题点数:50分,结帖人79bo]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
匿名用户不能发表回复!|&& &文章主题:
交流经验:
总积分:100
级别:普通会员
hibernate自定义主键生成器 hibernate3 hibernate 自定义主键生成器
hibernate可以自定义主键,自定义的主键策略可以指定实现类,保存时自动调用自定义的类来获取主键,前提是自定义的类要实现IdentifierGenerator接口。
另外,看网上许多人的做法,还要实现Configurable接口的configure方法,其实该方法就是获取hbm.xml对应的数据库的相关信息(表名,主键名等),因为IdentifierGenerator接口的generate(SessionImplementor session, Object object)方法有个入参是hbm.xml对应的实体对象object,那么,可以利用此object反射hbm.xml的中数据库信息,也就是通过此object的AbstractEntityPersister类来获取。
编写主键生成器类
package common.dao.
import java.io.S
import java.sql.SQLE
import java.util.P
import org.hibernate.HibernateE
import org.hibernate.MappingE
import org.hibernate.SessionF
import org.hibernate.dialect.D
import org.hibernate.engine.SessionI
import org.hibernate.id.C
import org.hibernate.id.IdentifierG
import org.hibernate.id.PersistentIdentifierG
import org.hibernate.persister.entity.AbstractEntityP
import org.hibernate.type.T
import org.springframework.orm.hibernate3.support.HibernateDaoS
import xxx.xxx.common.KeyG
* @ClassName: HibernateUserDefinedIDGenerator
* @Description: TODO(自定义主键生成器,需要在hbm.xml中或者Annotation中主键的generator的class指定该类)
* @Company xxx
* @author fulg
public class HibernateUserDefinedIDGenerator extends HibernateDaoSupport implements IdentifierGenerator{
//private Integer step = 4;//ID增长的步长
* (非 Javadoc)
* Title: generate
* Description:hibernate自动调用
* @param session
* @param object
* @throws HibernateException
* @see org.hibernate.id.IdentifierGenerator#generate(org.hibernate.engine.SessionImplementor, java.lang.Object)
* @author fulg
public Serializable generate(SessionImplementor session, Object object)throws HibernateException {
//持久化对象
AbstractEntityPersister classMetadata =
(AbstractEntityPersister)session.getFactory()
.getClassMetadata(object.getClass());
String tableName = classMetadata.getTableName();//表名
String IdentifierPropertyName = classMetadata.getIdentifierPropertyName();//id字段名
//调用之前已有的主键生成工具
//return KeyGenerator.getInstance(session.getFactory(), tableName, IdentifierPropertyName, step).getNextKey();
//到这里已经拿到了表名、id的字段名、session,可以session.connection()获取链接JDBC方式来拼写SQL操作数据库了
//既然继承了HibernateDaoSupport ,也拿到了session.getFactory(),那么也可以利用hibernate的getHibernateTemplate()来操作数据库了
//新手注意,不setSessionFactory,getHibernateTemplate()为null
setSessionFactory(session.getFactory());
getHibernateTemplate().executeFind(//以executeFind为例,能用的方法很多
new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException {
Query query = session.createQuery(hql);
.... .....
return query.list();
在xxx.hbm.xml中配置
&?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&&
Mapping file autogenerated by MyEclipse Persistence Tools
&hibernate-mapping&
&class name=&xxx.xxx.model.JianDingShenQing& table=&X_XXShenQing& &
&id name=&hangBiaoShi& type=&java.lang.Integer&&
&column name=&HangBiaoShi& /&
&generator class=&common.dao.hibernate.HibernateUserDefinedIDGenerator& /&
&property name=&renWuMingCheng& type=&java.lang.String&&
&column name=&RenWuMingCheng& length=&200& /&
&/property&
&property name=&renWuDanHao& type=&java.lang.String&&
&column name=&RenWuDanHao& length=&50& not-null=&true& /&
&/property&
&property name=&beiYongZi& type=&java.lang.Integer&&
&column name=&BeiYongZi& /&
&/property&
&property name=&beiYongZiFu& type=&java.lang.String&&
&column name=&BeiYongZiFu& /&
&/property&
&/hibernate-mapping&
至于在程序中的使用,平时怎么用hibernate操作的还怎么操作,只是id不用再手动的维护了。
精品视频课程推荐
本课程专注于数据结构和算法的内容,使用Java来进行代码示例,不空洞的讲解概念和理论,重点放在代码的实现和示例上。
从零开始、全面系统、成体系的讲解数据结构和基本算法,循序渐进的讲述构建软件系统所常见的数据结构和算法。
内容概述:Shiro是目前最热门、最易用、功能超强大的Java权限管理框架,强烈推荐,每个项目都必备的权限管理技术!通过本课程,你将从零开始直到彻底掌握Shiro的相关开发知识,达到可以进行实际项目开发的能力。包括:权限管理基础、Shiro入门、配置、身份认证、授权、Realms、Session管理、和Spring的集成、Web、Cache等众多开发细节技术
技术要点:源码级分析Shiro的授权过程、自定义开发Realm、多个Realms的开发配置、自定义开发AuthenticationStrategy、自定义开发自定义SessionDAO、和Struts2+Spring3的集成(包括修正struts2的bug)、Shiro和SpringMVC+Spring3的集成、包装使用其他的Cache框架、缓存数据同步更新的解决方案等等实际开发中常用的内容
创建规范的XML文档,DTD的作用,并且可以根据要求创建私用的DTD,通过JavaScript解析XML DOM
内容概述:本课程专注于构建:高可扩展性、高性能、大数据量、高并发、分布式的系统架构。
从零开始、全面系统、成体系的软件架构课程,循序渐进的讲述构建上述系统架构所需要的各种技术知识和技能。
技术要点:
1:构建基本的业务功能块,基于Maven+Git+Spring mvc+spring+mybatis+ehcache+mysql+X-gen代码生成
&2:高扩展性的分布式体系架构(基于Nginx+Varnish+Memcache+ActiveMQ)
&3:NoSQL的合理使用和架构优化(基于MongoDB)
&4:分布式文件存储和架构优化(基于MogileFS)
系统、完整的学习Spring Data JPA开发的知识。包括:Spring Data JPA入门;JpaRepository基本功能 ;JpaRepository的查询;客户化扩展JpaRepository;Specifications查询。
选择一个版面
软件设计专版
Web前端技术
学习问题讨论
面试、就业
版权所有 Copyright(C) 私塾在线学习网没有更多推荐了,
不良信息举报
举报内容:
Hibernate主键生成策略
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!博客分类:
Entity类中,主键尽量使用可以为null值的类型,比如Integer,Long,String等,不要用int,long等。因为如果主键为null,则表示该实体类还没有保存到数据库,是一个临时状态(Transient),而int,long不能设置为null,不具备该功能。
&!--以上抄书,待研究论证--&
name="属性名"column="数据库字段名" type="标识Hibernate类型的名字"
unsaved-value="null|any|none|undefined|id_value"
access="field|property|ClassName"&
&generator class="assigned|increment|identity|sequence|hilo|seqhilo|native|uuid|guid|select|foreign"/&
如果 name属性不存在,会认为这个类没有标识属性
unsaved-value 参考
access(可选 - 默认为property): Hibernate用来访问属性值的策略。 (网上查不到什么资料)
generator
1、assigned:
&& 在调用session.save()之前,必须手动setId(主键值),否则出错。
&& &generator&没有指定时的默认生成策略。
2、increment:自增长,为long, short或者int类型生成主键
&& 自动增长,由hibernate维护,适用于所有的数据库,每次插入数据前先查询最大id(select max(id) from xxx),即使id已经设好值,无视。
&& 缺点:不适合多进程并发更新数据库,适合单一进程访问数据库。不能用于群集环境。
3、identity:自增长
&&& 与increment不同的是:
&&& a)identity不是由hibernate控制,而是由数据库控制自增长,所插入数据前不会查询最大id。
&&& b)以Mysql为例,如果主键字段没有开启auto_increment,会抛异常"Field 'id' doesn't have a default value"。
&&& c)increment的insert语句包括id,identity的insert语句没有id字段。
&&& c)假设有五条数据,id分别为1、2、3、4,删除(3、4)后,用increment增加数据id为3,用identity增加数据id为5。
&&& 不同的数据库有不同的自增长方式。如MySql是auto_increment,SQL Server 中是Identity。支持的数据库:MySql、SQL Server、DB2、Sybase和HypersonicSQL。
&&& 优点: 不需要Hibernate和用户的干涉,使用较为方便。
&&& 缺点:但不便于在不同的数据库之间移植程序。
4、sequence:自增长
&&& 需要底层数据库支持Sequence方式。
&&& 实现了Sequence的数据库:Oracle、DB2、PostgreSQL。
&&& 没有实现Sequence的数据库:& MySQL、SQL Server、Sybase。
&&& 如果在MySql中使用该方式,hibernate会根据Dialect判断报错。
5、hilo:hi/low(高低位)算法,高低位算法使用一个高位值和一个低位值,然后把算法得到的两个值拼接起来作为数据库中的唯一主键。Hilo方式需要额外的数据库表和字段提供高位值来源。默认请况下使用的表是hibernate_unique_key,默认字段叫作next_hi。next_hi必须有一条记录否则会出现错误。
&generator class="hilo" &
&param name="table"&hi_value&/param&
&param name="column"&next_value&/param&
&param name="max_lo"&100&/param&
&/generator&
&&& hibernate根据hilo生成器生成主键的过程:
&&&& (1)读取并记录数据库的hi_value表中next_value字段的值,数据库中此字段值加1保存
&&&& (2)hibernate取得lo值(0到max_lo-1循环,lo到max_lo时,执行步骤1,然后lo继续从0到max_lo循环)
&&&& (3)取得hi值和lo值后,根据下面的公式计算主键值:hi*(max_lo+1)+
&&&& 过程参考:
&&& 个人感觉没有自增长好,不仅多维护一个表,每次插入数据都要进行查和修改next_value的值。
6、seqhilo基于sequence的hilo算法。
7、native:
 & Native主键生成方式会根据不同的底层数据库自动选择Identity、Sequence、Hilo主键生成方式
  特点:根据不同的底层数据库采用不同的主键生成方式。由于Hibernate会根据底层数据库采用不同的映射方式,因此便于程序移植,项目中如果用到多个数据库时,可以使用这种方式。
&&&& 疑问:什么时候选择Hilo?
7、uuid:
&&&& id必须是String类型。
 & 使用128位UUID算法生成主键,能够保证网络环境下的主键唯一性,也就能够保证在不同数据库及不同服务器下主键的唯一性。
 && 特点:能够保证数据库中的主键唯一性,生成的主键占用比较多的存贮空间。
8、guid
&&&&& 使用了一种特殊算法,保证生成主键的唯一性,支持SQL Server和MySQL。
&&&&& MySql中,先执行select uuid()。 uuid()是MySql自带的函数,取得uuid值后再生成主键。
9、select:使用数据库触发器赋值& (待研究)
10、foreign:使用外键赋值,在一对一实体关系时,可以保证关系双方的id保持一致。(待研究)
浏览: 19430 次
来自: 杭州
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 主键生成器 的文章

 

随机推荐