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 序列

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/340486.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java中date加1s_是否有一个java库将描述时间度量(例如“1d 1m 1s”)的字符串转换为毫秒?...

解析器不是太复杂&#xff1a;public static long parse(String input) {long result 0;String number "";for (int i 0; i < input.length(); i) {char c input.charAt(i);if (Character.isDigit(c)) {number c;} else if (Character.isLetter(c) &&…

几何画板200个经典课件_项目制学科联动 | 金芬娥首席工作室:灵动“画板”,研修创新,协同进步...

西湖区成立115个“项目制首席教师工作室”&#xff0c;建立中小学、幼儿园学科联动机制&#xff0c;以专业发展为目标&#xff0c;以教育问题为导向&#xff0c;整合发挥学科教研员、学科带头人和名师工作室领衔人的智力资源&#xff0c;助推教师的专业成长及区域的学科建设。西…

通过这些简单的步骤从头开始学习Java

Java是用于软件开发的最流行的编程语言之一。 无论您的最终目标或技能水平如何&#xff0c;学习和掌握Java都将为您作为开发人员打开大门。 今天&#xff0c;我们将讨论一些原因&#xff0c;我们认为您应该开始学习Java&#xff0c;然后提供有关入门的深入路线图。 为什么要学…

vs 服务容器中已存在服务_敏捷基础设施和公共基础服务

敏捷基础设施和公共基础服务敏捷基础设施和公共基础服务是微服务架构的有力支撑&#xff1b;能够简化业务开发&#xff0c;提升架构能力的基线。Cloud Native的基石是微服务架构、敏捷基础设施和公共基础服务。敏捷基础设施 - 通过容器封装环境&#xff0c;开发人员可以直接将所…

java 的简单代码_java初学 简单代码

1.简单的java程序public class RightAndWrong {public static void main(String argc[]){boolean bool true;if (bool false){System.out.println("This is wrong!");}else{System.out.println("This is right!");}}}//编译 javac RightAndWrong.java//…

使用php吧excel数据存到数据库,php如何存excel数据到数据库

一、使用PHPExcel Parser Pro软件&#xff0c;但是这个软件为收费软件&#xff1b;二、可将EXCEL表保存为CSV格式&#xff0c;然后通过phpmyadmin或者SQLyog导入&#xff0c;SQLyog导入的方法为&#xff1a;将EXCEL表另存为CSV形式&#xff1b;打开SQLyog&#xff0c;对要导入的…

sle linux lftp禁止匿名登陆_软件测试常用linux命令整理

作为一个名软件测试工程师&#xff0c;掌握Linux的基本操作是必须的。下面罗列下linux的常用命令&#xff0c;方便大家今后操作linux时查找&#xff0c;然后通过[帮助命令]进行具体的使用。1、帮助命令man -- man 命令 查看命令的使用帮助说明。2、显示目录和文件的命令ls --…

对编写的代码进行单元测试_编写数据访问代码测试–单元测试是浪费

对编写的代码进行单元测试几年前&#xff0c;我是为我的数据访问代码编写单元测试的那些开发人员之一。 我正在孤立地测试所有内容&#xff0c;我对自己感到非常满意。 老实说&#xff0c;我认为自己做得很好。 哦&#xff0c;男孩&#xff0c;我错了&#xff01; 这篇博客文章…

用php模拟斗地主发牌,php模拟实现斗地主发牌

本文实例为大家分享了php实现斗地主发牌的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下闲来无聊&#xff0c;就写了这个方法&#xff0c;也算是熟悉下php的数组操作&#xff0c;还请各位大神多指教。$arr 数组&#xff0c;好像有点问题&#xff0c;应该 2>"…

python odoo_Odoo开发教程20-使用 Python 虚拟环境安装 Odoo第二讲

配置插件(add-ons)路径社区贡献的插件可以打包成 Python 库&#xff0c;发布到 Python 包索引(PyPI -Python Package Index)&#xff0c;然后像其它库一样使用 pip 安装。为了能使用这一方法&#xff0c;Odoo 自动添加了 sitepackages/文件夹至插件配置路径&#xff0c;用于安装…

如何在AWS EC2实例上部署Spring Boot应用程序

