- ভূমিকা
- ও আর এম
- হাইবারনেট
- আর্কিটেকচার
- সেট আপ
- কনফিগারেশন
- সেশন
- পারসিসটেন্ট ক্লাস
- ম্যাপিং ফাইলস
- ম্যাপিং টাইপস
- উদাহরণ
- ও/আর ম্যাপিং
- অ্যানোটেশন
- কুয়েরি
- ক্রাইটেরিয়া কুয়েরি
- নেটিভ এস কিউ এল
- ক্যাশিং
- ব্যাচ প্রসেসিং
- ইন্টারসেপ্টর
ভূমিকা
হাইবারনেট ভালভাবে জানার জন্য জেডিবিসি, রিলেশনাল ডাটাবেজ এবং এস কিউ এল সম্পর্কে জানা থাকতে হবে।
ও আর এম
ও আর এম(ORM) হল অবজেক্ট রিলেশনাল মডেল। এটা হল এমন একটা টেকনিক যাতে প্রোগ্রামিং ল্যাঙ্গুয়েজের (C#, java) অবজেক্ট আর রিলেশনাল ডাটাবেজের টেবিলের মধ্যে ডাটা সহজে আদান প্রদান করা যায়।
জাভার অনেকগুলো ও আর এম ফ্রেমওয়ার্ক আছে। কয়েকটার নাম এখানে উল্লেখ করা হলঃ
- Enterprise JavaBeans Entity Beans
- Java Data Objects
- Castor
- TopLink
- Spring DAO
- Hibernate
হাইবারনেট
হাইবারনেট হল জাভার একটা ও আর এম সল্যুশন। এটি হল ওপেন সোর্স পারসিস্টেন্ট ফ্রেম ওয়ার্ক। হাইবারনেট জাভা ক্লাস আর ডাটাবেজ টেবিলের মধ্যে ম্যাপিং করে এক্স এম এল ফাইল অথবা প্রপারটিজ ফাইল ব্যবহারের মাধ্যমে এবং কোন কোড লেখা ছাড়াই।
আর্কিটেকচার
হাইবারনেট হল একাধিক স্তর বিশিষ্ট আর্কিটেকচার এবং এটি নিজে ও অনেক ধরনের এপিআই ব্যবহার করে। যেটা খুব সহজে আমরা ব্যবহার করতে পারি হাইবারনেটের ব্যবহৃত এপিআই সম্পর্কে জ্ঞান থাকা ছাড়াই। জেডিবিসি, জাভা ট্রানশাকশন এপিআই(JTA), জাভা নেমিং এন্ড ডিরেক্টরি ইন্টারফেস(JNDI) এই গুলো হাইবারনেটে ব্যবহৃত কিছু এপিআই। জেডিবিসি রিলেশনাল ডাটাবেজের সাথে কিছু প্রাথমিক লেভেলের সার্ভিস হাইবারনেট কে সরবারাহ করে থাকে। জেটিএ আর জেএনডিআই হাইবারনেটকে j2ee এর সাথে সমন্বয় সাধন করে।
হাইবারনেট ব্যবহার করা হয় এমন কিছু ক্লাস অবজেক্ট সেগুলো নিয়ে বর্ণনা করা হলঃ
-
কনফিগারেশন অবজেক্ট (Configuration Object)
কনফিগারেশন অবজেক্ট হল হাইবারনেট অ্যাপ্লিকেশনের প্রথম অবজেক্ট। এটা অ্যাপ্লিকেশন শুরু হওয়ার সাথে এই অবজেক্ট তৈরি হয়। এই অবজেক্ট কনফিগারেশন বা প্রপারটিজ এর তথ্য বহন্ করে। কনফিগারেশন অবজেক্টের ২ টা উপাদান আছেঃ
১. ডাটাবেজ কানেকশানঃ এটা কনফিগারেশন ফাইল সাপোর্ট করে। যেমনঃ hibernate.properties, hibernate.cfg.xml
২. ক্লাস ম্যাপিং সেটআপঃ এটা জাভা ক্লাস আর ডাটাবেজ টেবিলের মধ্যে কানেকশান তৈরি করে -
সেশনফ্যাক্টরি অবজেক্ট (SessionFactory Object)
সেশনফ্যাক্টরি অবজেক্ট তৈরি হয় কনফিগারেশন অবজেক্ট ব্যবহার করে। সেশনফ্যাক্টরি অবজেক্টের মাধ্যমে সেশন অবজেক্ট তৈরি হয়। প্রতিটা ডাটাবেজের জন্য একটি সেশনফ্যাক্টরি তৈরি করতে হয়। -
সেশন অবজেক্ট (Session Object)
সেশন অবজেক্ট হল ডাটাবেজের সাথে কানেকশন তৈরি করে। পারসিসটেন্ট অবজেক্ট সেভ এবং ডাটা পড়ে আনে সেশন অবজেক্টের দ্বারা। সেশন অবজেক্ট দীর্ঘ সময় ধরে ওপেন রাখা উচিত নয় কারন এটা থ্রেড সেফ নয়। এই অবজেক্ট প্রয়োজন অনুযায়ী তৈরি করে আবার ধ্বংস করে দিতে হয়। -
ট্রানজেকশন অবজেক্ট (Transaction Object)
ট্রানজেকশন অবজেক্ট ডাটাবেজের একটা ইউনিট এর কাজ সম্পন্ন করে। ডাটাবেজের ট্রানজেকশন ম্যানেজমেন্টের কাজ করে থাকে এটি। -
কুয়েরি অবজেক্ট (Query Object)
কুয়েরি অবজেক্ট sql বা hql ব্যবহার করে হাইবারনেটের ডাটাবেজ সেভ, ডাটা দেখানো ইত্যাদি কাজ সম্পন্ন করে থাকে। -
ক্রাইটেরিয়া অবজেক্ট (Criteria Object)
এইটা ব্যবহার করা হয় অবজেক্ট ওরিয়েন্টেড ক্রাইটেরিয়া কুয়েরি এক্সিকিউট করার জন্য।
কনফিগারেশন
হাইবারনেটের কিছু গুরুত্বপূর্ণ প্রোপার্টিজ আছে সেগুলো নিচে আলোচনা করা হলঃ
১. hibernate.dialect - এইটা হাইবারনেটে এসকিউএল কুয়েরি জেনারেট করে
২. hibernate.connection.driver_class - এখানে জেডিবিসি ক্লাসের নাম লেখা হয়
৩. hibernate.connection.url - এখানে ডাটাবেজের ইউআরএল লেখা হয়
৪. hibernate.connection.username - এখানে ডাটাবেজের এডমিন ইউজার নাম লেখা হয়
৫. hibernate.connection.password - এখানে ডাটাবেজের এডমিন পাসওয়ার্ড লেখা হয়
৬. hibernate.connection.pool_size - কতগুলো কানেকশান হাইবারনেট ডাটাবেজ পুলে রাখবে সেই সাইজটা লেখা হয়
৭. hibernate.connection.autocommit - এইটা অটো কমিট করতে সাহায্য করে
হাইবারনেটের কনফিগারেশনের জন্য তিনভাবে কাজটি করা যায়। সেগুলো হলঃ
১. এক্স এম এল ফাইল ব্যবহার করে
২. প্রোপার্টিজ ফাইল ব্যবহার করে
৩. জাভা ফাইল ব্যবহার করে
সেশন
সেশন ব্যবহার করা হয় ডাটাবেজের কানেকশান পাওয়ার জন্য। যখন ডাটাবেজে কোন ট্রানশাকশন করা হয় তখন প্রতিবার সেশন অবজেক্ট তৈরি করতে হয়। পারসিস্টেন্ট অবজেক্ট ডাটা ধরে রাখে সেশন অবজেক্টের মাধ্যমে। সেশন অবজেক্ট দীর্ঘ সময় ধরে ওপেন রাখা উচিত না কারন এটা থ্রেড সেফ না। এইজন্য সেশন অবজেক্ট প্রয়োজন অনুযায়ী তৈরি করে কাজ শেষে ধ্বংস করে দিতে হয়।
ডাটা অবজেক্ট তিন স্টেজে থাকেঃ
১. ট্রানজিয়েন্ট (transient) - পারসিস্টেন্ট ক্লাসের যে অবজেক্ট সেশনের সাথে সম্পর্ক থাকে না এবং ডাটাবেজে এই ক্লাসের কোন টেবিল থাকে না সেটাই ট্রানজিয়েন্ট অবজেক্ট।
২. পারসিস্টেন্ট (persistent) - পারসিস্টেন্ট ক্লাসের যে অবজেক্ট সেশনের সাথে সম্পর্ক থাকে এবং ডাটাবেজে এই ক্লাসের টেবিল থাকে সেটাই পারসিস্টেন্ট অবজেক্ট।
৩. ডিটাচড (detached) - যখন সেশন ক্লোজ করে দেওয়া হয় তখন পারসিস্টেন্ট অবজেক্ট ডিটাচড অবজেক্টে রূপ নেয়।
পারসিসটেন্ট ক্লাস
হাইবারনেটের মূল বিষয় হচ্ছে জাভা ক্লাস আর ডাটাবেজের টেবিলের সাথে ম্যাপিং। জাভা ক্লাস অবজেক্ট সরাসরি ডাটাবেজে সেভ হয় এবং ডাটা যখন দেখায় টেবিল থেকে অবজেক্টে এসে লোড হয়। এই জাভা ক্লাস কেই পারসিসটেন্ট ক্লাস বলে। কিছু নিয়ম আছে এই ক্লাস তৈরি করার ক্ষেত্রে, সেগুলোকে পোজো(plain old java object) প্রোগ্রামিং মডেল বলে।
নিয়মগুলো হলঃ
১. ক্লাসের একটা ডিফল্ট কন্সট্রাক্টর থাকতে হবে।
২. একটা id প্যারামিটার থাকতে হবে যেটা হবে প্রাইমারী key.
৩. সব প্যারামিটার প্রাইভেট হতে হবে এবং তাদের getter এবং setter মেথড থাকতে হবে।
কোড উদাহরণ
public class Student {
private int id;
private String firstName;
private String lastName;
public Student() {}
public Student(String fname, String lname) {
this.firstName = fname;
this.lastName = lname;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
}
ও/আর ম্যাপিং
হাইবারনেট ও/আর ম্যাপিং তিন ধরনের হয়ঃ
১. কালেকশান ম্যাপিং
২. অ্যাসোসিয়েশন ম্যাপিং
৩. কম্পনেন্ট ম্যাপিং
১. কালেকশান ম্যাপিং
- java.util.Set
- java.util.SortedSet
- java.util.List
- java.util.Collection
- java.util.Map
- java.util.SortedMap
২. অ্যাসোসিয়েশন ম্যাপিং
- One-to-One
- One-to-Many
- Many-to-One
- Many-to-Many
৩. কম্পনেন্ট ম্যাপিং
অ্যানোটেশন
হাইবারনেট জাভা অবজেক্ট আর ডাটাবেজের ভেতরে ম্যাপিং করে এক্স এম এল ফাইল ব্যবহার করে। এক্স এম এল ফাইলটা বলে দেয় কোন জাভা অবজেক্ট ডাটাবেজ টেবিলের কোন কলাম নির্দেশ করে। হাইবারনেট অ্যানোটেশন হল কিছুটা নতুন পদ্ধতি এই ম্যাপিং করার জন্য। এক কথায় এটা হল এক্স এম এল এর রিপ্লেসমেন্ট।
উদাহরণঃ
ডাটাবেজ টেবিল
create table STUDENT (
id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
PRIMARY KEY (id)
);
জাভা ক্লাস
@Entity
@Table(name = "STUDENT")
public class Student {
@Id @GeneratedValue
@Column(name = "id")
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
}
নিচে বিভিন্ন ধরনের অ্যানোটেশন সম্পর্কে আলোচনা করা হলঃ
১. @Entity Annotation - এইটা হল জাভা ক্লাসের আগেই দিতে হয় যা ডাটাবেজের টেবিল নির্দেশ করে। এটকে অবশ্যই দিতে হবে।
২. @Table Annotation - এইটা হল জাভা ক্লাসের আগেই দিতে হয় যা ডাটাবেজের টেবিল নির্দেশ করে। তবে এটা অপশনাল।
৩. @Id and @GeneratedValue Annotations - @Id অ্যানোটেশন প্রাইমারী কি নির্দেশ করে আর @GeneratedValue নির্দেশ করে দেয় কিভাবে প্রাইমারী কি জেনারেট হবে।
৪. @Column Annotation - এইটা জাভা ক্লাসের ভ্যারিয়েবল এর উপর লিখতে হয়। তবে এইটা ও অপশনাল।
কুয়েরি
হাইবারনেট কুয়েরি ল্যাঙ্গুয়েজ হল অবজেক্ট ওরিয়েন্টেড কুয়েরি যা সাধারন এস কিউ এল এর মতই কাজ করে কিন্তু এটা ডাটাবেজের টেবিলের সাথে কাজ করার পরিবর্তে জাভার পারসিসটেন্ট অবজেক্টের সাথে কাজ করে। কুয়েরি অবজেক্ট তৈরি করা হয় সেশন ইন্টারফেসের createQuery(hql) মেথড কলের মাধ্যমে এবং প্যারামিটার ইনপুট হচ্ছে হাইবারনেট কুয়েরি। কুয়েরি ইন্টারফেসের কিছু সাধারন মেথড নিয়ে আলোচনা করা হলঃ
১. public int executeUpdate() - আপডেট অথবা ডিলিট কুয়েরি এক্সিকিউট করা
২. public List list() - কুয়েরি রেসাল্ট লিস্ট আকারে return করা
৩. public Query setFirstResult(int rowno) - যেই row এর ডাটা প্রয়োজন সেই row নাম্বার ইনপুট দিতে হবে
৪. public Query setMaxResult(int rowno) - সর্বোচ্চ যত গুলো row এর ডাটা দেখা প্রয়োজন সেইটা ইনপুট হিসেবে যাবে
৫. public Query setParameter(int position, Object value) - কলাম নাম্বার আর ডাটা অবজেক্ট ইনপুট দিলে ডাটা কাঙ্ক্ষিত কলামে গিয়ে সেভ হয়
৬. public Query setParameter(String name, Object value) - কলাম নাম আর ডাটা অবজেক্ট ইনপুট দিলে ডাটা কাঙ্ক্ষিত কলামে গিয়ে সেভ হয়
উদাহরণঃ
FROM Clause
String hql = "FROM Student";
Query query = session.createQuery(hql);
List results = query.list();
SELECT Clause
String hql = "SELECT E.firstName FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();
ক্রাইটেরিয়া কুয়েরি
ক্রাইটেরিয়া কুয়েরি হল যখন কোন রেসাল্ট পড়ে আনা হয় নির্দিষ্ট কোন ক্রাইটেরিয়ার ভিত্তিতে করা হয়। এর মাধ্যমে ক্রাইটেরিয়া দিয়ে ফিল্টার করে বিভিন্ন ভাবে ডাটা পড়ে আনা যায়। সেশন ইন্টারফেসের createCriteria() মেথড ব্যবহার করে Criteria অবজেক্ট তৈরি করা হয়।
এটা হাইবারনেট ৫.২ ভার্সনে বাদ দিয়ে দেওয়া হয়েছে।
নেটিভ এস কিউ এল
হাইবারনেটে নেটিভ এস কিউ এল কুয়েরি ও সাপোর্ট করে। যদি আমি ওরাকল ডাটাবেজ ব্যবহার করি তাহলে ওরাকল কুয়েরি createSQLQuery() মেথডে প্যারামিটার হিসেবে ইনপুট দিলে সেটা এক্সিকিউট হয়ে যায়। নেটিভ এস কিউ এল এর মাধ্যমে stored procedure কল করা যায়।
code example
String sql = "SELECT * FROM Student";
NativeQuery query = session.createSQLQuery(sql);
query.addEntity(Student.class);
List results = query.list();
ক্যাশিং
হাইবারনেট ক্যাশিং সিস্টেমের পারফরম্যান্স বৃদ্ধি করে। ডাটাবেজ থেকে একই ডাটা বারবার read করতে গেলে এই ক্ষেত্রে ক্যাশিং ওই ডাটা গুলো ক্যাশ করে রাখে। এজন্য ডাটাবেজে সময় হিট করা লাগে না এইজন্য এর পারফরম্যান্স ও বেড়ে যায়।
হাইবারনেটে ক্যাশিং দুই রকমের হয়।
১ .First Level Cache
২. Second Level Cache
১. ফার্স্ট লেভেল ক্যাশ
ফার্স্ট লেভেল ক্যাশ ধ্নরে রাখে সেশন অবজেক্ট ডিফল্টভাবে। ট্রানজেকশন রিকুয়েস্ট পাঠানোর জন্য এইটা অবশ্যই দরকার।
২. সেকেন্ড লেভেল ক্যাশ
সেশনফ্যাক্টরি অবজেক্ট সেকেন্ড লেভেল ক্যাশের ডাটা ধরে রাখে। সেকেন্ড লেভেল ক্যাশে যে ডাটা সেভ হয় সেটা পুরো অ্যাপ্লিকেশনে পাওয়া যায়। কিন্তু সেটা আমাদের কনফিগারেশনে enable করে নিতে হবে।
ব্যাচ প্রসেসিং
যখন এক সঙ্গে অনেকগুলো অবজেক্ট সেভ করা প্রয়োজন হয় তখন হাইবেরনেট এই সমস্ত পারসিস্টেন্ট অবজেক্ট সেকেন্ড লেভেল ক্যাশে সেভ করে রাখে। এত গুলো অবজেক্ট ক্যাশে ধরে রাখতে পারে না তখন OutOfMemoryException দেখায়। এই ক্ষেত্রে ব্যাচ প্রোসেসিং ব্যবহার করে সমস্যা সমাধান করা যায়। যদি ১০০০ টা অবজেক্ট সেভ করতে হয় তাহলে আমরা যদি ব্যাচ সাইজ ৫০ ধরে নেই। তাহলে প্রতি ৫০ টা ডাটা সেভ হওয়ার পর সেশন ফ্লাশ ও ক্লিয়ার করতে হয়।
Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Student student = new Student(.....);
session.save(student);
if( i % 50 == 0 ) {
session.flush();
session.clear();
}
}
tx.commit();
session.close();
ইন্টারসেপ্টর