4.1 역사 속으로의 소풍
Java 개체를 데이터베이스에 저장하는 작업은 Java 언어가 생성된 직후에 관련이 있었습니다. 당시 Java 언어에는 UNIX 시간 표준(1970년 이후의 밀리초 수)에 따라 시간을 저장하는 날짜라는 데이터 유형이 하나뿐이었습니다.
글쎄, 그 당시 데이터베이스에는 이미 날짜에 대한 다른 데이터 유형이 있었고 최소한 날짜, 시간 및 날짜 + 시간에 대한 별도의 유형이 있었습니다.
- 날짜
- 시간
- 타임스탬프
따라서 Java 언어의 작성자는 클래스가 포함된 java.sql이라는 특수 패키지를 추가했습니다.
- java.sql.날짜
- java.sql.시간
- java.sql.타임스탬프
이러한 클래스를 매핑하는 것은 정말 즐거운 일입니다.
@Entity
public class TemporalValues {
@Basic
private java.sql.Date sqlDate;
@Basic
private java.sql.Time sqlTime;
@Basic
private java.sql.Timestamp sqlTimestamp;
}
그러나 프로그래머들은 클래스로 작업하곤 했기 때문에 Hibernate는 Date 유형의 매핑을 제어하기 위해 java.util.Date
특별한 주석을 추가했습니다 .@Temporal
예:
// 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가지 유형의 데이터를 지원합니다.
- 날짜 - 날짜: 년, 월, 일.
- TIME - 시간: 시, 분, 초.
- TIMESTAMP - 날짜, 시간 및 나노초.
- TIMESTAMP WITH TIME ZONE - TIMESTAMP 및 시간대(구역 이름 또는 오프셋).
유형을 나타내기 위해 날짜java.time.LocalDate
Java에서는 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
당신은 이미 DateTime API 에 익숙하기 때문에 , 이 문제를 기억하는 것은 당신에게 어렵지 않을 것입니다 :)
그것들을 매핑하는 것은 순수한 즐거움입니다.
@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" 또는 "Cairo"와 같은 문자열 이름이 있기 때문에 이는 논리적입니다.
4.4 나만의 시간대 설정
데이터베이스에 날짜를 저장하는 작업을 할 때 현재 시간대를 설정할 수 있는 위치가 이미 4개 있다는 사실을 알게 될 것입니다.
- 서버 운영체제;
- DBMS;
- 자바 애플리케이션
- 최대 절전 모드.
DBMS가 시간대(TimeZone)를 지정하지 않으면 운영 체제 설정에서 가져옵니다. 백업 DBMS는 자체 시간대가 있는 다른 데이터 센터에 있는 경우가 많기 때문에 이는 불편할 수 있습니다.
따라서 거의 모든 DBMS 관리자는 한 서버에서 다른 서버로 데이터를 쉽게 전송할 수 있도록 단일 영역을 설정합니다.
상황은 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가 특정 날짜의 TimeZone을 별도의 열에 저장할 수 있도록 하는 특수 주석을 추가한 일반적인 상황입니다.
예:
@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;
이것은 목발입니다. 그러나 이에 대한 변명도 있습니다. DateTime API가 아직 존재하지 않았을 때 나타났습니다. 그리고 클래스에 TimeZone을 저장하는 것은 불가능했습니다 java.util.Date
.
나는 당신이 당신의 코드에서 이것을 자주 보지 않기를 정말로 바랍니다.
GO TO FULL VERSION