CodeGym/Java курс/All lectures for BG purposes/Картографиране на дати

Картографиране на дати

На разположение

4.1 Излет в историята

Задачата за запазване на Java обекти в базата данни беше актуална почти веднага след създаването на езика Java. По това време имаше само един тип данни в езика Java, Date, който съхраняваше времето според стандарта за време на UNIX: като брой мorсекунди от 1970 г. насам.

Е, в базите данни по това време вече имаше различни типове данни за дати, поне имаше отделни типове за дата, час и дата + час:

  • ДАТА
  • ВРЕМЕ
  • КЛАПОТО ЗА ЧАС

Затова създателите на езика Java добавиха специален пакет към него - java.sql, който съдържаше класове:

  • java.sql.date
  • java.sql.Time
  • java.sql.timestamp

Картографирането на тези класове е истинско удоволствие:

@Entity
public class TemporalValues {

	@Basic
    private java.sql.Date sqlDate;

	@Basic
    private java.sql.Time sqlTime;

    @Basic
    private java.sql.Timestamp sqlTimestamp;
}

Но тъй като програмистите работеха с класа java.util.Date, Hibernate добави специална анотация, @Temporalза да контролира картографирането на типа Date.

Пример:

// 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;

Типът java.util.Calendarи java.util.Dateтипът по подразбиране използват типа TIMESTAMP , за да ги представят в базата данни.

4.2 Ново време

В момента с картографирането всичко е много по-просто и по-добре. Всички бази данни поддържат 4 вида данни за работа с времето:

  • ДАТА - дата: година, месец и ден.
  • ВРЕМЕ - време: часове, minutesи, секунди.
  • TIMESTAMP - дата, час и наносекунди.
  • TIMESTAMP WITH TIME ZONE - TIMESTAMP и часова зона (име на зона or отместване).

За представяне на типа ДАТАв Java, трябва да използвате клас java.time.LocalDateот JDK 8 DateTime API.

ТипВРЕМЕот базата данни може да бъде представен от два типа от Java: java.time.LocalTimeи java.time.OffsetTime. Нищо сложно.

И точната дата и час, представени от типаКЛАПОТО ЗА ЧАСв основата, в Java може да бъде представен от 4 типа:

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

И накраяЧАСОВ ПЕЧАТ С ЧАСОВА ЗОНАмогат да бъдат представени от два вида:

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

Тъй като вече сте запознати с API на DateTime , запомнянето на този въпрос няма да е трудно за вас :)

Картографирането им е чисто удоволствие:

@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;

Анотацията @Basicозначава, че полето трябва да се обработва автоматично : Hibernate ще реши към коя колона и тип трябва да бъде картографирано това поле.

4.3 Работа с часови зони

Ако часовата зона е част от дата, тогава съхраняването им в базата данни е просто - точно като обикновена дата:

@Basic
private java.time.OffsetDateTime offsetDateTime;

@Basic
private java.time.ZonedDateTime zonedDateTime;

Ако обаче искате да съхранявате часови зони отделно от датата:

@Basic
private java.time.TimeZone timeZone;

@Basic
private java.time.ZoneOffset zonedOffset;

Тогава Hibernate ще ги съхранява в тип VARCHAR по подразбиране. Което всъщност е логично, тъй като TimeZone обикновено има име на низ като "UTC + 3" or "Cairo".

4.4 Задаване на ваша собствена часова зона

Когато работите със запазване на дати в базата данни, ще се натъкнете на факта, че вече има 4 места, където можете да зададете текущата часова зона:

  • Сървърна операционна система;
  • СУБД;
  • Java приложение
  • Хибернация.

Ако СУБД не посочи часова зона (TimeZone), тогава тя ще я вземе от настройките на операционната система. Това може да бъде неудобно, тъй като резервните СУБД често се намират в други центрове за данни, които имат собствена часова зона.

Следователно почти всички администратори на СУБД задават една зона, така че данните да могат лесно да се прехвърлят от един сървър на друг.

Подобна е ситуацията и с Java приложение. Може също да се изпълнява на различни сървъри в различни центрове за данни, така че обикновено има изрична часова зона.

java -Duser.timezone=UTC ...

Или докато програмата работи:

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

И, разбира се, Hibernate ви позволява да зададете изрично вашата часова зона.

Първо, може да се посочи при конфигуриране на SessionFactory:

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

Второ, може да се посочи часовата зоназа конкретна сесия:

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

4.5 @TimeZoneStorage анотация

Често се случва програмистите да започнат да проектират база данни, базирана на работа в една държава (и една часова зона), а след това след няколко години трябва да добавят поддръжка за работа в различни часови зони.

Затова те просто добавиха отделна колона към базата данни за съхраняване на часовата зона. Това е толкова често срещана ситуация, че Hibernate добави специална анотация, която ви позволява да съхранявате часовата зона на конкретна дата в отделна колона.

Пример:

@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;

Това е патерица. Но има и извинение за това: появи се във време, когато API на DateTime все още не съществуваше. И беше невъзможно да се съхрани TimeZone в класа java.util.Date.

Наистина се надявам, че няма да виждате това често в codeа си.

Коментари
  • Популярен
  • Нов
  • Стар
Трябва да сте влезли, за да оставите коментар
Тази страница все още няма коментари