JPA 中保留非原始类型
在这篇文章中,我们将了解如何在 JPA 中保留非原始数据类型。
默认情况下,通过实现 Hibernate 或 EclipseLink 等 ORM 框架,原始数据类型(如 int、char、byte、String、boolean 或它们各自的包装类)会自动映射到正确的数据库类型。
对于日期和枚举等非原始数据类型来说,情况并非如此。
让我们看看如何可能的解决方案来持久化它们。
日期
让我们考虑一个示例,其中有一个带有成员变量 dob(出生日期) 的 Student 实体类。
@Entity
@Table(name = "Student_Table")
public class Student {
@Id
@GeneratedValue
private int id;
private String admission_no;
@Column(name = "student_name")
private String name;
private int age;
private Date dob;
}
这里的日期来自java.util.Date包,而不是java.sql.Date,它是 java.util.Date 包的子类。尽管 sql Date 是最终保存在数据库中的类型,但在使用 JPA 时,util Date 类型通常是首选。util Date 提供了一种在 JPA 中处理日期的标准化方法。util Date 提供毫秒精度的日期和时间。
@temporal注释与Date 类型结合使用。@temporal注释需要一个 TemporalType 类型的参数。共有三种时间类型DATE、TIME和TIMESTAMP。让我们逐一看看。
让我们用@temporal和TemporalType作为Date注释成员变量。
查看之前的文章,了解如何使用 JPA 和数据库设置 Java 项目。
@Entity
@Table(name = "Student_Table")
public class Student {
@Id
@GeneratedValue
private int id;
private String admission_no;
@Column(name = "student_name")
private String name;
private int age;
@Temporal(TemporalType.DATE)
private Date dob;
}
现在将学生实体保存在数据库中。
public class Main {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myPersistenceUnit");
EntityManager entityManager = entityManagerFactory.createEntityManager();
Student student1 = new Student();
student1.setName("Sohail Shah");
student1.setAge(18);
student1.setAdmission_no("1234");
student1.setDob(new Date());
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//persist the student entity
entityManager.persist(student1);
transaction.commit();
entityManager.close();
entityManagerFactory.close();
}
TemporalType.DATE仅保留日期。现在检查数据库中的值。
要保留时间戳,我们可以将TemporalType更改为TIMESTAMP。
@Entity
@Table(name = "Student_Table")
public class Student {
@Id
@GeneratedValue
private int id;
private String admission_no;
@Column(name = "student_name")
private String name;
private int age;
@Temporal(TemporalType.TIMESTAMP)
private Date dob;
}
保留学生实体后,检查数据库中的值。出生日期字段包含日期和时间。
要仅保留时间,请将TemporalType更改为TemporalType.TIME
@Entity
@Table(name = "Student_Table")
public class Student {
@Id
@GeneratedValue
private int id;
private String admission_no;
@Column(name = "student_name")
private String name;
private int age;
@Temporal(TemporalType.TIME)
private Date dob;
}
持久化学生实体并在数据库中,我们只能看到持久化的时间。
枚举
要使用 JPA 将枚举值持久保存到数据库列,请使用 @Enumerated 注释。@Enumerated 注释告诉 JPA 将枚举值映射到数据库。
让我们向我们的学生实体添加一个成员变量学生类型,它是一个枚举。
public enum StudentType {
SCHOLARSHIP,
NON_SCHOLARSHIP
}
@Entity
@Table(name = "Student_Table")
public class Student {
@Id
@GeneratedValue
private int id;
private String admission_no;
@Column(name = "student_name")
private String name;
private int age;
@Temporal(TemporalType.TIME)
private Date dob;
private StudentType studentType;
}
现在用@Enumerated注释student类型的成员变量
@Enumerated
private StudentType studentType;
就是这样,现在我们可以保留学生实体并检查数据库。
Student student1 = new Student();
student1.setName("Sohail Shah");
student1.setAge(18);
student1.setAdmission_no("1234");
student1.setDob(new Date());
student1.setStudentType(StudentType.SCHOLARSHIP);
数据库列中学生类型的值设置为 0。这是因为默认情况下枚举类型设置为序数。当枚举类型设置为序数时,JPA 会保留枚举在枚举类中的位置。在我们的示例中,StudentType 枚举类有两个常量字符串,位置为 0 的 SCHOLARSHIP 和位置为 1 的 NON_SCHOLARSHIP。由于我们将学生类型设置为 StudentType.SCHOLARSHIP,因此它的位置被保留。
可以通过在@Enumerated注释参数中将EnumType设置为 String来更改此行为。让我们现在就开始做吧。
@Enumerated(EnumType.STRING)
private StudentType studentType;
现在保留学生实体并检查数据库。 字符串的实际值保存到数据库中。 根据您的需要在注释参数中使用枚举类型,如EnumType.STRING或EnumType.ORDINAL。
但在实体中使用枚举时要小心。如果枚举类型设置为序数,则无法更改枚举类中常量字符串的位置。如果枚举类型设置为字符串,那么您可以更改位置,但不能更改其拼写。两者都做会导致数据库中的数据不一致。
- 点赞
- 收藏
- 关注作者
评论(0)