hibernate 序列

介绍

在上一篇文章中,我谈到了不同的数据库标识符策略。 这篇文章将比较最常见的替代主要关键策略:

  • 身份
  • 序列
  • 表(序列)

身份

IDENTITY类型(包括在SQL:2003标准中)受以下支持:

  • SQL服务器
  • MySQL(AUTO_INCREMENT)
  • DB2
  • 数据库

IDENTITY生成器允许按需自动增加integer / bigint列。 增量过程发生在当前正在运行的事务之外,因此回滚可能最终丢弃已分配的值(可能会发生值差距)。

增量过程非常有效,因为它使用了数据库内部的轻量级锁定机制,而不是重量级的事务性过程粒度锁定。

唯一的缺点是我们无法在执行INSERT语句之前知道新分配的值。 这种限制阻碍了Hibernate采用的“事务后写”刷新策略。 因此,Hibernates使用IDENTITY生成器为实体禁用JDBC批处理支持。

对于以下示例,我们将启用会话工厂JDBC批处理:

properties.put("hibernate.order_inserts", "true");
properties.put("hibernate.order_updates", "true");
properties.put("hibernate.jdbc.batch_size", "2");

让我们使用IDENTITY生成策略定义一个实体:

@Entity(name = "identityIdentifier")
public static class IdentityIdentifier {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;
}

持续存在5个实体:

doInTransaction(new TransactionCallable<Void>() {@Overridepublic Void execute(Session session) {for (int i = 0; i < 5; i++) {session.persist(new IdentityIdentifier());}session.flush();return null;}
});

将在另一个查询之后执行一个查询(不涉及JDBC批处理):

Query:{[insert into identityIdentifier (id) values (default)][]}
Query:{[insert into identityIdentifier (id) values (default)][]}
Query:{[insert into identityIdentifier (id) values (default)][]}
Query:{[insert into identityIdentifier (id) values (default)][]}
Query:{[insert into identityIdentifier (id) values (default)][]}

