Рубрики
Без рубрики

Поддержка JPA 2.2 для типов даты и времени Java 8

Посмотрите, как использовать классы пакетов java.time с JPA

Автор оригинала: baeldung.

1. Обзор

Версия JPA 2.2 официально представила поддержку API даты и времени Java 8 . До этого нам приходилось либо полагаться на собственное решение, либо использовать API JPA Converter.

В этом уроке мы покажем, как сопоставить различные типы Java 8 Дата и Время /. Мы особенно сосредоточимся на тех, которые учитывают информацию о смещении.

2. Зависимости Maven

Прежде чем мы начнем, нам нужно включить API JPA 2.2 в путь к классам проекта. В проекте на основе Maven мы можем просто добавить его зависимость к вашему pom.xml файл:


    javax.persistence
    javax.persistence-api
    2.2

Кроме того, для запуска проекта нам нужна реализация JPA и драйвер JDBC базы данных, с которой мы будем работать. В этом уроке мы будем использовать EclipseLink и базу данных PostgreSQL:


    org.eclipse.persistence
    eclipselink
    2.7.4
    runtime


    org.postgresql
    postgresql
    42.2.5
    runtime
    bundle

Не стесняйтесь проверять последние версии JPA API , EclipseLink и драйвера JDBC PostgreSQL на Maven Central.

Конечно, мы можем использовать другие базы данных или реализации JPA, такие как Hibernate.

3. Поддержка часового пояса

Мы можем работать с любой базой данных, но сначала мы должны проверить поддержку этих стандартных типов SQL, так как JDBC 4.2 основан на:

  • МЕТКА ВРЕМЕНИ(n) С ЧАСОВЫМ ПОЯСОМ
  • МЕТКА ВРЕМЕНИ(n) БЕЗ ЧАСОВОГО ПОЯСА
  • ВРЕМЯ(n) С ЧАСОВЫМ ПОЯСОМ
  • ВРЕМЯ(n) БЕЗ ЧАСОВОГО ПОЯСА

Здесь n – это точность в доли секунды и находится между 0 и 9 цифрами. БЕЗ ЧАСОВОГО ПОЯСА является необязательным и может быть опущен. Если указан С ЧАСОВЫМ ПОЯСОМ , требуется имя часового пояса или смещение в UTC.

Мы можем представить часовой пояс в одном из этих двух форматов:

  • Название часового пояса
  • Смещение от UTC или буква Z для UTC

Для нашего примера мы выбрали базу данных PostgreSQL благодаря ее полной поддержке типа SQL ВРЕМЯ С ЧАСОВЫМ ПОЯСОМ .

Обратите внимание, что другие базы данных могут не поддерживать эти типы.

4. Сопоставление Типов Данных До Java 8

До Java 8 нам обычно приходилось сопоставлять общие типы SQL TIME, DATE и TIMESTAMP либо с java.sql.* классами java.sql.Time , java.sql.Date, и java.sql.Timestamp соответственно, либо с java.util типами java.util.Дата и java.util.Календарь .

Во-первых, давайте посмотрим, как использовать типы java.sql . Здесь мы просто определяем атрибуты с помощью типов java.sql как часть класса @Entity :

@Entity
public class JPA22DateTimeEntity {

    private java.sql.Time sqlTime;
    private java.sql.Date sqlDate;
    private java.sql.Timestamp sqlTimestamp;
    
    // ...
}

В то время как В то время как типы работают, как и любые другие типы, без какого-либо дополнительного сопоставления, типы работают, как и любые другие типы, без какого-либо дополнительного сопоставления, типы должны указывать соответствующие временные типы.

Это делается с помощью аннотации @Temporal , чей атрибут value позволяет нам указать соответствующий тип JDBC, используя перечисление TemporalType :

@Temporal(TemporalType.TIME)
private java.util.Date utilTime;

@Temporal(TemporalType.DATE)
private java.util.Date utilDate;

@Temporal(TemporalType.TIMESTAMP)
private java.util.Date utilTimestamp;

Обратите внимание, что если мы используем Hibernate в качестве реализации, это не поддерживает сопоставление Calendar с ВРЕМЯ .

Аналогично, мы можем использовать класс Calendar :

@Temporal(TemporalType.TIME)
private Calendar calendarTime;

@Temporal(TemporalType.DATE)
private Calendar calendarDate;

@Temporal(TemporalType.TIMESTAMP)
private Calendar calendarTimestamp;

Ни один из этих типов не поддерживает часовой пояс или смещение. Чтобы справиться с этими фрагментами информации, мы традиционно должны были хранить время UTC.

5. Сопоставление типов дат Java 8

Java 8 представила пакеты java.time , а API JDBC 4.2 добавил поддержку дополнительных типов SQL МЕТКА ВРЕМЕНИ С ЧАСОВЫМ ПОЯСОМ и ВРЕМЯ С ЧАСОВЫМ ПОЯСОМ .

Теперь мы можем сопоставить типы JDBC TIME, DATE, и TIMESTAMP с типами java.time LocalTime, /LocalDate и LocalDateTime :

@Column(name = "local_time", columnDefinition = "TIME")
private LocalTime localTime;

@Column(name = "local_date", columnDefinition = "DATE")
private LocalDate localDate;

@Column(name = "local_date_time", columnDefinition = "TIMESTAMP")
private LocalDateTime localDateTime;

Кроме того, у нас есть поддержка смещения локального часового пояса в UTC через классы Offset Time и OffsetDateTime :

@Column(name = "offset_time", columnDefinition = "TIME WITH TIME ZONE")
private OffsetTime offsetTime;

@Column(name = "offset_date_time", columnDefinition = "TIMESTAMP WITH TIME ZONE")
private OffsetDateTime offsetDateTime;

Соответствующие сопоставленные типы столбцов должны быть TIME С ЧАСОВЫМ ПОЯСОМ и TIMESTAMP С ЧАСОВЫМ ПОЯСОМ . К сожалению, не все базы данных поддерживают эти два типа.

Как мы видим, JPA поддерживает эти пять классов в качестве основных типов, и нет никакой дополнительной информации, необходимой для различения информации о дате и/или времени.

После сохранения нового экземпляра нашего класса сущностей мы можем проверить правильность вставки данных:

6. Заключение

До Java 8 и JPA 2.2 разработчикам обычно приходилось преобразовывать типы даты и времени в UTC, прежде чем сохранять их. JPA 2.2 теперь поддерживает эту функцию из коробки, поддерживая смещение в UTC и используя поддержку JDBC 4.2 для часового пояса.

Полный исходный код для этих примеров можно найти на Github .