4.1 इतिहास में भ्रमण

जावा ऑब्जेक्ट को डेटाबेस में सहेजने का कार्य जावा भाषा के निर्माण के लगभग तुरंत बाद प्रासंगिक था। उस समय, जावा भाषा में केवल एक डेटा प्रकार था, दिनांक, जो यूनिक्स-समय मानक के अनुसार समय संग्रहीत करता था: 1970 से मिलीसेकंड की संख्या के रूप में।

ठीक है, उस समय डेटाबेस में तारीखों के लिए पहले से ही अलग-अलग डेटा प्रकार थे, कम से कम तारीख, समय और तारीख + समय के लिए अलग-अलग प्रकार थे:

  • तारीख
  • समय
  • TIMESTAMP

इसलिए, जावा भाषा के रचनाकारों ने इसमें एक विशेष पैकेज जोड़ा - java.sql, जिसमें कक्षाएं थीं:

  • java.sql.date
  • java.sql.समय
  • 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एक विशेष एनोटेशन जोड़ा ।@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 प्रकार के डेटा का समर्थन करते हैं:

  • दिनांक - दिनांक: वर्ष, माह और दिन।
  • समय - समय: घंटे, मिनट, सेकंड।
  • TIMESTAMP - दिनांक, समय और नैनोसेकंड।
  • टाइम ज़ोन के साथ टाइमस्टैम्प - टाइमस्टैम्प और टाइम ज़ोन (ज़ोन का नाम या ऑफ़सेट)।

प्रकार का प्रतिनिधित्व करने के लिए तारीखjava.time.LocalDateजावा में, आपको जेडीके 8 डेटटाइम एपीआई से कक्षा का उपयोग करने की आवश्यकता है ।

प्रकारसमयडेटाबेस से जावा से दो प्रकारों का प्रतिनिधित्व किया जा सकता है: java.time.LocalTimeऔर java.time.OffsetTime। कुछ भी जटिल नहीं।

और प्रकार द्वारा दर्शाई गई सटीक तिथि और समयTIMESTAMPआधार में, जावा में इसे 4 प्रकारों द्वारा दर्शाया जा सकता है:

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

और अंत मेंटाइम ज़ोन के साथ टाइमस्टैम्पदो प्रकारों द्वारा दर्शाया जा सकता है:

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

चूंकि आप पहले से ही डेटटाइम एपीआई से परिचित हैं , इसलिए इस मामले को याद रखना आपके लिए मुश्किल नहीं होगा :)

उनका मानचित्रण करना शुद्ध आनंद है:

@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मतलब है कि फ़ील्ड को स्वचालित रूप से संसाधित किया जाना चाहिए : हाइबरनेट यह तय करेगा कि किस कॉलम और प्रकार को इस फ़ील्ड को मैप किया जाना चाहिए।

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;

फिर हाइबरनेट उन्हें डिफ़ॉल्ट रूप से VARCHAR प्रकार में संग्रहीत करेगा। जो, वास्तव में, तार्किक है, क्योंकि TimeZone में आमतौर पर "UTC + 3" या "Cairo" जैसा एक स्ट्रिंग नाम होता है।

4.4 अपना समय क्षेत्र निर्धारित करना

जब आप डेटाबेस में तारीखों को सहेजने के साथ काम करते हैं, तो आप इस तथ्य से रूबरू होंगे कि पहले से ही 4 स्थान हैं जहाँ आप वर्तमान समय क्षेत्र निर्धारित कर सकते हैं:

  • सर्वर ऑपरेटिंग सिस्टम;
  • डीबीएमएस;
  • जावा अनुप्रयोग
  • सीतनिद्रा में होना।

यदि DBMS एक समय क्षेत्र (TimeZone) निर्दिष्ट नहीं करता है, तो यह इसे ऑपरेटिंग सिस्टम सेटिंग्स से लेगा। यह असुविधाजनक हो सकता है, क्योंकि बैकअप DBMS अक्सर अन्य डेटा केंद्रों में स्थित होते हैं जिनका अपना समय क्षेत्र होता है।

इसलिए, लगभग सभी DBMS व्यवस्थापक एक ही क्षेत्र निर्धारित करते हैं ताकि डेटा को एक सर्वर से दूसरे सर्वर पर आसानी से स्थानांतरित किया जा सके।

जावा एप्लिकेशन के साथ स्थिति समान है। इसे विभिन्न डेटा केंद्रों में विभिन्न सर्वरों पर भी चलाया जा सकता है, इसलिए इसका आमतौर पर एक स्पष्ट समय क्षेत्र होता है।


java -Duser.timezone=UTC ...

या जब प्रोग्राम चल रहा हो:

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

और, ज़ाहिर है, हाइबरनेट आपको अपना समय क्षेत्र स्पष्ट रूप से सेट करने की अनुमति देता है।

सबसे पहले, यह सत्र फ़ैक्टरी को कॉन्फ़िगर करते समय निर्दिष्ट किया जा सकता है:

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

दूसरे, समय क्षेत्र निर्दिष्ट किया जा सकता हैएक विशिष्ट सत्र के लिए:

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

4.5 @TimeZoneStorage एनोटेशन

अक्सर ऐसा होता है कि प्रोग्रामर ने एक देश (और एक समय क्षेत्र) में काम करने के आधार पर डेटाबेस डिजाइन करना शुरू कर दिया, और फिर कुछ सालों के बाद उन्हें अलग-अलग समय क्षेत्रों में काम करने के लिए समर्थन जोड़ने की जरूरत पड़ी।

इसलिए, उन्होंने समय क्षेत्र को स्टोर करने के लिए डेटाबेस में बस एक अलग कॉलम जोड़ा। यह ऐसी सामान्य स्थिति है कि हाइबरनेट ने एक विशेष एनोटेशन जोड़ा है जो आपको एक विशिष्ट तिथि के टाइमज़ोन को एक अलग कॉलम में स्टोर करने की अनुमति देता है।

उदाहरण:

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

यह एक बैसाखी है। लेकिन इसके लिए एक बहाना भी है: यह ऐसे समय में सामने आया जब डेटटाइम एपीआई अभी तक मौजूद नहीं था। और TimeZone को क्लास में स्टोर करना असंभव था java.util.Date

मैं वास्तव में आशा करता हूं कि आप इसे अक्सर अपने कोड में नहीं देखेंगे।