除了禁用JDBC批处理之外,IDENTITY生成器策略不适用于每个具体类继承模型的Table ,因为可能存在多个具有相同标识符的子类实体,并且基类查询最终将检索具有相同标识符的实体(甚至(如果属于不同类型)。

序列

SEQUENCE生成器(在SQL:2003标准中定义)受以下支持:

  • Oracle
  • SQL服务器
  • PostgreSQL
  • DB2
  • 数据库

SEQUENCE是一个数据库对象,它在每个连续的请求上生成增量整数。 SEQUENCES比IDENTIFIER列灵活得多,因为:

  • SEQUENCE是无表的,并且可以将同一序列分配给多个列或表
  • SEQUENCE可以预分配值以提高性能
  • SEQUENCE可以定义一个增量步骤,使我们可以受益于“池化” Hilo算法
  • SEQUENCE不会限制Hibernate JDBC批处理
  • SEQUENCE不会限制Hibernate继承模型

让我们使用SEQUENCE生成策略定义一个实体:

@Entity(name = "sequenceIdentifier")
public static class SequenceIdentifier {@Id@GenericGenerator(name = "sequence", strategy = "sequence", parameters = {@org.hibernate.annotations.Parameter(name = "sequenceName", value = "sequence"),@org.hibernate.annotations.Parameter(name = "allocationSize", value = "1"),})@GeneratedValue(generator = "sequence", strategy=GenerationType.SEQUENCE)private Long id;
}

我使用了“序列”生成器,因为我不想让Hibernate代表我们选择SequenceHiLoGenerator或SequenceStyleGeneGenerator 。

添加5个实体:

doInTransaction(new TransactionCallable<Void>() {@Overridepublic Void execute(Session session) {for (int i = 0; i < 5; i++) {session.persist(new SequenceIdentifier());}session.flush();return null;}
});

生成以下查询:

Query:{[call next value for hibernate_sequence][]}
Query:{[call next value for hibernate_sequence][]}
Query:{[call next value for hibernate_sequence][]}
Query:{[call next value for hibernate_sequence][]}
Query:{[call next value for hibernate_sequence][]}
Query:{[insert into sequenceIdentifier (id) values (?)][1]} {[insert into sequenceIdentifier (id) values (?)][2]}
Query:{[insert into sequenceIdentifier (id) values (?)][3]} {[insert into sequenceIdentifier (id) values (?)][4]}
Query:{[insert into sequenceIdentifier (id) values (?)][5]}

该表中的插入是批量处理的,但是我们知道在插入实体之前有5个序列调用。 这可以通过使用HILO算法进行优化。

表(序列)

生成序列还有另一种与数据库无关的替代方法。 一个或多个表可用于保存标识符序列计数器。 但这意味着要牺牲写入性能来实现数据库的可移植性。

尽管IDENTITY和SEQUENCES没有事务,但是使用数据库表授权ACID来同步多个并发id生成请求。

通过使用行级锁定,可以实现这一点,而行级锁定的成本要高于IDENTITY或SEQUENCE生成器。

必须在单独的数据库事务中计算序列,这需要IsolationDelegate机制,该机制同时支持本地(JDBC)和全局(JTA)事务。

  • 对于本地事务,它必须打开一个新的JDBC连接,因此对当前的连接池机制施加了更大的压力。
  • 对于全局事务,它需要挂起当前正在运行的事务。 在生成序列值之后,必须恢复实际事务。 此过程需要自己承担费用,因此可能会影响整体应用程序性能。

让我们使用TABLE生成策略定义一个Entity:

@Entity(name = "tableIdentifier")
public static class TableSequenceIdentifier {@Id@GenericGenerator(name = "table", strategy = "enhanced-table", parameters = {@org.hibernate.annotations.Parameter(name = "table_name", value = "sequence_table")})@GeneratedValue(generator = "table", strategy=GenerationType.TABLE)private Long id;
}

我使用了较新的“增强表”生成器,因为旧式“表”生成器已被弃用。

添加5个实体:

doInTransaction(new TransactionCallable<Void>() {@Overridepublic Void execute(Session session) {for (int i = 0; i < 5; i++) {session.persist(new TableSequenceIdentifier());}session.flush();return null;}
});

生成以下查询:

Query:{[select tbl.next_val from sequence_table tbl where tbl.sequence_name=? for update][default]}
Query:{[insert into sequence_table (sequence_name, next_val)  values (?,?)][default,1]}
Query:{[update sequence_table set next_val=?  where next_val=? and sequence_name=?][2,1,default]}
Query:{[select tbl.next_val from sequence_table tbl where tbl.sequence_name=? for update][default]}
Query:{[update sequence_table set next_val=?  where next_val=? and sequence_name=?][3,2,default]}
Query:{[select tbl.next_val from sequence_table tbl where tbl.sequence_name=? for update][default]}
Query:{[update sequence_table set next_val=?  where next_val=? and sequence_name=?][4,3,default]}
Query:{[select tbl.next_val from sequence_table tbl where tbl.sequence_name=? for update][default]}
Query:{[update sequence_table set next_val=?  where next_val=? and sequence_name=?][5,4,default]}
Query:{[select tbl.next_val from sequence_table tbl where tbl.sequence_name=? for update][default]}
Query:{[update sequence_table set next_val=?  where next_val=? and sequence_name=?][6,5,default]}
Query:{[insert into tableIdentifier (id) values (?)][1]} {[insert into tableIdentifier (id) values (?)][2]}
Query:{[insert into tableIdentifier (id) values (?)][3]} {[insert into tableIdentifier (id) values (?)][4]}
Query:{[insert into tableIdentifier (id) values (?)][5]}

表生成器允许JDBC批处理,但它诉诸于SELECT FOR UPDATE查询。 行级别锁定绝对比使用本机IDENTITY或SEQUENCE效率低。

因此,根据您的应用程序需求,您可以选择多个选项。 没有一个单一的获胜策略,每一个都有优点和缺点。

  • 代码可在GitHub上获得 。

翻译自: https://www.javacodegeeks.com/2014/07/hibernate-identity-sequence-and-table-sequence-generator.html

hibernate 序列

hibernate 序列_Hibernate身份,序列和表(序列)生成器相关推荐

  1. oracle数据库新建表增加表序列,设置id自增

    1,oracle数据库增加新表时,设置表id为自增 最小1 最大9999999999 CREATE SEQUENCE "数据库名称"."SEQ_表名称" MIN ...

  2. 波表序列合成器:KORG Wavestate Native Mac

    Korg 很自豪地推出 wavestate native,它是与硬件 wavestate 合成器完全兼容的软件对应物.wavestate native 在 macOS 和 Windows 上以 VST ...

  3. 查询oracle表序列,Oracle查询全部序列

    Oracle查询所有序列 --查看当前用户的所有序列 select SEQUENCE_OWNER,SEQUENCE_NAME from dba_sequences where sequence_own ...

  4. oracle两表链接序列跳序,Oracle学习之 序列(Sequence)

    Oracle学习之 序列(Sequence) [Oracle学习]之 序列(Sequence) oracle文档:https://docs.oracle.com/cd/B28359_01/server ...

  5. 栈 - 关于出栈序列,判断合法的出栈序列

    文章目录 1 引例 2 做题方法 3 原因 3.1 选项D(4 3 1 2)的模拟 1 引例 (例)设栈的入栈序列是 1 2 3 4,则下列不可能是其出栈序列的是( ). A. 1 2 4 3 B. ...

  6. MySQL数据库序列的作用_MySQL数据库:序列使用

    本文主要向大家介绍了MySQL数据库的序列使用,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. MySQL序列是一组整数:1, 2, 3, ...,由于一张数据表只能有一个字段自增 ...

  7. oracle定义递减序列步长值,浅谈Oracle序列

    Oracle是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一,而序列是一个计数器,它并不会与特定的表关联,通过创建Oracle序列和触发器实现表的主键自增. 序列一 ...

  8. oracle 序列递增更新,ORACLE自动递增--序列

    关于oracle的自动递增,一般依靠序列来产生.当然没SQL SERVICE 2005那样两粒简单的关键字就吃定. 创建序列的语法: CREATE SEQUENCE 序列名 [INCREMENT BY ...

  9. 【数字信号处理】傅里叶变换性质 ( 序列傅里叶变换共轭对称性质 | 序列实偶 傅里叶变换 实偶 | 序列实奇 傅里叶变换 虚奇 | 证明 “ 序列实奇 傅里叶变换 虚奇 “ )

    文章目录 一.序列实偶 傅里叶变换 实偶 二.序列实奇 傅里叶变换 虚奇 三.证明 " 序列实奇 傅里叶变换 虚奇 " 1.前置公式定理 ①.序列实部傅里叶变换 ②.序列虚部傅里叶 ...

最新文章

  1. JavaScript-学习一全局变量
  2. 如何使用Bootstrap4显示和隐藏元素
  3. LVS入门篇(五)之LVS+Keepalived实战
  4. php theexcerpt,wordpress的excerpt()函数的用法示例
  5. 《快活帮》第二次作业:团队项目选题报告
  6. 关于Oracle RAC调整网卡MTU值的问题
  7. (123)FPGA面试题-介绍低速接口(UART、IIC、SPI),SPI有几根线,每根线的作用?(三)
  8. python曲线拟合绘图_python – 将曲线拟合到分段图像
  9. APP运营者如何对用户的数据进行分析?
  10. window8.1中用户的管理员权限的提升方法
  11. 汉字、图形,Zebra打印机完全解决方案
  12. 使用Python绘制词云图(自定义形状)
  13. java实例分析宠物商店_Java实现宠物商店管理
  14. Ubuntu下locale命令路径无法找到问题解决方法:Cannot set LC_CTYPE to default locale: No such file or directory
  15. 想找Java项目练手,却不知道从哪找?
  16. 尼尔·斯蒂芬森 (Neal Stephenson) 谈他的新地球工程气候变化惊悚片并创造了“元宇宙”一词...
  17. Python实现文字转语音功能
  18. java 持久监听blockqueue的变化_Curator目录监听
  19. lnoi2019游记
  20. 创建自己的区块链网络 七

热门文章

  1. 2017西安交大ACM小学期数论 [更新学号]
  2. 三个好用的并发工具类
  3. Java最小堆解决TopK问题
  4. JVM调优总结(5):典型配置
  5. 【集合框架】JDK1.8源码分析之HashMap(一)
  6. 最好的方法,是为你们量身定制!
  7. 比较两个title是否相等(差点把我送走)
  8. 集成Swagger(API)---SpringBoot
  9. 配置spring、SpringMVC,mybatis进行整合
  10. spring boot 单元测试_spring-boot-plus1.2.0-RELEASE发布-快速打包-极速部署-在线演示