Hibernate和UUID标识符

介绍

在我以前的文章中,我讨论了UUID代理密钥以及用例 , 这些用例比更常见的自动递增标识符更合适。

UUID数据库类型

有几种表示128位UUID的方法,每当有疑问时,我都希望向Stack Exchange寻求专家建议。



由于通常对表标识符进行索引,因此数据库类型越紧凑,索引所需的空间就越少。 从效率最高到最低,这是我们的选择:

  1. 某些数据库( PostgreSQL , SQL Server )提供专用的UUID存储类型
  2. 否则,我们可以将这些位存储为字节数组(例如,Oracle中的RAW(16)或标准BINARY(16)类型)
  3. 另外,我们可以使用2个bigint(64位)列,但是复合标识符的效率要比单个列低
  4. 我们可以将十六进制值存储在CHAR(36)列中(例如32个十六进制值和4个破折号),但这将占用最多的空间,因此这是效率最低的替代方法

Hibernate提供了许多标识符策略供您选择,对于UUID标识符,我们有三种选择:

  • 分配的生成器以及应用程序逻辑UUID生成
  • 十六进制“ uuid”字符串生成器
  • 更灵活的“ uuid2”生成器,允许我们使用java.lang.UUID ,16字节数组或十六进制String值

分配的发电机

分配的生成器允许应用程序逻辑控制实体标识符生成过程。 通过简单地省略标识符生成器定义,Hibernate将考虑分配的标识符。 此示例使用BINARY(16)列类型,因为目标数据库是HSQLDB 。

@Entity(name = "assignedIdentifier")
public static class AssignedIdentifier {@Id@Column(columnDefinition = "BINARY(16)")private UUID uuid;public AssignedIdentifier() {}public AssignedIdentifier(UUID uuid) {this.uuid = uuid;}
}

持久实体:

session.persist(new AssignedIdentifier(UUID.randomUUID()));
session.flush();

恰好生成一个INSERT语句:

