1. Introduction
1.绪论
In this tutorial, we’ll learn about the basics of entities, along with various annotations that define and customize an entity in JPA.
在本教程中,我们将学习实体的基础知识,以及在JPA中定义和定制实体的各种注释。
2. Entity
2. 实体
Entities in JPA are nothing but POJOs representing data that can be persisted to the database. An entity represents a table stored in a database. Every instance of an entity represents a row in the table.
JPA中的实体不过是代表可以持久化到数据库的数据的POJOs。一个实体代表一个存储在数据库中的表。一个实体的每个实例都代表着表中的一行。
2.1. The Entity Annotation
2.1.Entity注释
Let’s say we have a POJO called Student, which represents the data of a student, and we would like to store it in the database:
假设我们有一个名为Student的POJO,它表示一个学生的数据,我们想把它存储在数据库中。
public class Student {
// fields, getters and setters
}
In order to do this, we should define an entity so that JPA is aware of it.
为了做到这一点,我们应该定义一个实体,让JPA知道它的存在。
So let’s define it by making use of the @Entity annotation. We must specify this annotation at the class level. We must also ensure that the entity has a no-arg constructor and a primary key:
所以让我们利用@Entity注解来定义它。我们必须在类的层次上指定这个注解。我们还必须确保该实体有一个无参数的构造函数和一个主键。
@Entity
public class Student {
// fields, getters and setters
}
The entity name defaults to the name of the class. We can change its name using the name element:
实体名称默认为类的名称。我们可以使用name元素来改变其名称。
@Entity(name="student")
public class Student {
// fields, getters and setters
}
Because various JPA implementations will try subclassing our entity in order to provide their functionality, entity classes must not be declared final.
因为各种JPA实现将尝试对我们的实体进行子类化以提供其功能,实体类不能被声明为final.。
2.2. The Id Annotation
2.2.Id注释
Each JPA entity must have a primary key that uniquely identifies it. The @Id annotation defines the primary key. We can generate the identifiers in different ways, which are specified by the @GeneratedValue annotation.
每个JPA实体都必须有一个主键来唯一地识别它。@Id注解定义了主键。我们可以以不同的方式生成标识符,这些标识符由@GeneratedValue注解指定。
We can choose from four id generation strategies with the strategy element. The value can be AUTO, TABLE, SEQUENCE, or IDENTITY:
我们可以通过strategy元素选择四种id生成策略。该值可以是AUTO、TABLE、SEQUENCE、或IDENTITY:。
@Entity
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
// getters and setters
}
If we specify GenerationType.AUTO, the JPA provider will use any strategy it wants to generate the identifiers.
如果我们指定GenerationType.AUTO,JPA提供者将使用它想要的任何策略来生成标识符。
If we annotate the entity’s fields, the JPA provider will use these fields to get and set the entity’s state. In addition to Field Access, we can also do Property Access or Mixed Access, which enables us to use both Field and Property access in the same entity.
如果我们注解了实体的字段,JPA提供者将使用这些字段来获取和设置实体的状态。除了字段访问,我们还可以进行属性访问或混合访问,这使得我们可以在同一个实体中同时使用字段和属性访问.。
2.3. The Table Annotation
2.3.表注解
In most cases, the name of the table in the database and the name of the entity won’t be the same.
在大多数情况下,数据库中的表的名称和实体的名称不会相同。
In these cases, we can specify the table name using the @Table annotation:
在这些情况下,我们可以使用@Table注解指定表名。
@Entity
@Table(name="STUDENT")
public class Student {
// fields, getters and setters
}
We can also mention the schema using the schema element:
我们也可以使用schema元素提及模式。
@Entity
@Table(name="STUDENT", schema="SCHOOL")
public class Student {
// fields, getters and setters
}
Schema name helps to distinguish one set of tables from another.
模式名称有助于将一组表与另一组表区分开来。
If we don’t use the @Table annotation, the name of the table will be the name of the entity.
如果我们不使用@Table注解,表的名字将是实体的名字。
2.4. The Column Annotation
2.4.Column注释
Just like the @Table annotation, we can use the @Column annotation to mention the details of a column in the table.
就像@Table注解一样,我们可以使用@Column注解来提及表中某列的细节。
The @Column annotation has many elements such as name, length, nullable, and unique:
@Column注解有许多元素,如name、length、nullable和unique。
@Entity
@Table(name="STUDENT")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(name="STUDENT_NAME", length=50, nullable=false, unique=false)
private String name;
// other fields, getters and setters
}
The name element specifies the name of the column in the table. The length element specifies its length. The nullable element specifies whether the column is nullable or not, and the unique element specifies whether the column is unique.
name 元素指定了表中的列的名称。length元素指定了它的长度。nullable元素指定该列是否为nullable,unique元素指定该列是否为唯一。
If we don’t specify this annotation, the name of the column in the table will be the name of the field.
如果我们不指定这个注解,表中的列名将是字段的名称。
2.5. The Transient Annotation
2.5.Transient注释
Sometimes, we may want to make a field non-persistent. We can use the @Transient annotation to do so. It specifies that the field won’t be persisted.
有时,我们可能想使一个字段变得不持久。我们可以使用@Transient注解来做到这一点。它指定该字段将不会被持久化。
For instance, we can calculate the age of a student from the date of birth.
例如,我们可以从出生日期计算出一个学生的年龄。
So let’s annotate the field age with the @Transient annotation:
因此,让我们用@Transient注解来注解字段年龄。
@Entity
@Table(name="STUDENT")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(name="STUDENT_NAME", length=50, nullable=false)
private String name;
@Transient
private Integer age;
// other fields, getters and setters
}
As a result, the field age won’t be persisted to the table.
因此,字段年龄将不会被持久化到表中。
2.6. The Temporal Annotation
2.6.时间性注解
In some cases, we may have to save temporal values in our table.
在某些情况下,我们可能必须在我们的表中保存时间性的值。
For this, we have the @Temporal annotation:
为此,我们有的@Temporal注释。
@Entity
@Table(name="STUDENT")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(name="STUDENT_NAME", length=50, nullable=false, unique=false)
private String name;
@Transient
private Integer age;
@Temporal(TemporalType.DATE)
private Date birthDate;
// other fields, getters and setters
}
However, with JPA 2.2, we also have support for java.time.LocalDate, java.time.LocalTime, java.time.LocalDateTime, java.time.OffsetTime and java.time.OffsetDateTime.
然而,在JPA 2.2中,我们还支持java.time.LocalDate、java.time.LocalTime、java.time.LocalDateTime、java.time.OffsetTime和java.time.OffsetDateTime。
2.7. The Enumerated Annotation
2.7.枚举式注释
Sometimes, we may want to persist a Java enum type.
有时,我们可能想持久化一个Java enum类型。
We can use the @Enumerated annotation to specify whether the enum should be persisted by name or by ordinal (default):
我们可以使用@Enumerated注解来指定enum应该按名称还是按序数(默认)来持久化。
public enum Gender {
MALE,
FEMALE
}
@Entity
@Table(name="STUDENT")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(name="STUDENT_NAME", length=50, nullable=false, unique=false)
private String name;
@Transient
private Integer age;
@Temporal(TemporalType.DATE)
private Date birthDate;
@Enumerated(EnumType.STRING)
private Gender gender;
// other fields, getters and setters
}
Actually, we don’t have to specify the @Enumerated annotation at all if we’re going to persist the Gender by the enum‘s ordinal.
实际上,如果我们要通过enum的序数来坚持Gender,我们根本不需要指定@Enumerated注释。
However, to persist the Gender by enum name, we’ve configured the annotation with EnumType.STRING.
然而,为了通过enum 名称来持久化Gender,我们在注释中配置了EnumType.STRING.。
3. Conclusion
3.总结
In this article, we learned what JPA entities are and how to create them. We also learned about the different annotations we can use to customize the entity further.
在这篇文章中,我们学习了什么是JPA实体以及如何创建它们。我们还了解了不同的注释,我们可以使用这些注释来进一步定制实体。
The complete code for this article can be found over on Github.
本文的完整代码可以在Github上找到over。