0

我在 Postgres 中的 Table 下方,并在 Spring Boot 2.1.6.RELEASE中使用Java 8 和 Postgres-11。我已经经历了这个问题这个问题,但我真的想使用 Java 8 Date API 而不是 Java 7。

CREATE TABLE note(
    note_id serial PRIMARY KEY,
    message varchar(255) NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

我已经创建了如下所示的模型类,但与我需要的不匹配。

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Entity
public class Note extends AuditEnabledEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "note_id")
    private int noteId;
    
    @Column(name = "message")
    private String message;
    
    @Column(name = "created_at")
    private LocalDateTime createdAt;
}
4

1 回答 1

4

Java(现代和传统)以及 SQL 标准中所有日期时间类型的表。

类型错误

LocalDateTime这里是错误的类型。正如其 Javadoc 中所解释的那样,该类不能代表片刻。

该类故意没有时区或与 UTC 偏移的概念。所以它代表一个日期和一天中的时间,例如“2019 年 1 月 23 日中午”,但不知道是东京、巴黎还是蒙特利尔的中午,例如,三个非常不同的时刻相隔几个小时。所以这种类型适用于标准 SQL 类型TIMESTAMP WITHOUT TIME ZONE——不带,不

有关更多讨论,请参阅:Instant 和 LocalDateTime 之间有什么区别?

正确的类型

对于标准 SQL 类型TIMESTAMP WITH TIME ZONE,您应该使用 Java 类型Instant、、OffsetDateTimeZonedDateTime。在这三个中,JDBC 4.2 只需要支持第二个,OffsetDateTime.

恢复。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

从 Postgres 检索的值将始终采用 UTC。SQL 标准没有指定这种行为,因此数据库会有所不同。在 Postgres 中,任何发送到类型字段的值TIMESTAMP WITH TIME ZONE都会调整为 UTC。检索到的值采用 UTC。

存储。

myPreparedStatement.setObject( … , odt ) ;

从 UTC(零偏移)调整到特定地区(时区)人们使用的挂钟时间。

ZoneId z = ZoneId.of( "Asia/Tokyo" ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

JPA

我不使用 JPA,更喜欢保持简单。

但是根据这个 Answer,JPA 2.2 支持java.time类型。

Hibernate 也支持java.time

于 2019-07-08T15:40:24.307 回答