Dvaletilstand - Kortlægning af dato og klokkeslæt

1. Introduktion

I denne artikel viser vi, hvordan man kortlægger tidsmæssige kolonneværdier i dvale, inklusive klasser fra java.sql, java.util og java.tid pakker.

2. Opsætning af projekt

For at demonstrere kortlægningen af ​​de tidsmæssige typer har vi brug for H2-databasen og den nyeste version af dvale-kerne bibliotek:

 org.hibernate hibernate-core 5.4.12.Finale com.h2database h2 1.4.194 

For den aktuelle version af dvale-kerne bibliotek, gå over til Maven Central repository.

3. Opsætning af tidszone

Når det drejer sig om datoer, er det en god ide at indstille en bestemt tidszone til JDBC-driveren. På denne måde ville vores ansøgning være uafhængig af systemets aktuelle tidszone.

For vores eksempel sætter vi det op pr. Session:

session = HibernateUtil.getSessionFactory (). withOptions () .jdbcTimeZone (TimeZone.getTimeZone ("UTC")) .openSession ();

En anden måde ville være at oprette hibernate.jdbc.time_zone egenskab i dvaleegenskabsfilen, der bruges til at konstruere sessionsfabrikken. På denne måde kunne vi angive tidszonen én gang for hele applikationen.

4. Kortlægning java.sql Typer

Det java.sql pakken indeholder JDBC-typer, der er tilpasset de typer, der er defineret af SQL-standarden:

  • Dato svarer til DATO SQL-type, som kun er en dato uden tid
  • Tid svarer til TID SQL-type, som er et tidspunkt på dagen angivet i timer, minutter og sekunder
  • Tidsstempel indeholder oplysninger om dato og klokkeslæt med nøjagtighed op til nanosekunder og svarer til TIDSSTEMPEL SQL-type

Da disse typer er i tråd med SQL, er deres kortlægning relativt ligetil. Vi kan bruge enten @Grundlæggende eller den @Kolonne kommentar:

@Entity offentlig klasse TemporalValues ​​{@Basic private java.sql.Date sqlDate; @ Grundlæggende privat java.sql.Time sqlTime; @ Grundlæggende privat java.sql.Timestamp sqlTimestamp; }

Vi kunne derefter indstille de tilsvarende værdier som denne:

temporalValues.setSqlDate (java.sql.Date.valueOf ("2017-11-15")); temporalValues.setSqlTime (java.sql.Time.valueOf ("15:30:14")); temporalValues.setSqlTimestamp (java.sql.Timestamp.valueOf ("2017-11-15 15: 30: 14.332"));

Bemærk, at du vælger java.sql typer til enhedsfelter er måske ikke altid et godt valg. Disse klasser er JDBC-specifikke og indeholder en masse forældet funktionalitet.

5. Kortlægning java.util.Date Type

Typen java.util.Date indeholder både dato og klokkeslæt op til millisekunders præcision. Men det vedrører ikke direkte nogen SQL-type.

Dette er grunden til, at vi har brug for en ny kommentar for at specificere den ønskede SQL-type:

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

Det @Temporal annotation har den enkelte parameterværdi af typen TemporalType. Det kan være enten DATO, TID eller TIDSSTEMPELafhængigt af den underliggende SQL-type, som vi vil bruge til kortlægningen.

Vi kunne derefter indstille de tilsvarende felter som denne:

temporalValues.setUtilDate (ny SimpleDateFormat ("åååå-MM-dd"). parse ("2017-11-15")); temporalValues.setUtilTime (ny SimpleDateFormat ("HH: mm: ss"). parse ("15:30:14")); temporalValues.setUtilTimestamp (ny SimpleDateFormat ("åååå-MM-dd HH: mm: ss.SSS") .parse ("2017-11-15 15: 30: 14.332"));

Som vi har set, det java.util.Date type (millisekunders præcision) er ikke præcis nok til at håndtere tidsstempelværdien (nanosekunders præcision).

Så når vi henter enheden fra databasen, finder vi ikke overraskende en java.sql.Tidsstempel eksempel på dette felt, selvom vi oprindeligt varede a java.util.Date:

temporalValues ​​= session.get (TemporalValues.class, temporalValues.getId ()); assertThat (temporalValues.getUtilTimestamp ()) .isEqualTo (java.sql.Timestamp.valueOf ("2017-11-15 15: 30: 14.332"));

Dette burde være fint for vores kode siden Tidsstempel strækker sig Dato.

6. Kortlægning java.util.Kalender Type

Som med java.util.Date, det java.util.Kalender typen kan kortlægges til forskellige SQL-typer, så vi er nødt til at specificere dem med @Temporal.

Den eneste forskel er, at dvale ikke understøtter kortlægning Kalender til TID:

@Basic @Temporal (TemporalType.DATE) privat java.util.Calendar calendarDate; @Basic @Temporal (TemporalType.TIMESTAMP) privat java.util.Calendar kalenderTimestamp;

Sådan kan vi indstille feltets værdi:

Calendar calendarDate = Calendar.getInstance (TimeZone.getTimeZone ("UTC")); calendarDate.set (Calendar.YEAR, 2017); calendarDate.set (Calendar.MONTH, 10); calendarDate.set (Calendar.DAY_OF_MONTH, 15); temporalValues.setCalendarDate (calendarDate);

7. Kortlægning java.tid Typer

Siden Java 8 er den nye Java Date and Time API tilgængelig til at håndtere tidsmæssige værdier. Denne API løser mange af problemerne med java.util.Date og java.util.Kalender klasser.

Typerne fra java.tid pakke kortlægges direkte til tilsvarende SQL-typer. Så der er ingen grund til specifikt at specificere @Temporal kommentar:

  • LocalDate er kortlagt til DATO
  • Lokal tid og OffsetTime er kortlagt til TID
  • Øjeblikkelig, LocalDateTime, OffsetDateTime og ZonedDateTime er kortlagt til TIDSSTEMPEL

Dette betyder, at vi kun kan markere disse felter med @Grundlæggende (eller @Kolonne) kommentar, sådan:

@ Grundlæggende privat java.time.LocalDate localDate; @ Grundlæggende privat java.time.LocalTime localTime; @ Grundlæggende privat java.time.OffsetTime offsetTime; @ Grundlæggende privat java.time.Instant øjeblik; @ Grundlæggende privat java.time.LocalDateTime localDateTime; @ Grundlæggende privat java.time.OffsetDateTime offsetDateTime; @ Grundlæggende privat java.time.ZonedDateTime zonedDateTime;

Hver timelig klasse i java.tid pakken har en statisk parse () metode til at analysere det leverede Snor værdi ved hjælp af det relevante format. Så her kan vi indstille værdierne for enhedsfelterne:

temporalValues.setLocalDate (LocalDate.parse ("2017-11-15"); temporalValues.setLocalTime (LocalTime.parse ("15:30:18")); temporalValues.setOffsetTime (OffsetTime.parse ("08: 22: 12 + 01: 00")); temporalValues.setInstant (Instant.parse ("2017-11-15T08: 22: 12Z")); temporalValues.setLocalDateTime (LocalDateTime.parse ("2017-11-15T08: 22: 12")); temporalValues.setOffsetDateTime (OffsetDateTime.parse ("2017-11-15T08: 22: 12 + 01: 00")); temporalValues.setZonedDateTime (ZonedDateTime.parse ("2017-11-15T08: 22: 12 + 01: 00 [Europe / Paris]"));

8. Konklusion

I denne artikel har vi vist, hvordan man kortlægger tidsmæssige værdier af forskellige typer i dvale.

Kildekoden til artiklen er tilgængelig på GitHub.