JPA 中保留非原始类型

举报
千锋教育 发表于 2023/07/19 13:51:35 2023/07/19
【摘要】 在这篇文章中,我们将了解如何在 JPA 中保留非原始数据类型。默认情况下,通过实现 Hibernate 或 EclipseLink 等 ORM 框架,原始数据类型(如 int、char、byte、String、boolean 或它们各自的包装类)会自动映射到正确的数据库类型。对于日期和枚举等非原始数据类型来说,情况并非如此。让我们看看如何可能的解决方案来持久化它们。日期让我们考虑一个示例,其...

JPA 中保留非原始类型.png

在这篇文章中,我们将了解如何在 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 类型的参数。共有三种时间类型DATETIMETIMESTAMP。让我们逐一看看。

让我们用@temporalTemporalType作为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.STRINGEnumType.ORDINAL
图片描述

但在实体中使用枚举时要小心。如果枚举类型设置为序数,则无法更改枚举类中常量字符串的位置。如果枚举类型设置为字符串,那么您可以更改位置,但不能更改其拼写。两者都做会导致数据库中的数据不一致。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。