从JPA到Hibernate的旧版和增强型标识符生成器

JPA标识符生成器

JPA定义了以下标识符策略:

战略 描述
汽车 持久性提供程序选择基础数据库支持的最合适的标识符策略
身份 标识符由数据库IDENTITY列分配
序列 持久性提供程序使用数据库序列来生成标识符
持久性提供程序使用单独的数据库表来模拟序列对象

在我以前的文章中,我举例说明了所有这些替代标识符策略的优缺点。

标识符优化器

尽管没有太多应用程序侧IDENTITY生成器优化(除了配置数据库标识预分配外),序列标识符在这方面提供了更大的灵活性。 最常见的优化策略之一是基于高/低分配算法 。

为此,Hibernate提供了:

发电机 描述
SequenceHiLoGenerator 它使用数据库序列生成hi值,而低值根据hi / lo算法递增

TableHiLoGenerator
数据库表用于生成hi值。 不推荐使用此生成器,而推荐使用MultipleHiLoPerTableGenerator,增强的TableGenerator或SequenceStyleGenerator。
多重HiLo
PerTableGenerator
它是一个高/低表生成器,即使对于多个标识符序列,也可以使用单个数据库表。
SequenceStyleGenerator 它是先前序列生成器的增强版本。 如果基础数据库支持,则使用序列。 如果当前数据库不支持序列,它将切换为使用表来生成序列值。 当以前的生成器具有预定义的优化算法时,可以使用优化器策略配置增强型生成器:
  • none :没有应用优化策略,因此从数据库中获取每个标识符
  • hi / lo :它使用原始的hi / lo算法。 这种策略使其他系统难以共享相同的标识符序列,从而要求其他系统实现相同的标识符生成逻辑。
  • pooled :此优化器使用高/低优化策略,但不保存当前的hi值,而是存储当前范围的上边界(或下边界– hibernate.id.optimizer.pooled.prefer_lo )。

池化是默认的优化器策略。

表格生成器 与MultipleHiLoPerTableGenerator一样,它可以将一个表用于多个标识符生成器,​​同时提供可配置的优化器策略。

池化是默认的优化器策略。

JPA到Hibernate标识符映射

拥有如此丰富的生成器,我们不禁要问哪个被用作默认的JPA生成器。

尽管JPA规范并不意味着任何特定的优化,但Hibernate宁愿选择一种优化的生成器,而不是总是为每个新标识符访问数据库的优化生成器。

JPA

我们将定义一个配置有SEQUENCE JPA标识符生成器的实体。 单元测试将保留五个这样的实体。

@Entity(name = "sequenceIdentifier")
public static class SequenceIdentifier {@Id@GeneratedValue(generator = "sequence", strategy=GenerationType.SEQUENCE)@SequenceGenerator(name = "sequence", allocationSize = 10)private Long id;
}@Test
public void testSequenceIdentifierGenerator() {LOGGER.debug("testSequenceIdentifierGenerator");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][]} 
Generated identifier: 10, using strategy: org.hibernate.id.SequenceHiLoGenerator
Generated identifier: 11, using strategy: org.hibernate.id.SequenceHiLoGenerator
Generated identifier: 12, using strategy: org.hibernate.id.SequenceHiLoGenerator
Generated identifier: 13, using strategy: org.hibernate.id.SequenceHiLoGenerator
Generated identifier: 14, using strategy: org.hibernate.id.SequenceHiLoGenerator
Query:{[insert into sequenceIdentifier (id) values (?)][10]} 
Query:{[insert into sequenceIdentifier (id) values (?)][11]} 
Query:{[insert into sequenceIdentifier (id) values (?)][12]} 
Query:{[insert into sequenceIdentifier (id) values (?)][13]} 
Query:{[insert into sequenceIdentifier (id) values (?)][14]}

Hibernate选择使用遗留的SequenceHiLoGenerator来向后兼容发行增强型生成器之前开发的所有那些应用程序。 将旧版应用程序迁移到新生成器上并非易事,因此,增强的生成器是新应用程序的更好替代方案。

默认情况下,Hibernate更喜欢使用“ seqhilo”生成器,这不是一个直观的假设,因为许多人可能期望使用原始的“ sequence”生成器(总是为每个新的标识符值调用数据库序列)。

