精通Hibernate——Hibernate内置标识符详解

1、increment标识符生成器

由Hibernate以递增的方式为代理主键,例如:

<hibernate-mapping>
    <class name="mypack.IncrementTester" table="INCREMENT_TESTER" >
        <id name="id" type="long" column="ID" >
            <meta attribute="scope-set">private</meta>
            <generator class="increment" />
        </id>

        <property name="name" type="string">
            <column name="NAME" length="15" />
        </property>
    </class>
</hibernate-mapping>

Hibernate在持久化一个IncrementTester对象时,会以递增的方式生成标识符,事实上,Hibernate在初始化阶段读取INCREMENT_TESTER表中最大主键值,接下来向INCREMENT_TESTER表中插入记录时,就在max(ID)基础上递增,增量为1。下面考虑有两个Hibernate应用进程访问同一个数据库的情景。

(1)假定第一个进程中的Hibernate在初始化阶段读取INCREMENT_TESTER表中最大主键为6

(2)第二个进程中的Hibernate在初始化阶段读取INCREMENT_TESTER表中最大主键仍然为6

(3)接下来两个进程中的Hibernate各自向INCREMENT_TESTER表中插入主键为7的记录,这违反了数据库完整性约束,导致有一个进程的插入操作失败。

由此看见,increment标识符生成器仅仅在单个Hibernate应用进程访问数据库的情况下才能有效工作。更确切的说,即使在同一个进程中创建了连接同一个数据库的多个SessionFactory实例,也会导致插入操作失效。在J2EE软件架构中,Hibernate通常作为JNDI资源运行在应用服务器上。

increment标识符生成器具有以下适用范围:

1、由于increment生成标识符的机制不依赖于底层数据库系统,因此他适用于所有的数据库系统

2、适用于只有单个Hibernate应用进程访问同一个数据库的场合,在集群环境下不推荐使用

3、OID必须为long,int或short类型,如果把OID定义为byte类型,在运行时会抛出以下异常:

[java] net.sf.hibernate.id.IdentifierGenerationException:this id generator generates long,integer,short,identity

2、identity标识符生成器

identity标识符生成器由底层数据库来负责生成标识符,他要求底层数据库把主键定义为自动增长字段类型。例如:在Mysql中,应该把主键定义为auto_increment类型,在MS SQL Service中,应该把主键定义为identity类型。配置如下:

<hibernate-mapping>
    <class name="mypack.IncrementTester" table="INCREMENT_TESTER" >
        <id name="id" type="long" column="ID" >
            <meta attribute="scope-set">private</meta>
            <generator class="identity" />
        </id>

        <property name="name" type="string">
            <column name="NAME" length="15" />
        </property>
    </class>
</hibernate-mapping>

Hibernate在持久化一个identityTester对象时,由底层数据库负责生成主键

identity标识符生成器具有以下使用范围。

1、由于identity生成标识符的机制依赖于底层数据库系统,因此,要求底层数据库系统必须支持自动增长字段类型。支持的数据库有DB2、Mysql、Ms SQL Server、Sybase、HSQLDB和Informix等

2、OID必须为long,int或short类型,如果把OID定义为byte在运行时会抛出以下异常

[java] net.sf.hibernate.id.IdentifierGenerationException:this id generator generates long,integer,short,identity

3、sequence标识符生成器

sequence标识符生成器利用底层数据提供的序列来生成标识符,例如:

<hibernate-mapping>
    <class name="mypack.IncrementTester" table="INCREMENT_TESTER" >
        <id name="id" type="long" column="ID" >
            <meta attribute="scope-set">private</meta>
            <generator class="sequence">
                <param name="sequence">tester_id_seq</param>
            </generator>
        </id>

        <property name="name" type="string">
            <column name="NAME" length="15" />
        </property>
    </class>
</hibernate-mapping>

Hibernate在持久化一个SequenceTester对象时,先从底层数据库的tester_id_seq序列中获得一个唯一的序列号,再把它作为主键值。

sequence标识符生成器具有以下使用范围:

