JPA 2.2 Поддръжка за Java 8 Типове дата / час

1. Общ преглед

Версията JPA 2.2 официално представи поддръжката на Java 8 API за дата и час . Преди това или трябваше да разчитаме на собствено решение, или трябваше да използваме JPA Converter API.

В този урок ще покажем как да картографираме различните типове дата и час на Java 8 . Особено ще се съсредоточим върху тези, които вземат предвид компенсиращата информация.

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

Преди да започнем, трябва да включим JPA 2.2 API към пътя на класа на проекта. В проект, базиран на 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 и PostgreSQL JDBC драйвер на Maven Central.

Разбира се, можем да използваме други бази данни или внедрения на JPA като Hibernate.

3. Поддръжка на TimeZone

Можем да работим с всяка база данни, но първо трябва да проверим поддръжката за тези стандартни типове SQL, тъй като JDBC 4.2 се основава на:

  • ВРЕМЕВЕН ТАМПЕР (n) С ЧАСОВА ЗОНА
  • ВРЕМЕВЕН ТАМПЪР (n) БЕЗ ЧАСОВА ЗОНА
  • ВРЕМЕ (n) С часовата зона
  • ВРЕМЕ (n) БЕЗ ЧАСОВА ЗОНА

Тук n е точността на дробните секунди и е между 0 и 9 цифри. БЕЗ ВРЕМЕВА ЗОНА е по избор и може да се пропусне. Ако е посочена WITH TIME ZONE , се изисква името на часовата зона или изместването към UTC.

Можем да представим часовата зона в един от тези два формата:

  • Име на часовата зона
  • Отместване от UTC или буквата Z за UTC

За нашия пример избрахме базата данни PostgreSQL, благодарение на пълната й поддръжка за SQL Type TIME WITH TIME ZONE .

Имайте предвид, че други бази данни може да не поддържат тези типове.

4. Картографиране на типове дати преди Java 8

Преди Java 8 обикновено трябваше да картографираме общите SQL типове TIME, DATE и TIMESTAMP , съответно на java.sql. * Класовете java.sql.Time , java.sql.Date и java.sql.Timestamp, съответно, или към java.util типове java.util.Date и java.util.Calendar .

Първо, нека видим как да използваме типовете java.sql . Тук просто дефинираме атрибутите с типовете java.sql като част от клас @Entity :

@Entity public class JPA22DateTimeEntity { private java.sql.Time sqlTime; private java.sql.Date sqlDate; private java.sql.Timestamp sqlTimestamp; // ... }

Докато типовете java.sql работят като всеки друг тип без допълнително картографиране, типовете java.util трябва да посочат съответните временни типове.

Това се прави чрез анотацията @Temporal, чийто атрибут стойност ни позволява да зададем съответния тип 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 като изпълнение, това не поддържа картографиране на Календар в TIME .

По същия начин можем да използваме класа Календар :

@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 TIMESTAMP С ВРЕМЕННА ЗОНА и ВРЕМЕ С ВРЕМЕННА ЗОНА .

Вече можем да съпоставим типовете 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 чрез класовете OffsetTime и 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 ZONE и TIMESTAMP С TIME ZONE . За съжаление не всички бази данни поддържат тези два типа.

Както виждаме, JPA поддържа тези пет класа като основни типове и не е необходима допълнителна информация, за да се прави разлика между датата и / или информацията за времето.

След като запазим нов екземпляр от нашия клас обект, можем да проверим дали данните са вмъкнати правилно:

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

Преди Java 8 и JPA 2.2, разработчиците обикновено трябваше да преобразуват типовете дата / час в UTC, преди да ги продължат. JPA 2.2 вече поддържа тази функция нестандартно, като поддържа изместването към UTC и като използва поддръжката на JDBC 4.2 за часовата зона.

Пълният изходен код за тези проби може да бъде намерен в Github.