4.1 Ekskursus menyang sajarah

Tugas nyimpen obyek Jawa menyang basis data cocog meh sanalika sawise nggawe basa Jawa. Ing wektu iku, mung ana siji jinis data ing basa Jawa, Date, sing disimpen wektu miturut standar UNIX-wektu: minangka jumlah milidetik wiwit taun 1970.

Inggih, ing basis data ing wektu iku wis ana macem-macem jinis data kanggo tanggal, paling ora ana jinis kapisah kanggo tanggal, wektu lan tanggal + wektu:

  • TANGGAL
  • WAKTU
  • TIMESTAMP

Mulane, sing nggawe basa Jawa nambahake paket khusus - java.sql, sing ngemot kelas:

  • java.sql.date
  • java.sql.Wektu
  • java.sql.timestamp

Pemetaan kelas kasebut pancen nyenengake:


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

Nanging wiwit programer biyen nggarap kelas java.util.Date, Hibernate nambahake anotasi khusus @Temporalkanggo ngontrol pemetaan jinis Tanggal.

Tuladha:

// If the annotation is missing, then the database will have a TIMESTAMP type
Date dateAsTimestamp;

@Temporal(TemporalType.DATE) // will be mapped to DATE type
Date dateAsDate;

@Temporal(TemporalType.TIME) // will be mapped to TIME type
Date dateAsTime;

Jinis java.util.Calendarlan java.util.Datejinis standar nggunakake jinis TIMESTAMP kanggo makili ing database.

4.2 Wektu anyar

Saiki, kanthi pemetaan, kabeh luwih gampang lan luwih apik. Kabeh basis data ndhukung 4 jinis data kanggo nggarap wektu:

  • DATE - tanggal: taun, sasi lan dina.
  • TIME - wektu: jam, menit, detik.
  • TIMESTAMP - tanggal, wektu lan nanodetik.
  • TIMESTAMP WITH TIME ZONE - TIMESTAMP lan zona wektu (jeneng zona utawa offset).

Kanggo makili jinis TANGGALing Jawa, sampeyan kudu nggunakake kelas java.time.LocalDatesaka JDK 8 DateTime API.

JinisWAKTUsaka database bisa dituduhake dening rong jinis saka Jawa: java.time.LocalTimelan java.time.OffsetTime. Ora ana sing rumit.

Lan tanggal lan wektu sing tepat diwakili dening jinis kasebutTIMESTAMPing basa Jawa bisa diwakili 4 jinis:

  • java.wektu.Instant
  • java.time.LocalDateTime
  • java.time.OffsetDateTime
  • java.time.ZonedDateTime

Lan pungkasaneTIMESTAMP KARO ZONA WAKTUbisa diwakili dening rong jinis:

  • java.time.OffsetDateTime
  • java.time.ZonedDateTime

Amarga sampeyan wis kenal karo DateTime API , ngelingi perkara iki ora bakal angel kanggo sampeyan :)

Pemetaan iku kesenengan murni:

@Basic
private java.time.LocalDate localDate;

@Basic
private java.time.LocalTime localTime;

@Basic
private java.time.OffsetTime offsetTime;

@Basic
private java.time.Instant instant;

@Basic
private java.time.LocalDateTime localDateTime;

@Basic
private java.time.OffsetDateTime offsetDateTime;

@Basic
private java.time.ZonedDateTime zonedDateTime;

Anotasi @Basictegese lapangan kudu diproses kanthi otomatis : Hibernate bakal mutusake kolom lan ketik kolom sing kudu dipetakan.

4.3 Nggarap zona wektu

Yen zona wektu minangka bagéan saka tanggal, banjur nyimpen ing database iku prasaja - kaya tanggal biasa:

@Basic
private java.time.OffsetDateTime offsetDateTime;

@Basic
private java.time.ZonedDateTime zonedDateTime;

Nanging, yen sampeyan pengin nyimpen zona wektu kanthi kapisah saka tanggal:

@Basic
private java.time.TimeZone timeZone;

@Basic
private java.time.ZoneOffset zonedOffset;

Banjur Hibernate bakal nyimpen ing jinis VARCHAR minangka standar. Sing, nyatane, logis, amarga TimeZone biasane duwe jeneng senar kaya "UTC + 3" utawa "Kairo".

4.4 Nyetel zona wektu sampeyan dhewe

Nalika sampeyan bisa nyimpen tanggal menyang database, sampeyan bakal nemokake kasunyatan sing wis ana 4 panggonan ngendi sampeyan bisa nyetel zona wektu saiki:

  • Sistem operasi server;
  • DBMS;
  • Aplikasi Java
  • Hibernate.

Yen DBMS ora nemtokake zona wektu (TimeZone), banjur bakal njupuk saka setelan sistem operasi. Iki bisa uga ora trep, amarga DBMS serep asring ana ing pusat data liyane sing duwe zona wektu dhewe.

Mulane, meh kabeh admin DBMS nyetel zona siji supaya data bisa gampang ditransfer saka siji server menyang server liyane.

Kahanane padha karo aplikasi Jawa. Iki uga bisa ditindakake ing server sing beda ing pusat data sing beda, mula biasane duwe zona wektu sing jelas.


java -Duser.timezone=UTC ...

Utawa nalika program lagi mlaku:

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

Lan, mesthi, Hibernate ngidini sampeyan nyetel zona wektu kanthi jelas.

Pisanan, bisa ditemtokake nalika ngonfigurasi SessionFactory:

settings.put(
    AvailableSettings.JDBC_TIME_ZONE,
    TimeZone.getTimeZone("UTC")
);

Kapindho, zona wektu bisa ditemtokakekanggo sesi tartamtu:

Session session = sessionFactory()
    .withOptions()
    .jdbcTimeZone(TimeZone.getTimeZone("UTC"))
    .openSession();

4.5 @TimeZoneStorage anotasi

Asring kedadeyan yen programer wiwit ngrancang basis data adhedhasar kerja ing sawijining negara (lan siji zona wektu), banjur sawise sawetara taun kudu nambah dhukungan kanggo kerja ing zona wektu sing beda.

Mulane, dheweke mung nambah kolom kapisah menyang database kanggo nyimpen zona wektu. Iki minangka kahanan umum sing Hibernate nambahake anotasi khusus sing ngidini sampeyan nyimpen TimeZone tanggal tartamtu ing kolom sing kapisah.

Tuladha:

@TimeZoneStorage(TimeZoneStorageType.COLUMN)
@TimeZoneColumn(name = "birthday_offset_offset")
@Column(name = "birthday_offset")
private OffsetDateTime offsetDateTimeColumn;

@TimeZoneStorage(TimeZoneStorageType.COLUMN)
@TimeZoneColumn(name = "birthday_zoned_offset")
@Column(name = "birthday_zoned")
private ZonedDateTime zonedDateTimeColumn;

Iki kruk. Nanging ana uga alesan kanggo iku: katon ing wektu nalika API DateTime durung ana. Lan ora bisa nyimpen TimeZone ing kelas java.util.Date.

Muga-muga sampeyan ora bakal kerep ndeleng iki ing kode sampeyan.