hibernate 序列_Hibernate身份,序列和表(序列)生成器
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身份,序列和表(序列)生成器相关推荐
- oracle数据库新建表增加表序列,设置id自增
1,oracle数据库增加新表时,设置表id为自增 最小1 最大9999999999 CREATE SEQUENCE "数据库名称"."SEQ_表名称" MIN ...
- 波表序列合成器:KORG Wavestate Native Mac
Korg 很自豪地推出 wavestate native,它是与硬件 wavestate 合成器完全兼容的软件对应物.wavestate native 在 macOS 和 Windows 上以 VST ...
- 查询oracle表序列,Oracle查询全部序列
Oracle查询所有序列 --查看当前用户的所有序列 select SEQUENCE_OWNER,SEQUENCE_NAME from dba_sequences where sequence_own ...
- oracle两表链接序列跳序,Oracle学习之 序列(Sequence)
Oracle学习之 序列(Sequence) [Oracle学习]之 序列(Sequence) oracle文档:https://docs.oracle.com/cd/B28359_01/server ...
- 栈 - 关于出栈序列,判断合法的出栈序列
文章目录 1 引例 2 做题方法 3 原因 3.1 选项D(4 3 1 2)的模拟 1 引例 (例)设栈的入栈序列是 1 2 3 4,则下列不可能是其出栈序列的是( ). A. 1 2 4 3 B. ...
- MySQL数据库序列的作用_MySQL数据库:序列使用
本文主要向大家介绍了MySQL数据库的序列使用,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. MySQL序列是一组整数:1, 2, 3, ...,由于一张数据表只能有一个字段自增 ...
- oracle定义递减序列步长值,浅谈Oracle序列
Oracle是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一,而序列是一个计数器,它并不会与特定的表关联,通过创建Oracle序列和触发器实现表的主键自增. 序列一 ...
- oracle 序列递增更新,ORACLE自动递增--序列
关于oracle的自动递增,一般依靠序列来产生.当然没SQL SERVICE 2005那样两粒简单的关键字就吃定. 创建序列的语法: CREATE SEQUENCE 序列名 [INCREMENT BY ...
- 【数字信号处理】傅里叶变换性质 ( 序列傅里叶变换共轭对称性质 | 序列实偶 傅里叶变换 实偶 | 序列实奇 傅里叶变换 虚奇 | 证明 “ 序列实奇 傅里叶变换 虚奇 “ )
文章目录 一.序列实偶 傅里叶变换 实偶 二.序列实奇 傅里叶变换 虚奇 三.证明 " 序列实奇 傅里叶变换 虚奇 " 1.前置公式定理 ①.序列实部傅里叶变换 ②.序列虚部傅里叶 ...
最新文章
- JavaScript-学习一全局变量
- 如何使用Bootstrap4显示和隐藏元素
- LVS入门篇(五)之LVS+Keepalived实战
- php theexcerpt,wordpress的excerpt()函数的用法示例
- 《快活帮》第二次作业:团队项目选题报告
- 关于Oracle RAC调整网卡MTU值的问题
- (123)FPGA面试题-介绍低速接口(UART、IIC、SPI),SPI有几根线,每根线的作用?(三)
- python曲线拟合绘图_python – 将曲线拟合到分段图像
- APP运营者如何对用户的数据进行分析?
- window8.1中用户的管理员权限的提升方法
- 汉字、图形,Zebra打印机完全解决方案
- 使用Python绘制词云图(自定义形状)
- java实例分析宠物商店_Java实现宠物商店管理
- Ubuntu下locale命令路径无法找到问题解决方法:Cannot set LC_CTYPE to default locale: No such file or directory
- 想找Java项目练手,却不知道从哪找?
- 尼尔·斯蒂芬森 (Neal Stephenson) 谈他的新地球工程气候变化惊悚片并创造了“元宇宙”一词...
- Python实现文字转语音功能
- java 持久监听blockqueue的变化_Curator目录监听
- lnoi2019游记
- 创建自己的区块链网络 七
热门文章
- 2017西安交大ACM小学期数论 [更新学号]
- 三个好用的并发工具类
- Java最小堆解决TopK问题
- JVM调优总结(5):典型配置
- 【集合框架】JDK1.8源码分析之HashMap(一)
- 最好的方法,是为你们量身定制!
- 比较两个title是否相等(差点把我送走)
- 集成Swagger(API)---SpringBoot
- 配置spring、SpringMVC,mybatis进行整合
- spring boot 单元测试_spring-boot-plus1.2.0-RELEASE发布-快速打包-极速部署-在线演示