1、由于sequence生成标识符机制依赖于底层数据库系统的序列,因此,要求底层数据库系统必须支持序列,支持的数据库有Oracle、DB2、SAP DB和PostgreSQL等

2、OID必须为long、int或short类型,如果把OID定义为byte类型,在运行时会报出如下异常:

[java] net.sf.hibernate.id.IdentifierGenerationException:this id generator generates long,integer,short,identity

4、Hilo标识符生成器

Hilo标识符生成器由Hibernate按照一定high/low算法来生成标识符,他从数据库的特定表的字段中获取high值,例如如下配置声明使用Hilo标识符生成器,其中high值存放在hi_value表的next_value字段中:

<hibernate-mapping>
    <class name="mypack.IncrementTester" table="INCREMENT_TESTER" >
        <id name="id" type="long" column="ID" >
            <meta attribute="scope-set">private</meta>
            <generator class="hilo">
                <param name="table">hi_value</param>
                <param name="column">next_value</param>
                <param name="max_lo">100</param>
            </generator>
        </id>

        <property name="name" type="string">
            <column name="NAME" length="15" />
        </property>
    </class>
</hibernate-mapping>

Hibernate在持久化一个HiloTester对象时,由Hibernate负责生成主键。Hilo标识符生成器在生成标识符时,需要读取并修改hi_value表中的next_value。这段操作需要在单独的事务中处理,例如以下代码中,当执行session.save(object)方法时,Hilo标识符生成器不适用Session对象的当前数据库连接和事务,而是在一个新的数据库连接中创建新的事务,然后访问hi_value表

tx = session.beginTransaction();
session.save(object);
tx.commit();

Hilo标识符生成器具有以下适用范围:

1、由于Hilo生成标识符的机制不依赖于底层数据库系统,因此适用于所有的数据库系统

2、OID必须为long、int或short类型,如果把OID定义为byte类型,在运行时会抛出如下异常:

[java] net.sf.hibernate.id.IdentifierGenerationException:this id generator generates long,integer,short,identity

3、high/low算法生成的标识符只能在一个数据库中保证唯一

4、当用户为Hibernate自行提供数据库连接,或者Hibernate通过JTA,从而应用服务器的数据源获得数据库连接的时候无法使用Hilo,因为这不能保证Hilo在新的数据库连接事务中访问hi_value,在这种情况下,如果数据库系统支持序列,可以使用sehilo生成器。,例如oracle

5、native标识符生成器

native标识符生成器依据底层数据库对自动生成标识符的支持能力,来选择使用identity、sequence或Hilo标识符生成器。native能自动判断底层数据库提供的生成标识符的机制。例如,如果Mysql和MS SQL Server,就选择identity标识符生成器;如果为Oracle,就选择sequence标识符生成器。例如:

<hibernate-mapping>
    <class name="mypack.IncrementTester" table="INCREMENT_TESTER" >
        <id name="id" type="long" column="ID" >
            <meta attribute="scope-set">private</meta>
            <generator class="native" />
        </id>

        <property name="name" type="string">
            <column name="NAME" length="15" />
        </property>
    </class>
</hibernate-mapping>

当底层数据库为Mysql时,其实使用的是identity标识符生成器,因此,当Hibernate在持久化一个NativeTester对象时,由底层数据库负责生成主键值。native标识符生成器具有以下适用范围:

1、由于native能根据底层数据库系统的类型自动选择合适的标识符生成器,因此很适合于夸数据库平台开发,即同一个Hibernate应用需要连接多种数据库系统的场合。

2、OID必须为long、int或short类型,如果把OID定义为byte类型,在运行时会抛出如下异常:

[java] net.sf.hibernate.id.IdentifierGenerationException:this id generator generates long,integer,short,identity

时间: 2024-10-06 11:49:17

精通Hibernate——Hibernate内置标识符详解的相关文章

Python内置函数详解

置顶   内置函数详解 https://docs.python.org/3/library/functions.html?highlight=built#ascii 此文参考了别人整理好的东西(地址:http://www.cnblogs.com/sesshoumaru/p/6140987.html#p1),然后结合自己的理解,写下来,一方面方便自己,让自己好好学习,顺便回忆回忆:另一方面,让喜欢的盆友也参考一下. 经查询,3.6版本总共有68个内置函数,主要分类如下: 数学运算(7个) 类型转换

