映射时间和日期

时间和日期在 Java 中有许多不同的类型:现在历史悠久的 DateCalendar,以及最近的 LocalDateLocalDateTime。而 TimestampInstantZonedLocalDateTime 和 Joda-time 类型。在数据库方面,我们有 timedatetimestamp(时间和日期),可能有或没有时区。

Java 8 之前的日期和时间

pre-Java-8 类型 java.util.Datejava.util.Calendarjava.sql.Timestamp默认映射是 SQL 中的 timestamp; 对于 java.sql.Date 来说,这是 date

@Entity
class Times {
    @Id
    private Integer id;

    @Basic
    private Timestamp timestamp;

    @Basic
    private java.sql.Date sqldate;

    @Basic
    private java.util.Date utildate;

    @Basic
    private Calendar calendar;
}

这将完美映射到下表:

CREATE TABLE times (
    id integer not null,
    timestamp timestamp,
    sqldate date,
    utildate timestamp,
    calendar timestamp
)

这可能不是意图。例如,通常使用 Java DateCalendar 来表示日期(出生日期)。要更改默认映射,或只是为了使映射显式,可以使用 @Temporal 注释。

@Entity
class Times {
    @Id
    private Integer id;

    @Temporal(TemporalType.TIME)
    private Date date;

    @Temporal(TemporalType.DATE)
    private Calendar calendar;
}

等效的 SQL 表是:

CREATE TABLE times (
    id integer not null,
    date time,
    calendar date
)

注 1: @Temporal 指定的类型影响 DDL 生成; 但你也可以只用 @Basic 注释将 date 的一个列映射到 Date

注 2: Calendar 不能仅持续 time

Java 8 的日期和时间

JPA 2.1 没有定义对 Java 8 中提供的 java.time 类型的支持。大多数 JPA 2.1 实现提供了对这些类型的支持,但这些严格来说是供应商扩展。

对于 DataNucleus,这些类型只是开箱即用,并提供了广泛的映射可能性,与 @Temporal 注释相结合。

对于 Hibernate,如果使用 Hibernate 5.2+,它们应该开箱即用,只需使用 @Basic 注释即可。如果使用 Hibernate 5.0-5.1,则需要添加依赖关系 org.hibernate:hibernate-java8。提供的映射是

  • LocalDatedate
  • InstantLocalDateTimeZonedDateTimetimestamp

供应商中立的替代方案也可以是为任何需要保留的 Java 8 java.time 类型定义 JPA 2.1 AttributeConverter