你好朋友&#xff0c; 在本教程中&#xff0c;我们将看到如何在AWS EC2实例上部署Spring Boot应用程序。 这是我们将要执行的步骤。 1.使用Spring Boot Initialiser创建一个Spring Boot项目。 2.创建一个休息端点&#xff0c;部署后我们可以访问 3.启动EC2实例 4.将我们的…

ps -ef grep java解释,ps -ef | grep java(示例代码)

ps命令将某个进程显示出来grep命令是查找中间的|是管道命令 是指ps命令与grep同时执行PS是LINUX下最常用的也是非常强大的进程查看命令grep命令是查找&#xff0c;是一种强大的文本搜索工具&#xff0c;它能使用正则表达式搜索文本&#xff0c;并把匹配的行打印出来。grep全称是…

python世界第一语言_Java 跌落神坛!Python 正式登顶世界第一编程语言

编程语言流行指数(PYPL)排行榜近日公布了2019年2月份榜单。在最新一期榜单上&#xff0c;Python的份额高达26.42&#xff05;&#xff0c;稳居第一&#xff0c;并且猛增5.2%&#xff0c;同时成为增长势头最好的语言。而被挤到第二的Java&#xff0c;目前份额为21.2&#xff05;…

成为Java流大师–第3部分:终端操作

比尔盖茨曾经说过&#xff1a;“我选择一个懒惰的人去做一件困难的事情&#xff0c;因为一个懒惰的人会找到一个简单的方法来做。” 关于流&#xff0c;没有什么比这更真实了。 在本文中&#xff0c;您将学习Stream如何通过在调用终端操作之前不对源元素执行任何计算来避免不必…

python选项卡中文详细说明_pycharm窗口选项卡管理

1、主题我们已经注意到Pycharm的主编辑框是基于窗口选项卡机制显示的&#xff0c;Pycharm选项卡多种多样&#xff0c;这里我们将详细介绍这种选项卡机制。2、激活的选项卡每当我们打开一个Python文件时open a file for editing&#xff0c;它都会对应打开一个选项卡窗口&#x…

和至少为k的最短子数组 python_和至少为k的最短子数组

// 单调栈// 维护一个具有栈单调性的队列&#xff0c;跟动态规划不一样的是时间复杂度为O(n)// queue[i]中存放着前缀和// 我们知道因为负数的存在&#xff0c;所以队列不是单调增长的&#xff0c;但是不单调的其实对我们没有用// 因为肯定可以找到比它短的(因此我们移除比)// …

matlab多径信道模型,基于matlab的无线多径信道建模与仿真分析

基于matlab的无线多径信道建模与仿真分析 基于MATLAB的无线多径信道建模与仿真分析 摘 要:对于无线通信, 衰落是影响系统性能的重要因素, 而不同形式的衰落对于信号产生的影响 也不相同。本文在阐述移动多径信道特性的基础上, 建立了不同信道模型下多径时延效应的计算 机仿真模…

c 遍历文件 递归遍历_将递归文件系统遍历转换为流

c 遍历文件 递归遍历在学习编程的时候&#xff0c;回溯到Turbo Pascal的时代&#xff0c;我设法使用FindFirst &#xff0c; FindNext和FindClose函数在目录中列出文件。 首先&#xff0c;我想出了一个打印给定目录内容的过程。 您可以想象我为能够真正从自身调用该过程以递归遍…

净迁移人口预测程序python_高质量深度学习模型, 一键模型预测,迁移学习很简单...

飞桨(PaddlePaddle)核心框架Paddle Fluid v1.5已经发布&#xff0c;而作为其关键工具&#xff0c;用来迁移学习的PaddleHub也进行了全面更新&#xff0c;正式发布了1.0版本。全新的PaddleHub模型和任务更加丰富&#xff0c;为用户提供了覆盖 文本 、 图像 和 视频 三大领域八大…

您的JVM是否泄漏文件描述符-像我的一样?

前言&#xff1a;此处描述的两个问题是在一年前发现并修复的。 本文仅用作历史证明&#xff0c;也是有关解决Java中文件描述符泄漏的初学者指南。 在Ultra ESB中&#xff0c;我们使用内存RAM磁盘文件缓存来进行快速且无垃圾的有效负载处理。 一段时间以前&#xff0c;我们在共…