为了启用增强的生成器,我们需要设置以下Hibernate属性:

properties.put("hibernate.id.new_generator_mappings", "true");

给我们以下输出:

Query:{[call next value for hibernate_sequence][]} 
Query:{[call next value for hibernate_sequence][]} 
Generated identifier: 1, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator
Generated identifier: 2, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator
Generated identifier: 3, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator
Generated identifier: 4, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator
Generated identifier: 5, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator
Query:{[insert into sequenceIdentifier (id) values (?)][1]} 
Query:{[insert into sequenceIdentifier (id) values (?)][2]} 
Query:{[insert into sequenceIdentifier (id) values (?)][3]} 
Query:{[insert into sequenceIdentifier (id) values (?)][4]} 
Query:{[insert into sequenceIdentifier (id) values (?)][5]}

新的SequenceStyleGenerator生成的标识符值不同于旧的SequenceHiLoGenerator。 新旧生成器之间的更新语句之所以不同,是因为新生成器的默认优化器策略是“池”的,而旧生成器只能使用“ hi / lo”策略。

JPA

@Entity(name = "tableIdentifier")
public static class TableSequenceIdentifier {@Id@GeneratedValue(generator = "table", strategy=GenerationType.TABLE)@TableGenerator(name = "table", allocationSize = 10)private Long id;
}

运行以下测试:

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

生成以下SQL语句输出:

Query:{[select sequence_next_hi_value from hibernate_sequences where sequence_name = 'tableIdentifier' for update][]} 
Query:{[insert into hibernate_sequences(sequence_name, sequence_next_hi_value) values('tableIdentifier', ?)][0]} 
Query:{[update hibernate_sequences set sequence_next_hi_value = ? where sequence_next_hi_value = ? and sequence_name = 'tableIdentifier'][1,0]} 
Generated identifier: 1, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator
Generated identifier: 2, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator
Generated identifier: 3, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator
Generated identifier: 4, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator
Generated identifier: 5, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator
Query:{[insert into tableIdentifier (id) values (?)][1]} 
Query:{[insert into tableIdentifier (id) values (?)][2]} 
Query:{[insert into tableIdentifier (id) values (?)][3]} 
Query:{[insert into tableIdentifier (id) values (?)][4]} 
Query:{[insert into tableIdentifier (id) values (?)][5]}

与前面的SEQUENCE示例一样,Hibernate使用MultipleHiLoPerTableGenerator来保持向后兼容性。

切换到增强的id生成器:

properties.put("hibernate.id.new_generator_mappings", "true");

给我们以下输出:

Query:{[select tbl.next_val from hibernate_sequences tbl where tbl.sequence_name=? for update][tableIdentifier]} 
Query:{[insert into hibernate_sequences (sequence_name, next_val)  values (?,?)][tableIdentifier,1]} 
Query:{[update hibernate_sequences set next_val=?  where next_val=? and sequence_name=?][11,1,tableIdentifier]} 
Query:{[select tbl.next_val from hibernate_sequences tbl where tbl.sequence_name=? for update][tableIdentifier]} 
Query:{[update hibernate_sequences set next_val=?  where next_val=? and sequence_name=?][21,11,tableIdentifier]} 
Generated identifier: 1, using strategy: org.hibernate.id.enhanced.TableGenerator
Generated identifier: 2, using strategy: org.hibernate.id.enhanced.TableGenerator
Generated identifier: 3, using strategy: org.hibernate.id.enhanced.TableGenerator
Generated identifier: 4, using strategy: org.hibernate.id.enhanced.TableGenerator
Generated identifier: 5, using strategy: org.hibernate.id.enhanced.TableGenerator
Query:{[insert into tableIdentifier (id) values (?)][1]} 
Query:{[insert into tableIdentifier (id) values (?)][2]} 
Query:{[insert into tableIdentifier (id) values (?)][3]} 
Query:{[insert into tableIdentifier (id) values (?)][4]} 
Query:{[insert into tableIdentifier (id) values (?)][5]}

您可以看到这次使用了新的增强型TableGenerator 。