ThinkPHP内置函数详解D、F、S、C、L、A、I

ThinkPHP内置函数详解D.F.S.C.L.A.I 单字母函数D.F.S.C.L.A.I 他们都在ThinkPHP核心的ThinkPHP/Mode/Api/functions.php这个文件中定义. 下面我分别说明一下他们的功能: D() 加载Model类 M() 加载Model类 A() 加载Action类 L() 获取语言定义 C() 获取配置值    用法就是   C("这里填写在配置文件里数组的下标") S() 全局缓存配置 用法S(“这里相当于一个唯一的标识”) F()

JavaWeb学习(三)----JSP内置对象详解

[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4065790.html 联系方式:[email protected] [系列]JSP学习系列文章:(持续更新) JavaWeb学习(一)----JSP简介及入门(含Tomcat的使用) JavaWeb学习(二)----JSP脚本元素.指令元素.动作元素 JavaWeb学习(三)----JSP内置对象

MYSQL常用内置函数详解说明

函数中可以将字段名当作变量来用,变量的值就是该列对应的所有值:在整理98在线字典数据时(http://zidian.98zw.com/),有这要一个需求,想从多音字duoyinzi字段值提取第一个拼音作为拼音pinyin字段的值,如:duoyinzi(ā,á,ǎ,à,a),想提取ā作为pinyin的值:数据有好几万条,不想用程序一条条处理,只想用一个sql来实现,后来了解了下MYSQL常用内置函数,是可以做到的:sql:UPDATE ol_zidian set pinyin=LEFT(duoyi

序列内置方法详解(string/list/tuple)

一.常用方法集合 1.1.string,字符串常用方法 以下举例是python2.7测试: 函数名称 作用 举例 str.capitalize() 字符串第一个字符如果是字母,则把字母替换为大写字母.然后返回新的字符串 >>> l = 'abc cba' >>> l.capitalize() 'Abc cba' >>> l.capitalize() '2b 3c' str.center() 字符串设置为指定字符宽度,并居中.默认是用空格填充前后空白字符

Hibernate学习-5-配置文件详解

自动建表的配置建完表后,最好关掉配置<property name="hibernate.hbm2ddl.auto">create</property>每次都重新建表,如果表已经存在就先删除再创建.<property name="hibernate.hbm2ddl.auto">create-drop</property>每次在创建sessionFactory时执行创建表当调用sessionFactory的close方法的

Python内置函数详解——总结篇

2个多月来,将3.5版本中的68个内置函数,按顺序逐个进行了自认为详细的解析,现在是时候进行个总结了.为了方便记忆,将这些内置函数进行了如下分类:     数学运算(7个)     类型转换(24个)     序列操作(8个)     对象操作(7个)     反射操作(8个)     变量操作(2个)     交互操作(2个)     文件操作(1个)     编译执行(4个)     装饰器(3个) 数学运算 abs:求数值的绝对值 >>> abs(-2) 2 divmod:返回两个

JSP内置对象详解

jsp中内置对象:request.response.session.applecation.out.pagecontesx.config.page.exception.cookie 1.request:是javax.servlet.httpservletRequest类型的对象,该对象是用户客户端的请求信息,主要用户接受客户端通过http协议传送到服务器的数据! (包括头部信息.系统信息.请求方式以及请求信息参数),jsp内置对象Web容器所创建的一组对象! 生命周期:jsp发出请求一个requ

ASP.NET 常用内置对象详解-----Response

利用提供的内置对象,可以实现页面之间的数据传递及实现一些特定的功能,如:缓冲输出,页面重定向等等. Response :响应,反应 Request:请求 Server:服务器 Application:应用,申请,应用程序: Session:回话,会议 Cookie:饼干 一. Response:  作用: 将动态生成的信息嵌入到HTML文档中,然后发送到客户端: 缓冲输出数据: 重定向浏览器到另一个URL: 向浏览器输出Cookie文件. 其类名为httpResponse 常用方法: : Res