hibernate 标识符_Hibernate中的标识符

hibernate 标识符

Hibernate中的标识符为实体的主键属性建模。 它有助于我们唯一地标识JPA实体。 每个实体都必须定义一个标识符。 同样,它可以是简单的也可以是复合的。

我们可以通过几种方式定义一个Hibernate标识符。 在本教程中,我们将学习如何做。

简单(单值)标识符:

如果我们有一个可以唯一标识我们实体的属性,则可以使用@Id注释对该属性进行简单注释:

Java

@Entity
public class Employee {@Idprivate Integer empId;...
}

请记住,用@Id注释的属性应为以下类型之一:

  • 任何Java基本类型或任何原始包装器类型
  • 任何Java 日期类型,或者
  • BigDecimalBigInteger

简单生成的标识符:

如果我们希望自动生成ID值怎么办? 为此,我们可以更进一步,在标识符字段上使用@GeneratedValue批注:

Java

@Entity
public class Employee {@Id@GeneratedValuepublic Integer empId;...
}

当使用@GeneratedValue时 ,Hibernate在保留实体的同时会为我们的id列生成值。 对我们而言,重要的是要记住, 我们只能自动生成整数类型( int,shortlong )或UUID

此外,我们提供了四种不同的密钥生成策略,可自动生成标识符的值:

Hibernate使用AUTO密钥生成策略作为默认策略。 从一个JPA持久性提供者到另一个JPA持久性提供者, AUTO策略的行为略有不同。 对于 Hibernate,如果 identifier属性的类型为UUID,则它使用UUIDGenerator或默认为序列生成策略。

仅在Hibernate 5和更高版本中支持UUID生成,并且长度为36个字符:

Java

@Entity
public class Employee {@Id@GeneratedValueprivate UUID empId;...
}

生成的UUID的格式为“ 4ee5a777-7981-4e01-06ab-19aabb2eaa122”。

对于IDENTITY生成策略,Hibernate使用IdentityGenerator生成标识符值 这些值由数据库的标识列生成,并自动递增:

Java

@Entity
public class Employee {@Id@GeneratedValue (strategy = GenerationType.IDENTITY)private Integer empId;...
}

使用此策略的主要缺点是它不支持批量JDBC插入。

在这里,顾名思义,数据库序列用于生成我们的标识符的值。 Hibernate在内部使用SequenceStyleGenerator类来实现它。 如果我们的数据库不支持序列,它将自动切换到TABLE密钥生成策略。

SEQUENCE生成器为每个序列生成唯一的值。 我们可以指定我们希望使用的数据库顺序:

Java

@Entity
public class Employee {@Id@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "emp_generator")@SequenceGenerator(name = "emp_generator",sequenceName = "emp_seq", allocationSize = 100)public Integer empId;...
}

否则,Hibernate将使用隐式命名的序列hibernate_sequence

Java

@Entity
public class Employee {@Id@GeneratedValue(strategy = GenerationType.SEQUENCE)public Integer empId;...
}

为我们的标识符字段生成值。

Hibernate TableGenerator使用一个表,该表能够保存标识符生成值的多个段。 除非指定,否则Hibernate默认使用hibernate_sequences表:

Java

@Entity
public class Employee {@Id@GeneratedValue(strategy = GenerationType.TABLE)public Integer empId;...
}

我们可以使用@TableGenerator来指定用于生成值的数据库表:

Java

@Entitypublic class Employee {@Id@GeneratedValue(strategy = GenerationType.TABLE, generator = "emp_generator") @TableGenerator(name = "emp_generator",table = "emp_generator_tbl",schema = "employees")public Integer empId;...}

TABLE策略的伸缩性不是很好,而且性能很差,因此在实际的实现中很少使用。 对于所有支持序列的数据库,我们应该始终偏向于使用SEQUENCE生成策略,而大多数现代数据库通常都会这样做。

复合标识符:

Hibernate还允许我们定义一个复合标识符。 要定义组合标识符,我们创建一个主键类,其中包含构成组合键的持久属性。 根据JPA规范, 我们的主键类必须为:

  1. @EmbeddedId@IdClass注释进行注释
  2. 公开并有一个公开的无参数构造函数
  3. 可序列化
  4. 实现equals()hashCode()方法

组成合成的属性可以是basic,composite或ManyToOne。 但是,集合和OneToOne属性被认为不合适。

1.使用

定义和使用复合键的一种方法是使用@EmbeddedId批注

