4.1 ইতিহাসে ভ্রমণ
ডাটাবেসে জাভা অবজেক্ট সংরক্ষণ করার কাজটি জাভা ভাষা তৈরির প্রায় সাথে সাথেই প্রাসঙ্গিক ছিল। সেই সময়ে, জাভা ভাষায় শুধুমাত্র একটি ডেটা টাইপ ছিল, তারিখ, যা UNIX-সময়ের মান অনুযায়ী সময় সংরক্ষণ করত: 1970 সাল থেকে মিলিসেকেন্ডের সংখ্যা হিসাবে।
ঠিক আছে, সেই সময়ে ডেটাবেসগুলিতে তারিখগুলির জন্য ইতিমধ্যেই বিভিন্ন ডেটা টাইপ ছিল, কমপক্ষে তারিখ, সময় এবং তারিখ + সময়ের জন্য পৃথক প্রকার ছিল:
- তারিখ
- টাইম
- টাইমস্ট্যাম্প
অতএব, জাভা ভাষার স্রষ্টারা এতে একটি বিশেষ প্যাকেজ যুক্ত করেছেন - 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
হাইবারনেট একটি বিশেষ টীকা যোগ করেছে ।@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
ডিফল্ট টাইপ ডাটাবেসে তাদের প্রতিনিধিত্ব করতে টাইমস্ট্যাম্প টাইপ ব্যবহার করে।
4.2 নতুন সময়
বর্তমানে, ম্যাপিংয়ের সাথে, সবকিছু অনেক সহজ এবং ভাল। সময়ের সাথে কাজ করার জন্য সমস্ত ডেটাবেস 4 ধরণের ডেটা সমর্থন করে:
- তারিখ - তারিখ: বছর, মাস এবং দিন।
- সময় - সময়: ঘন্টা, মিনিট, সেকেন্ড।
- টাইমস্ট্যাম্প - তারিখ, সময় এবং ন্যানোসেকেন্ড।
- টাইম জোনের সাথে টাইমস্ট্যাম্প - টাইমস্ট্যাম্প এবং টাইম জোন (জোনের নাম বা অফসেট)।
টাইপ প্রতিনিধিত্ব করতে তারিখজাভাতে, আপনাকে java.time.LocalDate
JDK 8 DateTime API থেকে একটি ক্লাস ব্যবহার করতে হবে।
টাইপটাইমডাটাবেস থেকে জাভা থেকে দুই ধরনের দ্বারা প্রতিনিধিত্ব করা যেতে পারে: java.time.LocalTime
এবং java.time.OffsetTime
. জটিল কিছুই না।
এবং সঠিক তারিখ এবং সময় প্রকার দ্বারা উপস্থাপিতটাইমস্ট্যাম্পবেসে, জাভাতে এটি 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
অর্থ হল ক্ষেত্রটি স্বয়ংক্রিয়ভাবে প্রক্রিয়া করা উচিত : হাইবারনেট সিদ্ধান্ত নেবে কোন কলাম এবং টাইপ এই ক্ষেত্রটি ম্যাপ করা উচিত।
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 টাইপে সংরক্ষণ করবে। যা, আসলে, যৌক্তিক, যেহেতু টাইমজোনে সাধারণত "UTC + 3" বা "কায়রো" এর মতো একটি স্ট্রিং নাম থাকে।
4.4 আপনার নিজস্ব সময় অঞ্চল সেট করা
আপনি যখন ডাটাবেসে তারিখ সংরক্ষণের সাথে কাজ করবেন, তখন আপনি এই সত্যটি দেখতে পাবেন যে ইতিমধ্যে 4টি স্থান রয়েছে যেখানে আপনি বর্তমান সময় অঞ্চল সেট করতে পারেন:
- সার্ভার অপারেটিং সিস্টেম;
- ডিবিএমএস;
- জাভা অ্যাপ্লিকেশন
- হাইবারনেট
যদি ডিবিএমএস একটি সময় অঞ্চল (টাইমজোন) নির্দিষ্ট না করে, তবে এটি অপারেটিং সিস্টেম সেটিংস থেকে এটি গ্রহণ করবে। এটি অসুবিধাজনক হতে পারে, যেহেতু ব্যাকআপ ডিবিএমএসগুলি প্রায়শই অন্যান্য ডেটা সেন্টারগুলিতে থাকে যেগুলির নিজস্ব সময় অঞ্চল রয়েছে৷
তাই, প্রায় সব ডিবিএমএস অ্যাডমিন একটি একক জোন সেট করে যাতে ডেটা সহজেই এক সার্ভার থেকে অন্য সার্ভারে স্থানান্তর করা যায়।
পরিস্থিতি একটি জাভা অ্যাপ্লিকেশনের সাথে অনুরূপ। এটি বিভিন্ন ডেটা সেন্টারে বিভিন্ন সার্ভারে চালানো যেতে পারে, তাই এটির সাধারণত একটি সুস্পষ্ট সময় অঞ্চল থাকে।
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
।
আমি সত্যিই আশা করি যে আপনি প্রায়শই আপনার কোডে এটি দেখতে পাবেন না।
GO TO FULL VERSION