Dvalemodus - Kartlegging av dato og klokkeslett
1. Introduksjon
I denne artikkelen viser vi hvordan du kan kartlegge verdier i timevis i dvalemodus, inkludert klassene fra java.sql, java.util og java.time pakker.
2. Prosjektoppsett
For å demonstrere kartleggingen av de tidsmessige typene, trenger vi H2-databasen og den siste versjonen av dvale-kjerne bibliotek:
org.hibernate hibernate-core 5.4.12.Final com.h2database h2 1.4.194
For den nåværende versjonen av dvale-kjerne bibliotek, gå over til Maven Central repository.
3. Tidssoneoppsett
Når du arbeider med datoer, er det en god ide å angi en bestemt tidssone for JDBC-driveren. På denne måten ville søknaden vår være uavhengig av systemets nåværende tidssone.
For vårt eksempel vil vi sette det opp per økt:
økt = HibernateUtil.getSessionFactory (). withOptions () .jdbcTimeZone (TimeZone.getTimeZone ("UTC")) .openSession ();
En annen måte ville være å sette opp dvalemodus.jdbc.time_zone eiendom i dvaleegenskapsfilen som brukes til å konstruere øktfabrikken. På denne måten kunne vi spesifisere tidssonen en gang for hele applikasjonen.
4. Kartlegging java.sql Typer
De java.sql pakken inneholder JDBC-typer som er justert med typene definert av SQL-standarden:
- Dato tilsvarer DATO SQL-type, som bare er en dato uten tid
- Tid tilsvarer TID SQL-type, som er en tid på dagen spesifisert i timer, minutter og sekunder
- Tidsstempel inneholder informasjon om dato og klokkeslett med presisjon opp til nanosekunder og tilsvarer TIDSTEMPEL SQL-type
Siden disse typene er i tråd med SQL, er kartleggingen deres relativt rett frem. Vi kan bruke enten @Basic eller @Kolonne kommentar:
@Entity offentlig klasse TemporalValues {@Basic private java.sql.Date sqlDate; @Grunnleggende privat java.sql.Time sqlTime; @Basic private java.sql.Timestamp sqlTimestamp; }
Vi kunne da sette de tilsvarende verdiene slik:
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"));
Merk at du velger java.sql typer for enhetsfelt er kanskje ikke alltid et godt valg. Disse klassene er JDBC-spesifikke og inneholder mye foreldet funksjonalitet.
5. Kartlegging java.util.Date Type
Typen java.util.Date inneholder både dato og klokkeslett, opp til millisekunders presisjon. Men det forholder seg ikke direkte til noen SQL-type.
Dette er grunnen til at vi trenger en ny kommentar for å spesifisere ønsket 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;
De @Temporal kommentar har den ene parameterverdien av typen TemporalType. Det kan være enten DATO, TID eller TIDSTEMPEL, avhengig av den underliggende SQL-typen vi vil bruke til kartleggingen.
Vi kunne da angi de tilsvarende feltene slik:
temporalValues.setUtilDate (ny SimpleDateFormat ("åååå-MM-dd"). analyse ("2017-11-15")); temporalValues.setUtilTime (ny SimpleDateFormat ("HH: mm: ss"). parsing ("15:30:14")); temporalValues.setUtilTimestamp (new SimpleDateFormat ("yyyy-MM-dd HH: mm: ss.SSS") .parse ("2017-11-15 15: 30: 14.332"));
Som vi har sett, de java.util.Date type (millisekunders presisjon) er ikke presis nok til å håndtere tidsstempelverdien (nanosekunders presisjon).
Så når vi henter enheten fra databasen, finner vi ikke overraskende en java.sql.Tidsstempel forekomst i dette feltet, selv om vi i utgangspunktet vedvarte 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 bra for koden vår siden Tidsstempel strekker Dato.
6. Kartlegging java.util.Kalender Type
Som med java.util.Date, den java.util.Kalender typen kan tilordnes forskjellige SQL-typer, så vi må spesifisere dem med @Temporal.
Den eneste forskjellen er at dvalemodus ikke støtter kartlegging Kalender til TID:
@Basic @Temporal (TemporalType.DATE) privat java.util.Calendar calendarDate; @Basic @Temporal (TemporalType.TIMESTAMP) privat java.util.Calendar calendarTimestamp;
Slik kan vi sette verdien av feltet:
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. Kartlegging java.time Typer
Siden Java 8 er den nye Java Date and Time API tilgjengelig for å håndtere tidsverdier. Denne APIen løser mange av problemene med java.util.Date og java.util.Kalender klasser.
Typene fra java.time pakken er direkte kartlagt til tilsvarende SQL-typer. Så det er ikke nødvendig å spesifisere noe @Temporal kommentar:
- LocalDate er kartlagt til DATO
- Lokal tid og OffsetTime er kartlagt til TID
- Umiddelbar, LocalDateTime, OffsetDateTime og ZonedDateTime er kartlagt til TIDSTEMPEL
Dette betyr at vi bare kan markere disse feltene med @Basic (eller @Kolonne) kommentar, slik:
@Basic private java.time.LocalDate localDate; @Basic privat java.time.LocalTime localTime; @Basic privat java.time.OffsetTime offsetTime; @Basic private java.time.Instant instant; @Basic private java.time.LocalDateTime localDateTime; @Basic privat java.time.OffsetDateTime offsetDateTime; @Basic private java.time.ZonedDateTime zonedDateTime;
Hver timelig klasse i java.time pakken har en statisk analysere () metode for å analysere den angitte String verdien i riktig format. Så her kan vi sette verdiene til enhetsfeltene:
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. Konklusjon
I denne artikkelen har vi vist hvordan du kan kartlegge tidsverdier av forskjellige typer i dvalemodus.
Kildekoden for artikkelen er tilgjengelig på GitHub.