因此,让我们开始定义主键类并使用@Embeddable对其进行注释

Java

@Embeddable
public class EmployeePurchasesPK implements Serializable {private long empId;private long productId;//equals() and hashCode() methods...
}

现在,我们可以使用@EmbeddedId批注轻松地从我们的实体中引用此类:

Java

@Entity
public class EmployeePurchases {@EmbeddedIdprivate EmployeePurchasesPK primaryAttributes;...
}

要使用我们的实体类设置或检索主键属性,我们将具有以下内容:

Java

EmployeePurchasesPK primaryAttributes = new EmployeePurchasesPK();
primaryAttributes.setEmpId(1001);
primaryAttributes.setProductId(7822);EmployeePurchases empPurchases = new EmployeePurchases();
empPurchases.setPrimaryAttributes(primaryAttributes);
...

显然,我们的EmployeePurchases实体具有一个由empIdproductId组成的复合键。

2.使用

使用@IdClass创建复合键时可以使用@Id批注在主类中定义所有合成属性。 我们的主键类中的代码保持原样,但仅充当“影子”

Java

@Entity
@IdClass(EmployeePurchasesPK.class)
public class EmployeePurchases {@Idprivate long empId;@Idprivate long productId;...}

通过这种方法,我们可以使用主要实体类的getter / setter方法直接设置键值:

Java

EmployeePurchases empPurchases = new EmployeePurchases(); 
empPurchases.setEmpId(1011);
empPurchases.setProductId(9331);
...

但是,此方法无法为我们提供标识符和实体对象之间的清晰区分。

派生标识符:

在Hibernate中,我们可以选择使用@MapsId注释从其关联之一复制实体的标识符值

Java

public class EmployeeHistory {@Idprivate long id;@OneToOne@MapsIdprivate Employee employee;...}

在这里,我们的EmployeeHistory实例将具有与相应Employee实例完全相同的ID

结论:

在本教程中,我们研究了在Hibernate中定义标识符的多种方法。 我们还介绍了不同的关键自动生成策略。

成为第一个发表评论的人。

翻译自: https://www.javacodegeeks.com/2019/04/identifiers-hibernate.html

hibernate 标识符

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

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

相关文章

java中延迟_Java中的延迟分配