Query:{[insert into assignedIdentifier (uuid) values (?)][[B@76b0f8c3]}

让我们看看发出合并时会发生什么:

session.merge(new AssignedIdentifier(UUID.randomUUID()));
session.flush();

这次我们同时获得了SELECT和INSERT:

Query:{[select assignedid0_.uuid as uuid1_0_0_ from assignedIdentifier assignedid0_ where assignedid0_.uuid=?][[B@23e9436c]} 
Query:{[insert into assignedIdentifier (uuid) values (?)][[B@2b37d486]}

persist方法采用一个临时实体,并将其附加到当前的Hibernate会话。 如果已经存在一个连接的实体,或者如果当前的实体是分离的,我们将得到一个异常。

合并操作会将当前对象状态复制到现有的持久实体(如果有)中。 此操作适用于临时实体和分离实体,但是对于临时实体持久化比合并操作有效得多。

对于分配的标识符,合并将始终需要进行选择,因为Hibernate无法知道是否已经存在具有相同标识符的持久实体。 对于其他标识符生成器,​​Hibernate会寻找一个空标识符,以判断该实体是否处于过渡状态。

这就是为什么Spring Data SimpleJpaRepository#save(S实体)方法不是使用分配的标识符的实体的最佳选择的原因:

@Transactional
public <S extends T> S save(S entity) {if (entityInformation.isNew(entity)) {em.persist(entity);return entity;} else {return em.merge(entity);}
}

对于分配的标识符,此方法将始终选择合并而不是持久化,因此对于每个新插入的实体,您将同时获得SELECT和INSERT。

UUID生成器

这次我们不会自己分配标识符,而是让Hibernate代表我们生成它。 当遇到一个空标识符时,Hibernate假定一个临时实体,为其生成一个新的标识符值。 这次,合并操作将不需要在插入过渡实体之前进行选择查询。

UUIDHexGenerator

UUID十六进制生成器是最早的UUID标识符生成器,​​它以“ uuid”类型注册。 它可以生成具有以下模式的32位十六进制UUID字符串值(也可以使用分隔符):8 {sep} 8 {sep} 4 {sep} 8 {sep} 4。

此生成器不符合IETF RFC 4122 ,它使用8-4-4-4-12数字表示。

@Entity(name = "uuidIdentifier")
public static class UUIDIdentifier {@GeneratedValue(generator = "uuid")@GenericGenerator(name = "uuid", strategy = "uuid")@Column(columnDefinition = "CHAR(32)")@Idprivate String uuidHex;
}

持久化或合并临时实体:

session.persist(new UUIDIdentifier());
session.flush();
session.merge(new UUIDIdentifier());
session.flush();

每个操作生成一个INSERT语句:

Query:{[insert into uuidIdentifier (uuidHex) values (?)][2c929c6646f02fda0146f02fdbfa0000]} 
Query:{[insert into uuidIdentifier (uuidHex) values (?)][2c929c6646f02fda0146f02fdbfc0001]}

您可以检出发送到SQL INSERT查询的字符串参数值。

UUIDGenerator

较新的UUID生成器符合IETF RFC 4122(变体2),并提供可插拔生成策略。 它以“ uuid2”类型注册,并且提供了更大的类型范围供您选择:

  • java.lang.UUID
  • 16字节数组
  • 十六进制字符串值
@Entity(name = "uuid2Identifier")
public static class UUID2Identifier {@GeneratedValue(generator = "uuid2")@GenericGenerator(name = "uuid2", strategy = "uuid2")@Column(columnDefinition = "BINARY(16)")@Idprivate UUID uuid;
}

持久化或合并临时实体:

session.persist(new UUID2Identifier());
session.flush();
session.merge(new UUID2Identifier());
session.flush();

每个操作生成一个INSERT语句:

Query:{[insert into uuid2Identifier (uuid) values (?)][[B@68240bb]} 
Query:{[insert into uuid2Identifier (uuid) values (?)][[B@577c3bfa]}

当我们配置@Id列定义时,此SQL INSERT查询正在使用字节数组。

  • 代码可在GitHub上获得 。

翻译自: https://www.javacodegeeks.com/2014/07/hibernate-and-uuid-identifiers.html

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

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

相关文章

应用宝苹果版_点赞应用ios版下载-点赞应用苹果版下载v1.1

《点赞应用》app是一款实用的视频生成器工具&#xff0c;用户可以利用它为自己的视频添加各种各样的点赞效果。应用内含有多种类型的模板&#xff0c;都是免费使用的&#xff0c;想要将你的视频变得更有趣吗&#xff1f;快来下载体验一下这款应用吧&#xff01;软件特色1、这个…

mysql+默认值+default_十六、MySQL 中数据类型的默认值 - default 约束-搜云库

MySQL 中&#xff0c;所有的数据类型&#xff0c;都可以显式或隐式的拥有默认值。我们可以使用 DEFAULT 约束显式的为列指定一个默认值。比如CREATE TABLE t1 (i INT DEFAULT -1,c VARCHAR(10) DEFAULT ,price DOUBLE(16,2) DEFAULT 0.00);在上面这条语句中&#xff0c;我们为 …

SQL即服务

自2007年以来&#xff0c;我一直在考虑这一点&#xff0c;大约在Amazon 推出 S3时。 我什至尝试实现了几次&#xff0c;但是在设计阶段之后就失败了。 我听说过一家初创公司&#xff0c;也曾尝试这样做&#xff0c;但也失败了 。 我仍然不确定是否可以这样做&#xff0c;但是它…

c++ vector 一部分_《JACS》:在富电子C-H键位点上实现光控活性聚合

可逆加成-断裂链转移(RAFT)自由基活性聚合是一种调控聚合物结构组成、分子量和分布的重要聚合方法&#xff0c;其中&#xff0c;光诱导电子/能量转移(PET)的RAFT聚合反应是一种更精确的调控手段&#xff0c;因而经常被用于设计具有复杂3D分子结构的聚合物。然而常规的PET-RAFT法…

phpmyadmin忘记mysql密码_忘记phpmyadmin密码怎么重置

忘记phpmyadmin密码怎么重置,新密码,教程,相关文章,重新启动,跳过忘记phpmyadmin密码怎么重置易采站长站&#xff0c;站长之家为您整理了忘记phpmyadmin密码怎么重置的相关内容。1、停止mysql服务&#xff1a;/etc/init.d/mysql stop2、跳过验证启动MySQL/usr/local/mysql/bin/…

java中避免空指针_在Java中避免空检查

java中避免空指针对于Java开发人员&#xff08;从初级到专家&#xff09;最糟糕的噩梦之一是空对象引用检查。 我很确定您已经看过几次这样的代码&#xff1a; public void addAddressToCustomer(Customer customer, Address newAddress){if ( cutomer null || newAddress n…

纵横免root框架打不开应用怎么办_很好用的软件多开神奇安卓欧皇十框架!!!...

欧皇十框架这是一款兼容安卓10的应用框架&#xff0c;轻松实现应用多开&#xff0c;可以完美免ROOT运行GG修改器&#xff0c;专为和平精英游戏设计&#xff0c;软件体积小&#xff0c;运行稳定。修改说明&#xff1a;1.支持更多应用游戏的多开、双开&#xff0c;使用更稳定、快…

用java和mysql开发网站怎么实现_如何用java开发一个网站?

java语言和类库&#xff1a;java语言是支持整个java技术的底层基础&#xff0c;java类库是随java语言Java 运行系统&#xff1a;主要指java虚拟机&#xff0c;负责将java与平台无关的中间代码翻译成本机的Java applet :Java applet 是用java语言编写的小应用程序&#xff0c;通…

Elasticsearch SQL

Elasticsearch引擎 Elasticsearch是当今许多生产部署中使用最广泛的搜索引擎之一。 它基于Lucene搜索库&#xff0c;它提供的主要功能之一是在Lucene之上的基于JSON的查询DSL&#xff0c;它提供了一种易于使用的机制来与搜索引擎进行交互。 但是&#xff0c;查询DSL非常特定于E…

电脑无internet访问_电脑中的代理服务器怎么设置 代理服务器设置方法 - 操作系统...

如何设置电脑中的代理服务器?对于代理服务器&#xff0c;可能大家对其并不是非常了解&#xff0c;其实代理服务器作为一种特殊的网络服务&#xff0c;可以代理网络用户去获取网络信息&#xff0c;提高浏览速度与效率&#xff0c;而且还可以突破自身IP的访问限制&#xff0c;访…

mysql先进后出_栈、队列中“先进先出”,“后进先出”的含义

展开全部先进先出(62616964757a686964616fe58685e5aeb931333433653339FIFO&#xff0c;first-in&#xff0c;first-out)为处理从队列或堆栈发出的程序工作要求的一种方法&#xff0c;它使最早的要求被最先处理。后进先出&#xff0c;从栈中取出数据项的顺序与将它们插入栈的顺序…

平台框架_从框架到平台

平台框架当我在十年前以Java开发人员的身份开始职业生涯时&#xff0c;该行业正经历着革命性的变化。 2003年发布的Spring框架Swift流行&#xff0c;并成为庞大的J2EE平台的严重挑战者。 经过过渡时间后&#xff0c;我很快发现自己赞成使用Spring框架而不是J2EE平台&#xff0c…

敲代码时如何快速移动光标_如何用 Linux 技巧大大提高工作效率?

前言Linux中的一些小技巧可以大大提高你的工作效率&#xff0c;本文就细数那些提高效率或者简单却有效的Linux技巧。命令编辑及光标移动这里有很多快捷键可以帮我们修正自己的命令。接下来使用光标二字代替光标的位置。删除从开头到光标处的命令文本ctrl u&#xff0c;例如&am…

Java 13:文本块

Java 13已交付了期待已久的多行字符串或Text Blocks 。 您不再需要连接跨越多行的字符串或转义特殊字符&#xff0c;这确实提高了代码的可读性。 文本块是一种预览语言功能 &#xff0c;这意味着必须使用--enable-preview标志在Java编译器和运行时中明确启用它们。 这是一个文…

java 异常练习题_java入门异常处理练习题问题

tppe大概方式&#xff1a;1、判断用户输入的类型是否正确&#xff0c;不正确捕获异常&#xff0c;把他包装成我自己定义的异常2、判断用户输入的数是多少2.1、如果是1&#xff0c;则打印“输入图书名称”&#xff0c;用户输入&#xff0c;定义一个Book类型的数组&#xff0c;然…

windows副本不是正版怎么办_盗版系统总是崩溃?别着急,让我来告诉你正版系统怎么下载...

电脑系统崩溃了怎么办&#xff1f;相信很多小伙伴都会选择重装系统&#xff0c;奈何自己又不会&#xff0c;只能搬到修电脑的地方&#xff0c;最后发现安装的还是盗版系统&#xff0c;不能登录微软账号不说&#xff0c;还会被捆绑安装一堆流氓软件&#xff0c;那么&#xff0c;…

java线程有几种状态_java线程的几种状态

java线程的几种状态导语&#xff1a;线程&#xff0c;有时被称为轻量级进程(Lightweight Process&#xff0c;LWP)&#xff0c;是程序执行流的最小单元。下面是Java线程的介绍&#xff0c;欢迎参考!新建&#xff1a;new一个Thread对象或者其子类对象就是创建一个线程&#xff0…

sudo spctl --master-disable_量大从优批发--阳离子聚丙烯酰胺--用于生活污水、

量大从优批发--阳离子聚丙烯酰胺--用于生活污水、wkkk量大从优批发--阳离子聚丙烯酰胺--用于生活污水、怎么来辨别聚丙烯酰胺到底是什么型号的呢&#xff1f;下面来介绍型号辨别的消防法。聚丙烯酰胺我们都知道聚丙烯酰基是昂贵的阳离子&#xff0c;其次是非离子聚丙烯酰胺&…

java 框架 例子_如何设计Java框架? –一个简单的例子

通过优锐课核心java学习笔记中&#xff0c;我们可以看到&#xff0c;码了很多专业的相关知识&#xff0c; 分享给大家参考学习。你可能对框架如何工作感到好奇&#xff1f; 这里将通过一个简单的框架示例来说明框架的思想。框架目标首先&#xff0c;为什么我们需要一个除普通库…

jboss eap_HawtIO在JBoss EAP上(第二部分)

jboss eap我刚刚发布了一篇关于在JBoss Wildfly 8.1上运行HawtIO的条目 。 从那篇文章中&#xff0c;您将了解HawtIO的出色表现 &#xff0c;以及它必须具备的所有 出色 插件&#xff0c;才能从单个仪表板管理基于JVM的技术……好吧…… hawt ……。 但是&#xff0c;出于上一…