type (可选): 标识Hibernate类型的名字。
column (可选 - 默认为属性名): 主键字段的名字。
unsaved-value (可选 - 默认为null): 一个特定的标识属性值,用来标志该实例是刚刚创建的,尚未保存。这可以把这种实例和从以前的session中装载过(可能又做过修改--译者注)但未再次持久化的实例区分开来。
access (可选 - 默认为property): Hibernate用来访问属性值的策略。
如果 name属性不存在,会认为这个类没有标识属性。
unsaved-value 属性很重要!如果你的类的标识属性不是默认为null的,你应该指定正确的默认值。
还有一个另外的<composite-id>声明可以访问旧式的多主键数据。我们强烈不鼓励使用这种方式。
1. generator
必须声明的<generator>子元素是一个Java类的名字,用来为该持久化类的实例生成唯一的标识。如果这个生成器实例需要某些配置值或者初始化参数,用<param>元素来传递。
<id name="id" type="long" column="uid" unsaved-value="0">
<generator class="net.sf.hibernate.id.TableHiLoGenerator">
<param name="table">uid_table</param>
<param name="column">next_hi_value_column</param>
</generator>
</id>
所有的生成器都实现net.sf.hibernate.id.IdentifierGenerator接口。这是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。当然,Hibernate提供了很多内置的实现。下面是一些内置生成器的快捷名字:
increment(递增)
用于为long, short或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。
identity
对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。返回的标识符是long, short 或者int类型的。
sequence (序列)
在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence),而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。
hilo (高低位)
使用一个高/低位算法来高效的生成long, short或者 int类型的标识符。给定一个表和字段(默认分别是是hibernate_unique_key 和next)作为高位值得来源。高/低位算法生成的标识符只在一个特定的数据库中是唯一的。在使用JTA获得的连接或者用户自行提供的连接中,不要使用这种生成器。
seqhilo(使用序列的高低位)
使用一个高/低位算法来高效的生成long, short或者 int类型的标识符,给定一个数据库序列(sequence)的名字。
uuid.hex
用一个128-bit的UUID算法生成字符串类型的标识符。在一个网络中唯一(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。
uuid.string
使用同样的UUID算法。UUID被编码为一个16个字符长的任意ASCII字符组成的字符串。不能使用在PostgreSQL数据库中
native(本地)
根据底层数据库的能力选择identity, sequence 或者hilo中的一个。
assigned(程序设置)
让应用程序在save()之前为对象分配一个标示符。
foreign(外部引用)
使用另外一个相关联的对象的标识符。和<one-to-one>联合一起使用。
2. 高/低位算法(Hi/Lo Algorithm)
hilo 和 seqhilo生成器给出了两种hi/lo算法的实现,这是一种很令人满意的标识符生成算法。第一种实现需要一个“特殊”的数据库表来保存下一个可用的“hi”值。第二种实现使用一个Oracle风格的序列(在被支持的情况下)。
<id name="id" type="long" column="cat_id">
<generator class="hilo">
<param name="table">hi_value</param>
<param name="column">next_value</param>
<param name="max_lo">100</param>
</generator>
</id>
<id name="id" type="long" column="cat_id">
<generator class="seqhilo">
<param name="sequence">hi_value</param>
<param name="max_lo">100</param>
</generator>
</id>
很不幸,你在为Hibernate自行提供Connection,或者Hibernate使用JTA获取应用服务器的数据源连接的时候无法使用hilo 。Hibernate必须能够在一个新的事务中得到一个"hi"值。在EJB环境中实现hi/lo算法的标准方法是使用一个无状态的session bean。
3. UUID算法(UUID Algorithm )
UUID包含:IP地址,JVM的启动时间(精确到1/4秒),系统时间和一个计数器值(在JVM中唯一)。在Java代码中不可能获得MAC地址或者内存地址,所以这已经是我们在不使用JNI的前提下的能做的最好实现了。
不要试图在PostgreSQL中使用uuid.string。
4. 标识字段和序列(Identity Columns and Sequences)
对于内部支持标识字段的数据库(DB2,MySQL,Sybase,MS SQL),你可以使用identity关键字生成。对于内部支持序列的数据库(DB2,Oracle, PostgreSQL, Interbase, McKoi,SAP DB),你可以使用sequence风格的关键字生成。这两种方式对于插入一个新的对象都需要两次SQL查询。
<id name="id" type="long" column="uid">
<generator class="sequence">
<param name="sequence">uid_sequence</param>
</generator>
</id>
<id name="id" type="long" column="uid" unsaved-value="0">
<generator class="identity"/>
</id>
对于跨平台开发,native策略会从identity, sequence 和hilo中进行选择,取决于底层数据库的支持能力。
下面再给个简单例子:
<id name="id" type="long" column="uid">
<generator class="sequence">
<param name="sequence">uid_sequence</param>
</genarator>
</id>
注意:
<generator class=""> 里面可以选啊!推荐Oracle用sequence,seqhilo
分享到:
相关推荐
- 在多进程或集群环境中可能导致主键冲突。 **官方建议:** - 只有在没有其他进程往同一张表中插入数据时才能使用,在集群下不要使用。 #### 四、hilo **定义与用途:** - **定义:**hilo策略采用高位/低位算法来...
Hibernate不参与主键的生成过程,这意味着你需要在调用save()之前通过setter方法为对象设置一个唯一的ID。这种方法虽然灵活,但可能导致并发问题,因此不推荐在多线程或分布式环境中使用。 配置示例: ```xml <id ...
- 在单个进程中使用安全,但在集群环境下可能引发冲突。 6. **Native**: - 根据底层数据库的能力选择最合适的生成策略。 - 通常是最优选择,可以自动适应不同的数据库。 7. **Select**: - 通过执行数据库...
- 在多进程并发更新数据库的情况下可能会导致主键冲突; - 官方建议仅在没有其他进程向同一张表插入数据时使用。 ##### 3. Hilo (High-Low) **描述**:Hilo 算法是一种常用的主键生成策略,它需要一张额外的表来...
但这种方法不适用于多线程或分布式环境,因为可能会导致并发问题,即多个进程可能会同时读取到相同的最大 ID,从而导致主键冲突。 2. Identity 标识符生成器:这是由底层数据库自身来处理主键生成的策略,例如 ...
这种策略可以跨数据库,但它有一个缺点,即在多进程并发更新数据库时,可能会产生主键冲突。因此,它适合单一进程访问数据库,不能用于群集环境。 例子:<id name="id" column="id">...
第二级缓存是可选的,可以是进程内或进程间共享的。此外,还可以使用查询缓存来存储SQL查询的结果。 **六、高级数据映射** 除了基本的对象属性映射,NHibernate还支持复杂的数据结构映射,如集合映射(List、Set、...
根据提供的文件信息,我们可以整理出一系列关于Java的重要知识点,这些知识点涵盖了Java基础知识、容器管理、多线程处理、反射机制、对象拷贝以及Java Web开发等几个方面。 ### Java基础知识 1. **JDK和JRE的区别*...
一个进程可以包含多个线程。 37. **守护线程**:守护线程是一种服务线程,在程序运行时提供辅助性服务。当进程中没有其他线程运行时,守护线程将自动结束。 38. **创建线程的方法**:主要有两种,继承Thread类并...