iBATIS (বর্তমানে MyBatis নামে পরিচিত) হল একটি SQL Mapping Framework যা Java objects এবং relational databases এর মধ্যে ম্যাপিং করতে ব্যবহৃত হয়। iBATIS-এর একটি শক্তিশালী বৈশিষ্ট্য হল Nested Objects এবং Collection Mapping, যেখানে আপনি একাধিক সম্পর্কিত অবজেক্ট এবং একাধিক সম্পর্কিত রেকর্ডকে একটি Java অবজেক্টে ম্যাপ করতে পারেন। এটি one-to-many, many-to-one, many-to-many সম্পর্কের ক্ষেত্রেও কার্যকর।
1. Nested Objects Mapping in iBATIS
Nested Objects mapping ব্যবহার করে, iBATIS আপনাকে এক বা একাধিক অবজেক্টের মধ্যে সম্পর্ক স্থাপন করতে সহায়ক। এটি resultMap ব্যবহার করে complex object mapping করার জন্য আদর্শ। একাধিক টেবিলের ডেটাকে একসাথে nested objects হিসেবে Java অবজেক্টে ম্যাপ করা যায়।
Nested Objects Mapping Example:
ধরা যাক, একটি Employee টেবিল এবং একটি Department টেবিল রয়েছে, যেখানে Employee অবজেক্টটি Department অবজেক্টকে একটি nested object হিসেবে ধারণ করে (এটি many-to-one সম্পর্ক)।
Step 1: SQL Mapping File (XML)
<mapper namespace="com.example.mapper.EmployeeMapper">
<!-- ResultMap for Nested Objects -->
<resultMap id="employeeResultMap" type="com.example.model.Employee">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<association property="department" column="department_id" javaType="com.example.model.Department">
<id property="id" column="department_id"/>
<result property="name" column="department_name"/>
</association>
</resultMap>
<!-- Select Employee with Nested Department Object -->
<select id="getEmployeeWithDepartment" resultMap="employeeResultMap">
SELECT e.id, e.name, e.age, d.id AS department_id, d.name AS department_name
FROM employee e
JOIN department d ON e.department_id = d.id
WHERE e.id = #{id}
</select>
</mapper>
Explanation:
<association>ট্যাগ ব্যবহার করে, Employee অবজেক্টের মধ্যে Department অবজেক্টকে nested করা হয়েছে।column="department_id"এবংjavaType="com.example.model.Department"এর মাধ্যমে Employee এবং Department এর সম্পর্ক স্থাপন করা হয়েছে।
Step 2: Java Code
import org.apache.ibatis.session.SqlSession;
public class EmployeeService {
private SqlSession session;
public EmployeeService(SqlSession session) {
this.session = session;
}
public Employee getEmployeeWithDepartment(int id) {
return session.selectOne("com.example.mapper.EmployeeMapper.getEmployeeWithDepartment", id);
}
}
এখানে, getEmployeeWithDepartment মেথডটি Employee অবজেক্টের সাথে সংশ্লিষ্ট Department অবজেক্টকেও ফিরিয়ে দেবে, যা একটি nested object।
2. Collection Mapping in iBATIS
Collection Mapping ব্যবহার করে, iBATIS-এ আপনি একাধিক সম্পর্কিত রেকর্ড বা one-to-many বা many-to-many সম্পর্কের ডেটাকে একটি Java collection (যেমন List, Set) এ ম্যাপ করতে পারেন। আপনি ট্যাগ ব্যবহার করে একাধিক সম্পর্কিত অবজেক্টকে List বা Set-এ ম্যাপ করতে পারেন।
One-to-Many Collection Mapping (Employee - Projects Example)
ধরা যাক, Employee টেবিলের সাথে Project টেবিলের একটি one-to-many সম্পর্ক রয়েছে, যেখানে একজন Employee একাধিক Project তে কাজ করতে পারেন। এটি Collection Mapping এর একটি উদাহরণ।
Step 1: SQL Mapping File (XML)
<mapper namespace="com.example.mapper.EmployeeMapper">
<!-- ResultMap for Employee with Projects -->
<resultMap id="employeeWithProjectsResultMap" type="com.example.model.Employee">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<collection property="projects" ofType="com.example.model.Project">
<result property="id" column="project_id"/>
<result property="name" column="project_name"/>
</collection>
</resultMap>
<!-- Select Employee with Projects -->
<select id="getEmployeeWithProjects" resultMap="employeeWithProjectsResultMap">
SELECT e.id, e.name, e.age, p.id AS project_id, p.name AS project_name
FROM employee e
LEFT JOIN project p ON e.id = p.employee_id
WHERE e.id = #{id}
</select>
</mapper>
Explanation:
<collection>ট্যাগ ব্যবহার করে Employee অবজেক্টের projects প্রপার্টি একটি List হিসাবে ম্যাপ করা হয়েছে।- LEFT JOIN এর মাধ্যমে Employee এবং Project টেবিলের মধ্যে সম্পর্ক স্থাপন করা হয়েছে।
Step 2: Java Code
import org.apache.ibatis.session.SqlSession;
public class EmployeeService {
private SqlSession session;
public EmployeeService(SqlSession session) {
this.session = session;
}
public Employee getEmployeeWithProjects(int id) {
return session.selectOne("com.example.mapper.EmployeeMapper.getEmployeeWithProjects", id);
}
}
এখানে, getEmployeeWithProjects মেথডটি Employee অবজেক্টের সাথে সংশ্লিষ্ট Project অবজেক্টগুলির একটি List রিটার্ন করবে।
3. Many-to-Many Collection Mapping Example (Student - Course)
Many-to-Many সম্পর্কের ক্ষেত্রে একটি Student একাধিক Course এ ভর্তি হতে পারে এবং একটি Course একাধিক Student থাকতে পারে। এই সম্পর্কের জন্য Collection Mapping ব্যবহার করা যেতে পারে।
Step 1: SQL Mapping File (XML)
<mapper namespace="com.example.mapper.StudentMapper">
<!-- ResultMap for Student with Courses -->
<resultMap id="studentWithCoursesResultMap" type="com.example.model.Student">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<collection property="courses" ofType="com.example.model.Course">
<result property="id" column="course_id"/>
<result property="name" column="course_name"/>
</collection>
</resultMap>
<!-- Select Student with Courses -->
<select id="getStudentWithCourses" resultMap="studentWithCoursesResultMap">
SELECT s.id, s.name, s.age, c.id AS course_id, c.name AS course_name
FROM student s
JOIN student_course sc ON s.id = sc.student_id
JOIN course c ON sc.course_id = c.id
WHERE s.id = #{id}
</select>
</mapper>
Explanation:
<collection>ট্যাগ ব্যবহার করে Student এর courses প্রপার্টি একটি List হিসাবে ম্যাপ করা হয়েছে।- JOIN এর মাধ্যমে Student এবং Course টেবিলের মধ্যে সম্পর্ক স্থাপন করা হয়েছে।
Step 2: Java Code
import org.apache.ibatis.session.SqlSession;
public class StudentService {
private SqlSession session;
public StudentService(SqlSession session) {
this.session = session;
}
public Student getStudentWithCourses(int id) {
return session.selectOne("com.example.mapper.StudentMapper.getStudentWithCourses", id);
}
}
এখানে, getStudentWithCourses মেথডটি Student অবজেক্টের সাথে সংশ্লিষ্ট Course অবজেক্টগুলির একটি List রিটার্ন করবে।
4. Best Practices for Nested Objects and Collection Mapping in iBATIS/MyBatis:
- Use
resultMapfor Complex Relationships: জটিল সম্পর্কের জন্যresultMapব্যবহার করা উচিত, যেমন one-to-many বা many-to-many সম্পর্ক। এটি সহজে একাধিক সম্পর্কিত অবজেক্টের ম্যাপিং করার সুযোগ দেয়। - Avoid N+1 Query Problem:
N+1 query problemএড়ানোর জন্য JOIN ব্যবহার করা উচিত, যেমনJOIN FETCHবাLEFT JOINএর মাধ্যমে সম্পর্কিত ডেটাগুলিকে একসাথে লোড করা। - Use
Lazy LoadingandEager LoadingAppropriately: সম্পর্কিত ডেটা লোড করার সময় Lazy Loading এবং Eager Loading ব্যবহার সঠিকভাবে করুন। যদি সম্পর্কিত ডেটা কেবলমাত্র কিছু ক্ষেত্রেই প্রয়োজন হয়, তবে Lazy Loading ব্যবহার করুন। - Optimize SQL Queries for Collections: যখন একাধিক সম্পর্কিত রেকর্ড নিয়ে কাজ করছেন, তখন SQL কুয়েরিগুলি অপটিমাইজ করতে চেষ্টা করুন যাতে একাধিক
JOINঅপারেশন ডেটাবেসের পারফরম্যান্স কমাতে না পারে। - Cache Collection Data: যদি একই সম্পর্কিত ডেটা বার বার ব্যবহার করতে হয়, তবে caching প্রযুক্তি ব্যবহার করতে পারেন (যেমন second-level cache)।
iBATIS/MyBatis-এ nested objects এবং collection mapping একাধিক সম্পর্কিত অবজেক্ট এবং ডেটাকে একটি Java অবজেক্টে ম্যাপ করার জন্য অত্যন্ত কার্যকরী। resultMap এবং <collection> ট্যাগগুলি ব্যবহার করে আপনি one-to-many, many-to-many, এবং many-to-one সম্পর্কের ডেটাকে খুব সহজে Java collections (যেমন List, Set) বা nested objects হিসেবে ম্যাপ করতে পারেন। এটি iBATIS/MyBatis ব্যবহারকারীদের জন্য ডেটাবেসের সাথে সম্পর্কিত ডেটা পরিচালনা করার একটি শক্তিশালী এবং কাস্টমাইজড উপায় প্রদান করে।
Read more