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

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 :此优化器使用了一个高/低优化策略,但是不是保存当前的高值,而是存储当前范围的上边界(或下边界– 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

jpa和hibernate

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

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

相关文章

去掉前后空格_mysql批量去掉某个字段字符中的空格

mysql有什么办法批量去掉某个字段字符中的空格&#xff1f;不仅是字符串前后的空格&#xff0c;还包含字符串中间的空格&#xff0c;答案是 replace&#xff0c;使用mysql自带的 replace 函数&#xff0c;另外还有个 trim 函数。 &#xff08;1&#xff09;mysql replace 函数 …

python自己做个定时器_技术图文:如何利用 Python 做一个简单的定时器类?

原标题&#xff1a;技术图文&#xff1a;如何利用 Python 做一个简单的定时器类&#xff1f;背景今天在B站上看有关 Python 最火的一个教学视频 -- “零基础入门学习 Python”&#xff0c;这也是我们 Python基础刻意练习活动 的推荐视频教程。python视频在学习魔法方法的时候&a…

成为Java流大师–第6部分:使用流创建新的数据库应用程序

您是否曾经想开发数据库应用程序的“快速”版本&#xff1f; 在此动手实验文章中&#xff0c;您将学习一种真正简单而直接的方法。 整个Java域模型将自动为您生成。 您只需连接到现有数据库&#xff0c;然后开始使用Java流进行开发。 例如&#xff0c;您将能够在几分钟内为您现…

快速排序 挖坑_由浅入深玩转快速排序算法

由浅入深玩转快速排序算法快速排序可以说是最快的通用排序算法&#xff0c;它甚至被誉为20世纪科学和工程领域的十大算法之一。在众多排序算法中其无论是时间复杂度还是空间复杂度都颇具优势。作为开发工程师&#xff0c;我们很有必要了解它的思想。接下来将由在下为大家一步步…

代码拾取图片某一点的颜色_RPG游戏开发日志7:道具拾取与存放

本项目同步上传于github和coding上&#xff0c;国内读者可以通过在coding下载项目。也欢迎你加入我的UE4学习交流QQ群&#xff1a;872537977。如果你喜欢我写的文章&#xff0c;也希望你点赞、收藏、转发。谢谢&#xff01;如果你喜欢我写的文章&#xff0c;也希望你点赞、收藏…

使用sstableloader恢复Cassandra Priam备份

之前&#xff0c;我曾写过关于设置Cassandra和Priam进行备份和集群管理的文章。 但是&#xff0c;我在此处提供的用于备份还原的示例并不适用于所有情况&#xff0c;例如&#xff0c;它可能不适用于完全独立的群集。 或者在部分还原到一个表而不是整个数据库的情况下。 在这种…

abp vue如何配置服务地址_DHCP服务如何配置才能尽量减少被攻击的可能

DHCP Snooping是啥&#xff1f;DHCP Snooping是DHCP的一种安全特性&#xff0c;用来保证DHCP客户端能够正确的从DHCP服务器获取IP地址&#xff0c;防止网络中针对DHCP的攻击。DHCP Snooping是如何防止DHCP攻击的呢&#xff1f;DHCP&#xff0c;动态主机配置协议&#xff0c;在I…

通达信缠论买卖点公式_通达信缠论多空主图指标公式

1.高位无量就拿&#xff0c;就算拿错了也要拿着。高位就是说股价处于或者接近历史的最高位。高位无量横盘&#xff0c;是非常典型的上涨中继形态之一&#xff0c;高位的窄幅箱型振荡。2.高位放量出现就要跑,哪怕是跑错也要跑。股价在已经过了一段时间比较大的涨幅后&#xff0c…

python服务器搭建 实战_实战讲解:如何用Python搭建一个服务器

有人说表示只学Python没有用&#xff0c;必须学会一个框架(比如Django和web.py)才能找到工作。其实掌握一个类似于框架的高级工具是有用的&#xff0c;但是基础的东西可以让你永远不被淘汰&#xff0c;不要被工具限制了自己的发展。今天不使用框架&#xff0c;也不使用Python标…

多节锂电串联保护板ic_如何有效保护锂电池板,一款优质的MOS管就能解决

锂电池几乎应用于我们日常接触到的各类电器之中&#xff0c;但如何保护锂电池&#xff0c;你又是否知道呢&#xff1f;其实在锂电池保护板&#xff0c;最主要的元器件是IC与MOS。MOS对锂电池板的保护作用非常大&#xff0c;它可以检测过充电&#xff0c;检测过放电&#xff0c;…

使用Java 8 Lambda表达式将实体映射到DTO

当我们需要将DTO转换为实体&#xff08;Hibernate实体等&#xff09;并向后转换时&#xff0c;我们都会面临混乱的开销代码。 在我的示例中&#xff0c;我将用Java 8演示代码如何变得越来越短。 让我们创建目标DTO&#xff1a; public class ActiveUserListDTO {public Acti…

使用pp架构形成计算机集群请求的地址无效_干货!史上最详细脑图《大型网站技术架构》...

1. 介绍一下《大型网站技术架构》这本书可能很多人都看过&#xff0c;小编个人觉得真的是非常不错的一本书。看完这本书后&#xff0c;你会对如何设计大型网站架构&#xff0c;有非常清晰的思路。如果还没有读过的小伙伴&#xff0c;赶紧去读一读吧。PS&#xff1a;小编这里有这…

linux 启动rsyslog服务_linux rsyslog服务部署

软件安装在centos7&#xff0c;rsyslog默认安装&#xff0c;重点在于配置文件。[rootlocalhost samba]# vim /etc/rsyslog.conf$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)$ModLoad imjournal # provides access to the systemd…

泰坦尼克号数据_数据分析-泰坦尼克号乘客生存率预测

项目背景目标预测一个乘客是否能够在泰坦尼克号事件中幸存。概述1912年4月15日&#xff0c;泰坦尼克号在首次航行期间撞上冰山后沉没&#xff0c;船上共有2224名人员&#xff08;包括乘客和机组人员&#xff09;&#xff0c;共有1502人不幸遇难。造成海难失事的原因之一是乘客和…

linux mysql服务器安装_Linux服务器MySQL安装

Linux服务器MySQL安装1. MySQL官网下载如图&#xff1a;2. 安装MySQL[rootiZ2zebb0428roermd00462Z /]# rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch#过滤MySQL&#xff1a;[rootiZ2zebb0428roermd00462Z /]#yum repolist all |grep mysql#ena…

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

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

python3 array为什么不能放不同类型的数据_来自俄罗斯的凶猛彪悍的分析数据库ClickHouse...

点击上方蓝色字体&#xff0c;选择“设为星标”回复”资源“获取更多资源大数据技术与架构点击右侧关注&#xff0c;大数据开发领域最强公众号&#xff01;暴走大数据点击右侧关注&#xff0c;暴走大数据&#xff01;ClickHouse相关文章推荐&#xff1a;战斗民族开源 | ClickHo…

php mysql 实现原理_PHP底层和mysql的通信原理

要清楚的几个概念&#xff1a;FPM进程&#xff1a;进程数在php-fpm.ini中设置。没有设置 max_requests &#xff0c;那么进程是不会销毁的&#xff0c;也就是说当一个进程里面出现死循环或者内存溢出等导致进程僵死的情况出现的时候&#xff0c;处理的进程就会少一个。mysql连接…

通过READ-BEHIND CACHE来控制缓慢的生产者

在我们的互联世界中&#xff0c;我们经常使用我们不拥有或无权改善的API中的数据。 如果一切顺利&#xff0c;他们的表现就会很好&#xff0c;每个人都会感到高兴。 但是太多次&#xff0c;我们不得不使用延迟小于最佳延迟的 API。 当然&#xff0c;答案是缓存该数据 。 但是&…

mysql用户名锁定_MySQL用户锁定

修改方式&#xff1a;set global log_warnings2;MySQL 5.5版本官方文档中&#xff0c;并没有用户锁的状态。因此不存在用户会被锁。。The account-locking capability depends on the presence of the account_locked column in themysql.user table. For upgrades to MySQL 5.…