有关这些优化策略的更多信息,请阅读原始发行说明 。

  • 代码可在GitHub上获得 。

翻译自: https://www.javacodegeeks.com/2014/07/from-jpa-to-hibernates-legacy-and-enhanced-identifier-generators.html

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

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

相关文章

快速了解AngularJs HTTP响应拦截器

任何时候&#xff0c;如果我们想要为请求添加全局功能&#xff0c;例如身份认证、错误处理等&#xff0c;在请求发送给服务器之前或服务器返回时对其进行拦截&#xff0c;是比较好的实现手段。 angularJs通过拦截器提供了一个从全局层面进行处理的途径。 四种拦截器 实现 req…

U盘专杀工具,U盘防御软件,U盘病毒防火墙--UDiskSyS

近来闲聊无事&#xff0c;写了一款专门针对U盘的防御软件&#xff0c;U盘插入后自动扫描并清除病毒并还原被感染的文件。是常见的文件夹伪装病毒&#xff0c;死亡应答病毒&#xff0c;exe感染型病毒的克星。UDiskSyS不像那些所谓的正规杀毒软件遇到搞不定的病毒统统删除之&…

CenterNet算法笔记(目标检测论文)

论文名称&#xff1a;CenterNet: Keypoint Triplets for Object Detectiontection 论文链接&#xff1a;https://arxiv.org/abs/1904.08189 代码链接&#xff1a;https://github.com/Duankaiwen/CenterNet 简介 该论文是由中科院&#xff0c;牛津大学以及华为诺亚方舟实验室联合…

git提交代码时报错:nothing added to commit but untracked files present

原因&#xff1a; git没有把提交的文件加载进来&#xff0c;报红色的是需要提交的文件&#xff0c; 解决步骤&#xff1a; 用git add XXX(文件名) 把提示报红色的文件加上git commit -m “xx”git push -u origin master重新提交就可以了

VSS使用手册

1 VSS概述 版本控制是工作组软件开发中的重要方面&#xff0c;它能防止意外的文件丢失、允许反追踪到早期版本、并能对版本进行分支、合并和管理。在软件开发和您需要比较两种版本的文件或找回早期版本的文件时&#xff0c;源代码的控制是非常有用的。Visual SourceSafe 是一种…

语句和函数

1.for-in语句&#xff1a;是一种精准的迭代语句&#xff0c;可以用来枚举对象的属性。 2.label语句&#xff1a;在代码中添加标签&#xff0c;以便将来使用&#xff0c;由break和continue语句调用。3.with语句&#xff1a;将代码的作用域设置到一个特定的对象中。一般不建议过多…

服务器与客户端渲染(AngularJS与服务器端MVC)

关于服务器与客户端应用程序渲染的讨论很多。 虽然没有“一刀切”的解决方案&#xff0c;但我将尝试从不同的角度主张客户端&#xff08;特别是AngularJS&#xff09;。 首先是建筑。 建筑 做得好的架构已经明确定义了关注点分离&#xff08;SoS&#xff09; 。 在大多数情况下…

MySQL 数据类型简介 创建数据表及其字段约束

数据类型介绍 MySQL 数据类型分类 整型浮点型字符类型(char与varchar)日期类型枚举与集合具体数据类型见这篇博客 MySQL表操作中的约束 primary key 主键约束 非空唯一unique key 唯一约束not null 非空约束foreign key 外键约束创建表的的语法 CREATE TABLE[IF NOT EXISTS] tb…

elementUI的container布局设置全屏宽度

进用element UI的 container 布局&#xff0c;发现不能全屏铺满 添加了一行代码&#xff1a; .el-container{height:100%;padding:0;margin:0;width:100%;}发现高度占满全屏&#xff0c;但是宽度还没有 继续给 html,body加了 width&#xff1a;100%&#xff1b;还是没有任何…

【转】首次敏捷项目开发实践

首次采用敏捷方式进行开发&#xff0c;我想把我们的做法与大家分享下&#xff0c;同时希望大家指出我们的不足和需要改进的地方&#xff0c;让我们的项目进行的更顺利&#xff0c;目前项目已过三分之一&#xff0c;客户比较满意&#xff0c;还算顺利。项目简介&#xff1a;一个…

