Hibernate - Mapovanie dátumu a času

1. Úvod

V tomto článku si ukážeme, ako mapovať hodnoty dočasných stĺpcov v režime dlhodobého spánku vrátane tried z java.sql, java.util a java.time balíkov.

2. Nastavenie projektu

Aby sme demonštrovali mapovanie časových typov, budeme potrebovať databázu H2 a jej najnovšiu verziu hibernácia-jadro knižnica:

 org.hibernate hibernate-core 5.4.12. Konečná kom.h2databáza h2 1.4.194 

Pre aktuálnu verziu hibernácia-jadro knižnica, choďte do centrálneho úložiska Maven.

3. Nastavenie časovej zóny

Pri práci s dátumami je dobré nastaviť konkrétne časové pásmo pre ovládač JDBC. Takto by bola naša aplikácia nezávislá od aktuálneho časového pásma systému.

V našom príklade to nastavíme na základe relácie:

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

Ďalším spôsobom by bolo zriadenie hibernate.jdbc.time_zone vlastnosť v súbore vlastností režimu dlhodobého spánku, ktorá sa používa na vytvorenie továrne na relácie. Takto by sme mohli určiť časové pásmo raz pre celú aplikáciu.

4. Mapovanie java.sql Typy

The java.sql balík obsahuje typy JDBC, ktoré sú zarovnané s typmi definovanými štandardom SQL:

  • Dátum zodpovedá DÁTUM Typ SQL, čo je iba dátum bez času
  • Čas zodpovedá TIME Typ SQL, čo je denný čas určený v hodinách, minútach a sekundách
  • Časová značka obsahuje informácie o dátume a čase s presnosťou až na nanosekundy a zodpovedá ČASOVÁ ZNAČKA Typ SQL

Pretože sú tieto typy v súlade s SQL, je ich mapovanie relatívne priame. Môžeme použiť buď @Základné alebo @ Stĺpec anotácia:

@Entity verejná trieda TemporalValues ​​{@Základné súkromné ​​java.sql.Date sqlDate; @ Základné súkromné ​​java.sql.Time sqlTime; @ Základné súkromné ​​java.sql.Timestamp sqlTimestamp; }

Potom by sme mohli nastaviť zodpovedajúce hodnoty takto:

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"));

Všimnite si, že výber java.sql typy pre polia entít nemusia byť vždy dobrou voľbou. Tieto triedy sú špecifické pre JDBC a obsahujú veľa zastaraných funkcií.

5. Mapovanie java.util.Date Typ

Typ java.util.Date obsahuje informácie o dátume aj čase s presnosťou až na milisekundy. Ale priamo to nesúvisí so žiadnym typom SQL.

Z tohto dôvodu potrebujeme ďalšiu anotáciu, aby sme určili požadovaný typ SQL:

@Basic @Temporal (TemporalType.DATE) súkromné ​​java.util.Date utilDate; @Basic @Temporal (TemporalType.TIME) súkromné ​​java.util.Date utilTime; @Basic @Temporal (TemporalType.TIMESTAMP) súkromné ​​java.util.Date utilTimestamp;

The @ Temporal anotácia má jedinú hodnotu parametra typu TemporalType. Môže to byť buď DÁTUM, TIME alebo ČASOVÁ ZNAČKA, v závislosti od základného typu SQL, ktorý chceme použiť na mapovanie.

Potom by sme mohli nastaviť zodpovedajúce polia takto:

temporalValues.setUtilDate (nový SimpleDateFormat ("rrrr-MM-dd"). parse ("2017-11-15")); temporalValues.setUtilTime (nový SimpleDateFormat ("HH: mm: ss"). parse ("15:30:14")); temporalValues.setUtilTimestamp (nový SimpleDateFormat ("rrrr-MM-dd HH: mm: ss.SSS") .parse ("2017-11-15 15: 30: 14,332"));

Ako sme videli, the java.util.Date typ (presnosť na milisekundy) nie je dosť presný na spracovanie hodnoty časovej pečiatky (presnosť na nanosekundy).

Takže keď načítame entitu z databázy, prekvapivo nájdeme a java.sql.Timestamp inštancie v tejto oblasti, aj keď sme spočiatku pretrvávali 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"));

To by malo byť v poriadku pre náš kód, pretože Časová značka predlžuje Dátum.

6. Mapovanie java.util.Calendar Typ

Rovnako ako v prípade java.util.Date, java.util.Calendar typ môžu byť mapované na rôzne typy SQL, takže ich musíme špecifikovať pomocou @ Temporal.

Jediný rozdiel je v tom, že režim dlhodobého spánku nepodporuje mapovanie Kalendár do TIME:

@Basic @Temporal (TemporalType.DATE) súkromné ​​java.util.Calendar calendarDate; @Basic @Temporal (TemporalType.TIMESTAMP) súkromná java.util.Calendar calendarTimestamp;

Hodnotu poľa môžeme nastaviť takto:

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. Mapovanie java.time Typy

Od verzie Java 8 je k dispozícii nové rozhranie Java Date and Time API na prácu s časovými hodnotami. Toto API opravuje mnoho problémov so serverom java.util.Date a java.util.Calendar triedy.

Typy z java.time balík sú priamo mapované na zodpovedajúce typy SQL. Nie je teda potrebné výslovne špecifikovať @ Temporal anotácia:

  • LocalDate je namapované na DÁTUM
  • Miestny čas a Čas posunu sú mapované na TIME
  • Okamžité, LocalDateTime, OffsetDateTime a ZonedDateTime sú mapované na ČASOVÁ ZNAČKA

To znamená, že tieto polia môžeme označiť iba pomocou @Základné (alebo @ Stĺpec) anotácia, napríklad táto:

@ Základné súkromné ​​java.time.LocalDate localDate; @ Základné súkromné ​​java.time.LocalTime localTime; @ Základné súkromné ​​java.time.OffsetTime offsetTime; @ Základná súkromná java.time. Okamžitý okamih; @ Základné súkromné ​​java.time.LocalDateTime localDateTime; @ Základné súkromné ​​java.time.OffsetDateTime offsetDateTime; @ Základné súkromné ​​java.time.ZonedDateTime zonedDateTime;

Každá časová trieda v java.time balík má statický analyzovať () metóda na analýzu poskytnutého String hodnotu v príslušnom formáte. Takto môžeme nastaviť hodnoty polí entity:

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 [Európa / Paríž]"));

8. Záver

V tomto článku sme si ukázali, ako mapovať časové hodnoty rôznych typov v režime dlhodobého spánku.

Zdrojový kód článku je k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found