JPA 2.2 Support til Java 8 dato / tidstyper

1. Oversigt

JPA 2.2-versionen har officielt introduceret supporten til Java 8 Dato og Tid API. Før det måtte vi enten stole på en proprietær løsning, eller så måtte vi bruge JPA Converter API.

I denne vejledning vi viser, hvordan man kortlægger de forskellige Java 8 Dato og Tid typer. Vi fokuserer især på dem, der tager højde for offsetoplysningerne.

2. Maven-afhængigheder

Før vi starter, skal vi inkludere JPA 2.2 API i projektets klassesti. I et Maven-baseret projekt kan vi blot tilføje dets afhængighed til vores pom.xml fil:

 javax.persistence javax.persistence-api 2.2 

Derudover har vi brug for en JPA-implementering og JDBC-driveren til den database, som vi vil arbejde med, for at køre projektet. I denne vejledning bruger vi EclipseLink og PostgreSQL-databasen:

 org.eclipse.persistence eclipselink 2.7.4 runtime org.postgresql postgresql 42.2.5 runtime bundle 

Du er velkommen til at tjekke de nyeste versioner af JPA API, EclipseLink og PostgreSQL JDBC-driveren på Maven Central.

Selvfølgelig kan vi bruge andre databaser eller JPA-implementeringer som Hibernate.

3. TimeZone Support

Vi kan arbejde med enhver database, men først skal vi kontrollere supporten til disse standard SQL-typer, da JDBC 4.2 er baseret på:

  • TIMESTAMP (n) MED TIDSZONE
  • TIMESTAMP (n) UDEN TIDSZONE
  • TID (n) MED TIDSZONE
  • TID (n) UDEN TIDSZONE

Her, n er præcisionen på brøkdele af sekunder og er mellem 0 og 9 cifre. UDEN TIDSZONE er valgfri og kan udelades. Hvis MED TIDSZONE er angivet, kræves tidszonenavnet eller forskydningen til UTC.

Vi kan repræsentere tidszonen i et af disse to formater:

  • Tidszone navn
  • Forskydning fra UTC eller bogstavet Z for UTC

For vores eksempel har vi valgt PostgreSQL-databasen takket være dens fulde understøttelse af SQL-typen TID MED TIDSZONE.

Bemærk, at andre databaser muligvis ikke understøtter disse typer.

4. Kortlægning af datatyper før Java 8

Før Java 8 var vi normalt nødt til at kortlægge de generiske SQL-typer TID, DATOog TIDSSTEMPEL, til enten java.sql. * klasser java.sql.Tid, java.sql.dato, og java.sql.Tidsstempel, henholdsvis eller til java.util typer java.util.Date og java.util.Kalender.

Lad os først se, hvordan du bruger java.sql typer. Her definerer vi simpelthen attributterne med java.sql typer som en del af en @Enhed klasse:

@Entity offentlig klasse JPA22DateTimeEntity {privat java.sql.Time sqlTime; privat java.sql.Date sqlDate; privat java.sql.Timestamp sqlTimestamp; // ...}

Mens java.sql typer fungerer som alle andre typer uden yderligere kortlægning, java.util typer skal specificere de tilsvarende tidsmæssige typer.

Dette gøres gennem @Temporal kommentar hvis værdi -attribut giver os mulighed for at specificere den tilsvarende JDBC-type ved hjælp af TemporalType optælling:

@Temporal (TemporalType.TIME) privat java.util.Date utilTime; @Temporal (TemporalType.DATE) privat java.util.Date utilDate; @Temporal (TemporalType.TIMESTAMP) privat java.util.Date utilTimestamp;

Bemærk, at hvis vi bruger dvale som en implementering, understøtter dette ikke kortlægning Kalender til TID.

På samme måde kan vi bruge Kalender klasse:

@Temporal (TemporalType.TIME) privat kalender calendarTime; @Temporal (TemporalType.DATE) privat kalender calendarDate; @Temporal (TemporalType.TIMESTAMP) privat kalender kalenderTidsstempel;

Ingen af ​​disse typer understøtter tidszonen eller forskydningen. For at håndtere disse stykker information måtte vi traditionelt gemme UTC-tiden.

5. Kortlægning af Java 8 datatyper

Java 8 har introduceret java.tid pakker og JDBC 4.2 API tilføjede understøttelse af de yderligere SQL-typer TIDSTEMPEL MED TIDSZONE og TID MED TIDSZONE.

Vi kan nu kortlægge JDBC-typerne TID, DATO, og TIDSSTEMPEL til java.tid typerLokal tid,LocalDateog LocalDateTime:

@Column (name = "local_time", columnDefinition = "TIME") privat LocalTime localTime; @Column (name = "local_date", columnDefinition = "DATE") privat LocalDate localDate; @Column (name = "local_date_time", columnDefinition = "TIMESTAMP") privat LocalDateTime localDateTime;

Derudover har vi support til den forskudte lokale tidszone til UTC gennem OffsetTime og OffsetDateTime klasser:

@Column (name = "offset_time", columnDefinition = "TID MED TIDSZONE") privat OffsetTime offsetTime; @Column (navn = "offset_date_time", columnDefinition = "TIMESTAMP MED TIDSZONE") privat OffsetDateTime offsetDateTime;

De tilsvarende kortlagte kolonnetyper skal være TID MED TIDSZONE og TIDSTEMPEL MED TIDSZONE. Desværre understøtter ikke alle databaser disse to typer.

Som vi kan se, understøtter JPA disse fem klasser som grundlæggende typer, og der er ingen yderligere oplysninger nødvendige for at skelne mellem dato og / eller tidsinformation.

Efter at have gemt en ny forekomst af vores enhedsklasse, kan vi kontrollere, at data er indsat korrekt:

6. Konklusion

Før Java 8 og JPA 2.2 måtte udviklere normalt konvertere dato / tidstyper til UTC, før de fortsatte. JPA 2.2 understøtter nu denne funktion ud af kassen ved at understøtte forskydningen til UTC og ved at udnytte JDBC 4.2-support til tidszonen.

Den fulde kildekode til disse prøver findes på Github.