CSS border-radius边框圆角

在CSS3中提供了对边框进行圆角设定的支持&#xff0c;可对边框1~4个角进行圆角样式设置。 目录 1. 介绍 2. value值的格式和类型 3. border-radius 1~4个参数说明 4. 在线示例 1. 介绍 1.1 圆角属性 CSS3提供了5种圆角属性 border-radius &#xff1a;同时设置4个边框的…

element实现动态路由+面包屑

要掌握&#xff1a;localStorage&#xff0c;组件封装 ​​​​ emm&#xff0c;第一次上传视频转gif的图片&#xff0c;效果不咋好。。。 视频转gif 的软件连接 http://www.zxt2007.com/downloads.html 找到一个可以截取部分视频制作gif图的软件https://soft.onlinedo.cn/gif…

Matlab——矩阵运算 矩阵基本变换操作

矩阵运算 加 - 减 .* 乘 ./ 左除 .\ 右除 .^ 次方 . 转置 除了加减符号&#xff0c;其余的运算符必须加“.” >> a 1:5a 1 2 3 4 5>> a-2 %减法ans -1 0 1 2 3 >> 2.*a-1 %乘法 减法ans 1 3 5 7 9 >&g…

Oracle最新的Java 8更新破坏了您的工具-它是如何发生的?

如果您最近一直在关注Java世界的消息&#xff0c;那么您可能听说过Oracle发布的最新Java 8构建&#xff0c;Java 8u11&#xff08;和Java 7u65&#xff09;引入了错误并破坏了一些流行的第三方工具&#xff0c;例如ZeroTurnaround的JRebel&#xff0c;Javassist&#xff0c;Goo…

为什么选择Dojo - 记Dojo中文博客正式开张

公告栏里写到&#xff1a;Dojo的高门槛一旦跨过&#xff0c;必将别无所求。含义有二&#xff1a;第一&#xff0c;Dojo难学&#xff1b;第二&#xff0c;Dojo很强大。 这也揭示了本博客的目标&#xff1a;帮助大家用好Dojo这个优秀的Ajax框架。 在回答为什么选择Dojo之前&#…

ExtJS 4.2 第一个程序

本篇介绍如何创建一个ExtJS应用程序。并通过创建目录、导入文件、编写代码及分析代码等步骤来解释第一个ExtJS程序。 目录 1. 创建程序 1.1 创建目录建议 1.2 实际目录 1.3 index.html 1.4 运行图 2. 代码分析 2.1 Ext.onReady() 2.2 Ext.create() 1. 创建程序 1.1 创建目录…

ZooKeeper,策展人以及微服务负载平衡的工作方式

Zookeeper如何确保每位工人都能愉快地从工作委托经理那里得到一些工作。 Apache ZooKeeper是注册&#xff0c;管理和发现在不同计算机上运行的服务的工具。 当我们必须处理具有许多节点的分布式系统时&#xff0c;它是技术堆栈中必不可少的成员&#xff0c;这些节点需要知道其…

elementUI清空弹框中的表单数据

点击此处直达应用场景示例 官网&#xff1a;https://element.eleme.cn/#/zh-CN/component/form 补充&#xff1a;改变表头颜色&#xff1a; <el-table :data"tableData" border style"width: 100%" :header-cell-style"{background:#d3dce6,col…

(一)PHP基础知识考察点

1&#xff0c;PHP引用变量的考察点&#xff1a; 概念&#xff1a;引用就是用不同的名字访问同一个变量内容。 定义方式&#xff1a; 使用&符号。 PHP引用变量的工作原理 这里有个COW copy on write 用zval&#xff08;&#xff09;去查看空间占用情况以及引用情况。 unse…

.Net4.0 Parallel编程(三)Data Parallelism下

在上篇文章中介绍了如何Break、Stop循环&#xff0c;以及如何定义线程局部变量。在本文中介绍如何在外部去取消循环、以及异常的处理。 Cancel 在并行的循环中支持通过传递ParallelOptions参数中的CancellationToken进行取消循环的控制&#xff0c;我们可以CancellationTokenSo…