對映時間和日期

時間和日期在 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