3.4.3 选择主键

你需要告诉Hibernate你选择的主键生成策略。但是首先,让我们定义什么是主键。

候选键是唯一能标识数据库的行的键。一个候选键必须满足如下的属性:

值不能为空

每一行都有一个唯一的值

对于特定行来说,其值是稳定的,不改变的

对于给定的表来说,几列或者几列的联合必须满足这些属性。如果一个表拥有一个能够标识行的属性,这就称之为主键。如果同时存在多个候选键,那么你可以从其中选择一个作为主键。如果表中不存在唯一的列标识,因此也就不存在候选键,那么按照关系模型的定义它就不是一个关系,这个时候,你可能需要重新考虑你的数据模型了。

许多遗留的SQL数据模型都是用了原生的主键。从业务上解释原生主键就是,一个属性或者属性的联合必须在业务语义上是唯一的。一个很好的例子就是美国社会保险号码或者澳大利亚税务文件号码。区分原生键也是简单:如果一个候选键属性的语义不在数据库的上下文中,那么它就是原生键,无论它是否是自动生成的。

经验显示原生键通常会造成一些问题。一个定义良好的主键应该是唯一的、不变的并且不能为空。很少有实体属性能够同时满足这些要求,许多属性也不能很好的进行SQL数据库的索引。除此之外,你必须保证候选键在编程主键之前它的值绝对不能被改变。改变主键的定义以及与其关联的外键是一件令人恼火的工作。

基于以上原因,我们强烈推荐新的应用程序使用人工生成的标识符(这也被称之为代理键)。代理键没有任何业务语义---它们通过数据库或者应用程序生成唯一的值。有许多广为人知的方法用来生成代理键。

Hibernate拥有集中内置的标识符生成策略。我们在表3.1中列举几种有用的选项:

表3.1 Hibernate内置标识符生成模块

生成器名称

描述

native

native依赖于其他几种生成策略,主要看使用的数据库的类型。

 

identity

支持DB2,MySql,SQL Server,Sybase,HSQLDB,Informix和HypersonicSQL。 其返回类型是long,short或者int。

sequence

DB2,PostgreSQL,Oracle,SAP DB,McKoi,Firebird或者InterBase的生成器。返回值是long,short或者int。

increment

在hibernate启动的时候,生成器或读取表格主键的最大值,当有新行插入的时候,会自动增加最大值。其类型可以是long,short或者int。这种策略在使用单服务器的Hibernate应用程序上尤其有效。

hilo

使用 high/low算法来生成类型long,short,int 的主键,假定一个表或者列是hi值的源。这种算法只针对特定的数据库有效。

Uuid.hex

这种生成器使用了128位的UUID。生成的IP地址加上唯一的时间戳。UUID使用32位的16进制数字进行编码。这种生成策略并不流行,因为相对于数字来说,字符型的主键需要更多的存储空间并且速度上更慢一些。

当然,你并不仅仅局限于使用这几种内置的策略。你可以通过实现Hibernate的IdentifierGenerator接口来实现自己的生成器。你甚至可以在同一个业务模型中混用几种不同的生成策略,但是对于非遗留数据我们推荐使用相同的生成器。

相对于原生的主键来说,这些生成策略更加有用。这些策略允许应用能够在调用save()方法进行持久化之前给主键分配值。然而对于那些分离的对象来说,这些策略有着一些缺点。应该尽量避免使用分配的标识符,使用表3.1中列出的策略会更加简单。

对于遗留数据,情形似乎更加复杂一些。在这个例子中,我们经常使用原生键尤其是那些组合键。由于组合标识符更加的男,我们将在第八章中来讨论它。

下一步就是为CaveatEmptor 增加标识符属性了。是不是所有的类都有数据库的标识符呢?为了回答这个问题,我们将继续探讨实体和值类型在hibernate中却别。这些概念是一个好的对象模型所必需的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值