java中延迟程序员本质上是懒惰的,而similis simili gaudet就像程序是懒惰的一样。 您听说过延迟加载吗? 还是懒惰的单身人士? (不过,我个人更喜欢单一麦芽版本。)如果使用Scala或Kotlin(这也是一…

camel apache_短款Apache Camel K

camel apache您可能已经看到我们在Camel K周围的Apache Camel社区中所做的工作。 Nicola于半年前在他的博客中介绍了Camel K , 就在几个月前,我们正在讨论一个新项目,该项目可以作为Apache Camel的一部分启动。 一个有可能改变人们处理集成方…

java 栈 队列 接口_Java队列接口

java 栈 队列 接口介绍: 队列是FIFO(先进先出)抽象数据类型(ADT)。 换句话说,按插入顺序将元素删除。 java.util.Queue是Java 中的接口,并且从java.util.Collection扩展。 一些常用的Queue实现…

jakarta ee_Jakarta EE 8状态

jakarta ee遵循Jakarta EE的人们可能知道即将发布的Jakarta EE 8在功能上将与Java EE 8等效。其原因是我们想证明从Oracle的传输已经完成,并且我们能够产生这些流程,规范,测试套件以及通过Eclipse Foundation的兼容实现。 到目前为止&#x…

IntelliJ IDEA如何查看接口的实现类以及如何查看被实现的接口

在接口的左边有个向下的小箭头,点击小箭头就能看到接口的实现类和方法的实现: 在实现类的左边有个向上的小箭头,可以查看被实现的接口和被覆盖重写的方法:

c#自定义控件资源释放问题_定义资源

c#自定义控件资源释放问题在Fielding的论文中 ,资源描述为: “可以命名的任何信息”……“文档或图像,临时服务(例如,“洛杉矶今天的天气”),其他资源的集合,非虚拟对象&#xff08…

MySQL数据库存入日期(java.sql.Date)数据,天数会少一天的问题

网络上给的解决办法: 这是数据库服务器时区的问题,即连接参数 serverTimezone 的问题,默认情况下 serverTimezoneUTC,改成 HongKong 或者 Asia/Shanghai 就可以了。如下所示: jdbc:mysql://localhost:3306/test?useU…

spring的bean范围_Spring Bean范围

spring的bean范围介绍: Spring核心容器实例化bean并管理其生命周期。 在定义bean时,我们可以提供其范围。 除非明确提供,否则单例是Spring容器中Bean的默认范围。 Spring提供了五种类型的bean作用域。 在本教程中,我们将探讨它们…

java.util.Date转换成java.sql.Date

// 获取当前的系统时间,以java.util.Date对象返回 Date dateUtil new Date(); // 获取当前的系统时间,以时间戳返回 long l System.currentTimeMillis();时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现…

省编码市编码区县编码_无浪费编码

省编码市编码区县编码本文介绍了如何通过减少软件堆栈中的浪费来高效解决有意义的事件处理问题。 Java通常被视为无法在低内存环境中有效运行的内存猪。 目的是证明许多人认为不可能的事情,有意义的java程序几乎可以在没有内存的情况下运行。 示例流程 在Java的单…

Java日期时间字符串和毫秒相互转换的方法

参考链接: 1.https://www.jb51.net/article/130195.htm 2.https://blog.csdn.net/yhj19920417/article/details/73799842?locationNum10&fps1

谷歌本地不支持websocket_django开发-websocket的实现

今天介绍下如何在django中使用channels实现websocket。其实还可以使用dwebsocket实现websocket,这里不做介绍。首先介绍一个概念ASGI。ASGI异步网关协议接口,一个介于网络协议服务和Python应用之间的标准接口,能够处理多种通用的协议类型&…

我要正式开始《一个项目征服Java中高级体系》

在互联网上经常看到很多人说35岁危机的问题、大厂裁员、互联网寒冬这些问题。我感觉比较幸运的是,在之前大环境还不是很坏时候就被裁了一次,所以我很早就开始做持续的准备,现在不好说一定能怎么样, 至少自己在持续的探索适合自己的…

cuba 平台_CUBA 7的新功能

cuba 平台三年前,我们宣布了该框架的第二个公开可用的主要版本。 CUBA 6是改变游戏规则的版本–许可从专有转为Apache 2.0。 那些日子,我们甚至无法猜测从长远来看它将把框架带到哪里。 CUBA社区开始呈指数级增长,因此我们了解了开发人员如何…

java.util.Date详解

获取当前的系统时间: Date date new Date();获取毫秒数: long time date.getTime();毫秒数转成 Date 对象: long l 23434324324343L; Date date new Date(l);比较两个 Date 对象: SimpleDateFormat sdf new SimpleDateFo…

夸克代码_关于夸克的思考

夸克代码Quarkus,新的“超音速,亚原子” Java框架目前正受到广泛关注。 对于企业Java的未来而言,此构建和运行时工具背后的思想确实比我们感兴趣。 使用Quarkus有什么好处和缺点? 摆脱动力 Quarkus认为,在容器化的世…

ntdll 异常代码0xc0000374_不要把异常当做业务逻辑,这性能可能你无法承受

一:背景1. 讲故事在项目中摸爬滚打几年,应该或多或少的见过有人把异常当做业务逻辑处理的情况(┬_┬),比如说判断一个数字是否为整数,就想当然的用try catch包起来,再进行 int.Parse,如果抛异常就说明不是整…

java中的hashset_Java中的HashSet

java中的hashset介绍: Java中的HashSet实现Set接口,即它不允许重复。 它在内部由HashMap支持,该哈希表基于哈希原理。 我们可以在HashSet中存储一个空值。 默认容量为16,负载系数为0.75,其中: Load facto…

win32bridge.server.exe函数不正确_修电脑?不,其实我们学的是......

COMPUTER计信学子Python?JAVA?C?C?HTML?身为重师计信人逢年过节总免不了被亲戚们“盘问”一番必问清单第一名就是“专业”他们往往从字面去理解而我们计信人被误解的频率相当高“学计算机的肯定会修电脑对吧”请接着看下去吧!我们学的到底是什么?(点击查看答案…

SimpleDateFormat详解

SimpleDateFormat 中的时间标识含义: G 年代标志符 y 年 M 月 d 日 h 时 在上午或下午 (1~12) H 时 在一天中 (0~23) m 分 s 秒 S 毫秒 E 星期 D 一年中的第几天 F 一月中第几个星期几 w 一年中第几个星期 W 一月中第几个星期 a 上午 / 下午 标记符 k 时 在一天中 …