映射时间和日期
时间和日期在 Java 中有许多不同的类型:现在历史悠久的 Date
和 Calendar
,以及最近的 LocalDate
和 LocalDateTime
。而 Timestamp
,Instant
,ZonedLocalDateTime
和 Joda-time 类型。在数据库方面,我们有 time
,date
和 timestamp
(时间和日期),可能有或没有时区。
Java 8 之前的日期和时间
pre-Java-8 类型 java.util.Date
,java.util.Calendar
和 java.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 Date
或 Calendar
来表示日期(出生日期)。要更改默认映射,或只是为了使映射显式,可以使用 @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
。提供的映射是
LocalDate
到date
Instant
,LocalDateTime
和ZonedDateTime
到timestamp
供应商中立的替代方案也可以是为任何需要保留的 Java 8 java.time
类型定义 JPA 2.1 AttributeConverter
。