Dynamic SQL এবং iBATIS

আইবাটিস (iBATIS) - Java Technologies

422

iBATIS (বর্তমানে MyBatis) হল একটি শক্তিশালী এবং নমনীয় Object-Relational Mapping (ORM) ফ্রেমওয়ার্ক যা SQL statements এবং Java objects এর মধ্যে সম্পর্ক স্থাপন করে। iBATIS SQL কুয়েরিগুলি dynamic হতে সহায়ক করে, যার মাধ্যমে আপনি সহজেই conditional queries এবং dynamic SQL তৈরি করতে পারেন। Dynamic SQL ব্যবহারের মাধ্যমে SQL কুয়েরি লজিকের কিছু অংশকে runtime-এ পরিবর্তন করা যায়, যা ডেটাবেসের কাজের গতিকে আরো নমনীয় এবং কার্যকরী করে তোলে।

iBATIS (MyBatis) এর dynamic SQL ফিচার আপনাকে SQL statements তৈরি করার সময় শর্তাবলী (conditions) এবং প্যারামিটারগুলি সহজভাবে অ্যাড বা পরিবর্তন করতে দেয়। এর মাধ্যমে ডেটাবেসে চাহিদা অনুসারে বিভিন্ন ধরনের কুয়েরি জেনারেট করা যায়, যা সাধারাণ SQL কুয়েরির চেয়ে অনেক বেশি দক্ষ এবং পারফর্ম্যান্ট হতে পারে।


Dynamic SQL in iBATIS

iBATIS এ Dynamic SQL তৈরি করার জন্য XML Mapper ফাইলে কিছু বিশেষ ট্যাগ ব্যবহার করা হয়, যেমন:

এই ট্যাগগুলির মাধ্যমে SQL কুয়েরিতে conditional statements, loops, এবং dynamic conditions ব্যবহার করা যায়, যা runtime-এ SQL কুয়েরি পরিবর্তন করতে সাহায্য করে।


1. The <if> Tag for Conditional SQL

iBATIS এর <if> ট্যাগ ব্যবহার করে SQL কুয়েরিতে শর্ত (conditions) অ্যাড করা হয়। এটি SQL কুয়েরির অংশমাত্র একটি শর্তের ভিত্তিতে ইনক্লুড বা এক্সক্লুড করতে সক্ষম করে।

Example: Using <if> in Dynamic SQL

<select id="getEmployeesBySalary" resultClass="com.example.model.Employee">
    SELECT id, name, salary
    FROM employees
    WHERE 1 = 1
    <if test="minSalary != null">
        AND salary >= #{minSalary}
    </if>
    <if test="maxSalary != null">
        AND salary <= #{maxSalary}
    </if>
</select>

Explanation:

  • এখানে <if> ট্যাগ ব্যবহার করে minSalary এবং maxSalary প্যারামিটারগুলির ভিত্তিতে কুয়েরি কন্ডিশনালভাবে পরিবর্তিত হবে।
  • যদি minSalary বা maxSalary প্রদান না করা হয়, তাহলে সেই অংশটি SQL কুয়েরিতে অন্তর্ভুক্ত হবে না।

2. The <choose> Tag for Multiple Conditions

iBATIS-এ <choose> ট্যাগ ব্যবহার করে if-else লজিক তৈরি করা যায়, যেখানে একাধিক শর্তের মধ্যে কোনটি কাজ করবে তা runtime-এ নির্বাচন করা হয়।

Example: Using <choose> for Conditional SQL

<select id="getEmployeeByDepartment" resultClass="com.example.model.Employee">
    SELECT id, name, salary
    FROM employees
    WHERE 1 = 1
    <choose>
        <when test="department != null">
            AND department = #{department}
        </when>
        <otherwise>
            AND department IS NULL
        </otherwise>
    </choose>
</select>

Explanation:

  • এখানে, <choose> ট্যাগের মাধ্যমে department এর ভিত্তিতে শর্ত প্রয়োগ করা হয়েছে। যদি department প্যারামিটারটি প্রোভাইড করা হয়, তবে নির্দিষ্ট ডিপার্টমেন্টের কর্মচারী পাওয়া যাবে, না হলে ডিপার্টমেন্টের মান NULL হতে হবে।

3. The <foreach> Tag for Loops

iBATIS এর <foreach> ট্যাগ ব্যবহার করে আপনি SQL IN কুয়েরি তৈরি করতে পারেন, যেখানে একাধিক মান একটি কলামের মধ্যে ইনসার্ট করা হয়। এটি একটি loop তৈরি করে এবং একটি প্যারামিটার থেকে একাধিক মান নিয়ে SQL কুয়েরি তৈরি করতে সহায়ক।

Example: Using <foreach> for SQL IN Clause

<select id="getEmployeesByIds" resultClass="com.example.model.Employee">
    SELECT id, name, salary
    FROM employees
    WHERE id IN
    <foreach item="id" collection="idList" open="(" close=")" separator=",">
        #{id}
    </foreach>
</select>

Explanation:

  • এখানে <foreach> ট্যাগের মাধ্যমে idList নামক একটি List থেকে সব ID নিয়ে SQL IN ক্লজ তৈরি করা হয়েছে।
  • open="(" এবং close=")" ব্যবহার করা হয়েছে যাতে SQL ক্লজে সঠিকভাবে প্যারেন্টেসিস যোগ করা হয়।

4. The <trim> Tag for Trimming SQL Strings

iBATIS-এর <trim> ট্যাগ ব্যবহার করা হয় SQL স্ট্রিংয়ে অতিরিক্ত স্পেস বা অপ্রয়োজনীয় ক্যারেক্টার যেমন AND বা OR সরাতে। এটি অনেক সময় ডাইনামিক SQL তৈরির ক্ষেত্রে ব্যবহার হয়, যেখানে বিভিন্ন শর্ত একত্রে যোগ করা হয় এবং অতিরিক্ত ক্যারেক্টারগুলি বাদ দিতে হয়।

Example: Using <trim> for Clean SQL

<select id="getEmployeeByDynamicCriteria" resultClass="com.example.model.Employee">
    SELECT id, name, salary
    FROM employees
    <trim prefix="WHERE" prefixOverrides="AND |OR ">
        <if test="name != null">AND name = #{name}</if>
        <if test="department != null">AND department = #{department}</if>
        <if test="salary != null">AND salary >= #{salary}</if>
    </trim>
</select>

Explanation:

  • <trim> ট্যাগের মাধ্যমে আপনি prefix এবং prefixOverrides ব্যবহার করে অপ্রয়োজনীয় AND বা OR শর্ত সরাতে পারবেন।

5. Combining Dynamic SQL with Parameters

iBATIS এর dynamic SQL এর সাথে প্যারামিটার parameterized queries ব্যবহারের মাধ্যমে আরো কার্যকরী এবং নিরাপদ SQL কুয়েরি তৈরি করা যেতে পারে, যা SQL injection থেকে রক্ষা করে।

Example: Using Dynamic SQL with Parameters

<select id="getEmployeesByNameAndSalary" resultClass="com.example.model.Employee">
    SELECT id, name, salary
    FROM employees
    WHERE 1 = 1
    <if test="name != null">AND name = #{name}</if>
    <if test="salary != null">AND salary >= #{salary}</if>
</select>

Explanation:

  • এখানে name এবং salary প্যারামিটারগুলির ভিত্তিতে SQL কুয়েরি কন্ডিশনালভাবে তৈরি হচ্ছে। #{} সিনট্যাক্স ব্যবহার করে parameterized query তৈরি করা হয়েছে।

Best Practices for Using Dynamic SQL in iBATIS

  1. Avoid Overuse of Dynamic SQL: Dynamic SQL শক্তিশালী হলেও অতিরিক্ত ব্যবহার করলে পারফরম্যান্স ইস্যু সৃষ্টি হতে পারে। শুধুমাত্র সেই ক্ষেত্রে ডাইনামিক SQL ব্যবহার করুন যখন সত্যিই শর্তাবলী পরিবর্তন করা প্রয়োজন।
  2. Use trim to Clean SQL Statements: <trim> ট্যাগ ব্যবহার করে SQL স্ট্রিংয়ে অপ্রয়োজনীয় AND বা OR সরিয়ে দিন, এটি কোডকে পরিষ্কার এবং পড়তে সহজ করে তোলে।
  3. Always Use foreach for List Parameters: যখন SQL কুয়েরি IN কন্ডিশন বা লুপ প্রয়োজন হয়, তখন <foreach> ট্যাগ ব্যবহার করুন, যাতে প্যারামিটারগুলি একসাথে যুক্ত করা যায়।
  4. Use Proper Parameter Validation: Dynamic SQL ব্যবহারের সময় নিশ্চিত করুন যে প্যারামিটারগুলি সঠিকভাবে যাচাই করা হয়েছে এবং SQL injection প্রতিরোধের জন্য সুরক্ষিত।
  5. Minimize Use of OR: যখন শর্তগুলি একাধিক প্যারামিটার দ্বারা কনফিগার করা হয়, তখন OR ক্লজ কম ব্যবহার করুন, কারণ এটি পারফরম্যান্সে প্রভাব ফেলতে পারে।

Dynamic SQL iBATIS (MyBatis)-এ ডেটাবেসের সাথে ইন্টারঅ্যাকশনে একটি অত্যন্ত শক্তিশালী টুল। <if>, <foreach>, <choose>, <trim> ইত্যাদি ট্যাগের মাধ্যমে, আপনি SQL কুয়েরিতে শর্তাবলী এবং প্যারামিটারকে ডাইনামিকভাবে নিয়ন্ত্রণ করতে পারেন। এটি আপনাকে SQL কুয়েরিগুলির নমনীয়তা প্রদান করে, যাতে আপনি runtime-এ SQL কুয়েরি তৈরি বা পরিবর্তন করতে পারেন, যা performance এবং maintainability এর জন্য গুরুত্বপূর্ণ। iBATIS এর এই ডাইনামিক SQL ফিচার আপনার অ্যাপ্লিকেশনে ডেটাবেস অপারেশনগুলোকে আরও কার্যকরী, স্কেলেবল এবং সুরক্ষিত করতে সাহায্য করে।

Content added By

iBATIS (বর্তমানে MyBatis নামে পরিচিত) হল একটি SQL Mapping Framework যা SQL স্টেটমেন্টগুলি Java objects এর সাথে সম্পর্কিত করে। MyBatis ডেটাবেসের সাথে কাজ করার জন্য SQL Mapping ব্যবহারের মাধ্যমে ডেটা অ্যাক্সেস করতে সাহায্য করে। MyBatis এর একটি শক্তিশালী বৈশিষ্ট্য হল Dynamic SQL

Dynamic SQL হল এমন একটি পদ্ধতি যেখানে SQL স্টেটমেন্টগুলি রানটাইমে পরিবর্তিত হয়, অর্থাৎ SQL কোড তৈরি বা কাস্টমাইজ করা যায়, যাতে শর্তাবলী বা বিভিন্ন ফিল্টার ব্যবহারকারী বা ডেটার ওপর নির্ভর করে তৈরি হয়। এটি অনেক সময় WHERE, ORDER BY, INSERT, UPDATE বা DELETE এর মতো কুয়েরি অংশগুলিকে ডায়নামিকভাবে নির্মাণ করতে ব্যবহৃত হয়।

Dynamic SQL এর গুরুত্ব

  1. Flexible Queries:
    • ডাইনামিক SQL স্টেটমেন্ট দিয়ে একাধিক শর্ত বা কন্ডিশনের ভিত্তিতে SQL কুয়েরি তৈরি করা যায়। এটি ব্যবহারকারীর ইনপুট বা অ্যাপ্লিকেশন স্টেটের উপর ভিত্তি করে SQL স্টেটমেন্ট কাস্টমাইজ করতে সাহায্য করে।
  2. Reduced Boilerplate Code:
    • আপনি কুয়েরি স্টেটমেন্টের পুনরাবৃত্তি বা নির্দিষ্ট শর্তাবলী যুক্ত করা থেকে মুক্তি পান। একক স্টেটমেন্টে একাধিক প্যারামিটার বা শর্ত যোগ করতে পারেন।
  3. Improved Maintainability:
    • SQL কোডের পুনঃব্যবহারযোগ্যতা এবং রক্ষণাবেক্ষণ সহজ হয়, কারণ ডাইনামিক SQL কোডটি কমপ্লেক্স শর্তাবলী অথবা ফিল্টারগুলি ইনক্লুড করার জন্য তৈরি করা যেতে পারে।
  4. Performance Optimization:
    • ডাইনামিক SQL এর মাধ্যমে আপনি কেবলমাত্র প্রয়োজনীয় ডেটা লোড করতে পারেন, এবং অপ্রয়োজনীয় অংশ বাদ দিতে পারেন, যা পারফরম্যান্স অপটিমাইজ করতে সাহায্য করে।

MyBatis (iBATIS) এ Dynamic SQL

MyBatis (iBATIS) ডাইনামিক SQL তৈরি করতে XML Mapper এবং , , , ইত্যাদি XML ট্যাগ ব্যবহার করে। এই ট্যাগগুলো SQL স্টেটমেন্টের মধ্যে ডাইনামিক কন্ডিশন এবং অংশ যুক্ত করতে সাহায্য করে।

MyBatis Dynamic SQL এর Tag গুলি:

  1. <if>: একটি শর্ত পরীক্ষা করে এবং যদি শর্তটি সত্য হয়, তাহলে SQL কোডে সেই অংশটি যোগ করা হয়।
  2. <choose>: একাধিক শর্তের মধ্যে প্রথম সত্য শর্ত অনুযায়ী SQL কোড তৈরি করা হয়।
  3. <where>: WHERE ক্লজের জন্য ডাইনামিক শর্ত যোগ করতে ব্যবহৃত হয়। এটি প্রথম শর্তটি যোগ করার জন্য WHERE শব্দটি স্বয়ংক্রিয়ভাবে যুক্ত করে।
  4. <foreach>: একাধিক মান বা আইটেমের জন্য একটি লুপ চালানোর জন্য ব্যবহৃত হয়, যেমন একটি IN কুয়েরি তৈরি করতে।

Dynamic SQL Example in MyBatis

Step 1: Mapper XML with Dynamic SQL

ধরা যাক, আমাদের একটি Employee ক্লাস এবং EmployeeMapper.xml ফাইল তৈরি করতে হবে, যেখানে ডাইনামিক SQL কুয়েরি তৈরি করা হবে।

EmployeeMapper.xml - Dynamic SQL
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.EmployeeMapper">

    <!-- Dynamic SQL Example -->
    <select id="findEmployees" resultType="com.example.model.Employee">
        SELECT * FROM Employee
        <where>
            <if test="name != null">
                AND name = #{name}
            </if>
            <if test="department != null">
                AND department = #{department}
            </if>
            <if test="salary != null">
                AND salary > #{salary}
            </if>
        </where>
    </select>

    <!-- Dynamic SQL with Choose Example -->
    <select id="findEmployeeByIdOrName" resultType="com.example.model.Employee">
        SELECT * FROM Employee
        <where>
            <choose>
                <when test="id != null">
                    AND id = #{id}
                </when>
                <when test="name != null">
                    AND name = #{name}
                </when>
                <otherwise>
                    AND department = 'Unknown'
                </otherwise>
            </choose>
        </where>
    </select>

    <!-- Dynamic SQL with foreach Example (for IN clause) -->
    <select id="findEmployeesByIds" resultType="com.example.model.Employee">
        SELECT * FROM Employee
        WHERE id IN
        <foreach collection="ids" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </select>

</mapper>

Explanation of Tags Used:

  • <if>: যদি কোনো প্যারামিটার (যেমন name, department, salary) প্রদান করা হয়, তাহলে সেই শর্ত SQL কুয়েরিতে যোগ হবে।

    <if test="name != null">
        AND name = #{name}
    </if>
    
  • <choose>: <choose> ব্লক ব্যবহার করে, আপনি একাধিক শর্ত পরীক্ষা করতে পারেন এবং যেকোনো শর্ত পূর্ণ হলে সেই শর্ত অনুসারে SQL কোড তৈরি হবে। <when> এবং <otherwise> ব্যবহৃত হয়।

    <choose>
        <when test="id != null">
            AND id = #{id}
        </when>
        <otherwise>
            AND department = 'Unknown'
        </otherwise>
    </choose>
    
  • <foreach>: এটি ব্যবহার করা হয় একাধিক মান বা আইটেমের জন্য, যেমন IN clause-এর জন্য।

    <foreach collection="ids" item="id" open="(" close=")" separator=",">
        #{id}
    </foreach>
    

Step 2: Mapper Interface (EmployeeMapper.java)

EmployeeMapper Interface:

package com.example.mapper;

import com.example.model.Employee;
import java.util.List;

public interface EmployeeMapper {
    // Find employees based on dynamic criteria
    List<Employee> findEmployees(String name, String department, Double salary);

    // Find employee by ID or Name (dynamic choice)
    Employee findEmployeeByIdOrName(Integer id, String name);

    // Find employees by a list of IDs (dynamic IN clause)
    List<Employee> findEmployeesByIds(List<Integer> ids);
}

Explanation:

  • findEmployees method: এটি Dynamic SQL ব্যবহার করে name, department, এবং salary এর ভিত্তিতে ফিল্টারিং করবে।
  • findEmployeeByIdOrName method: এটি choose ব্লক ব্যবহার করে প্রথমে id এবং পরে name অনুসারে ডেটা ফিল্টার করবে। যদি কোন শর্ত পূর্ণ না হয়, তবে Unknown ডিপার্টমেন্ট প্রদান করবে।
  • findEmployeesByIds method: এটি foreach ব্লক ব্যবহার করে, IN clause দিয়ে একাধিক id দিয়ে সার্চ করবে।

Step 3: MyBatis Session Setup and Testing

Main Application Code (Main.java):

package com.example;

import com.example.mapper.EmployeeMapper;
import com.example.model.Employee;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // MyBatis configuration and session factory setup
        String resource = "mybatis-config.xml";
        InputStream inputStream = Main.class.getClassLoader().getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // Open session
        try (SqlSession session = sqlSessionFactory.openSession()) {
            EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
            
            // Test Dynamic SQL for finding employees
            List<Employee> employees = employeeMapper.findEmployees("John", null, 50000.0);
            for (Employee employee : employees) {
                System.out.println(employee);
            }

            // Test Dynamic SQL with Choose (id or name)
            Employee employee = employeeMapper.findEmployeeByIdOrName(null, "John");
            System.out.println(employee);

            // Test Dynamic SQL with IN clause (foreach)
            List<Employee> employeesByIds = employeeMapper.findEmployeesByIds(Arrays.asList(1, 2, 3));
            for (Employee e : employeesByIds) {
                System.out.println(e);
            }
        }
    }
}

Explanation:

  • findEmployees: এটি ডাইনামিক SQL ব্যবহার করে name এবং salary ফিল্টার করবে।
  • findEmployeeByIdOrName: এটি choose ব্যবহার করে id বা name অনুসারে ডেটা খোঁজে।
  • **findEmployees

ByIds**: এটি একাধিক id এর ভিত্তিতে ডেটা খুঁজে বের করবে, IN clause ব্যবহার করে।


Dynamic SQL MyBatis (iBATIS) এ একটি শক্তিশালী বৈশিষ্ট্য যা SQL কুয়েরি গুলিকে রানটাইমে কাস্টমাইজ করতে সাহায্য করে। , , এবং এর মতো MyBatis এর XML ট্যাগ গুলি ব্যবহার করে ডাইনামিক কুয়েরি তৈরি করা যায়। এটি আপনাকে SQL কোডের মধ্যে শর্তাবলী এবং কাস্টম প্যারামিটার অন্তর্ভুক্ত করতে দেয়, যা আপনার অ্যাপ্লিকেশনকে আরও নমনীয় এবং পারফরম্যান্স-বান্ধব করে তোলে।

Content added By

iBATIS (বর্তমানে MyBatis নামে পরিচিত) ডাইনামিক SQL তৈরির জন্য একটি শক্তিশালী ফিচার সরবরাহ করে, যা বিভিন্ন ধরনের কন্ডিশন বা ফিল্টারগুলির ওপর ভিত্তি করে SQL স্টেটমেন্টগুলি পরিবর্তন করতে পারে। এটি XML Mapper ফাইলের মাধ্যমে SQL কুয়েরি তৈরি এবং ডাইনামিকভাবে তৈরি করা সম্ভব। MyBatis-এ Dynamic SQL তৈরির জন্য <if>, <choose>, <when>, <otherwise>, <foreach> ইত্যাদি ট্যাগ ব্যবহার করা হয়।

ডাইনামিক SQL আপনার কুয়েরির মধ্যে শর্ত, লুপ, এবং বিকল্প যুক্ত করতে সাহায্য করে, যা ডেটা ফিল্টারিং এবং কন্ডিশনাল ডেটাবেস অপারেশন আরও নমনীয় করে তোলে।

Dynamic SQL তৈরি করতে iBATIS / MyBatis-এ ব্যবহৃত সাধারণ ট্যাগসমূহ:

  1. <if>: একটি শর্ত যোগ করতে ব্যবহার করা হয়।
  2. <choose>, <when>, <otherwise>: একাধিক শর্তের মধ্যে কোনটি ব্যবহার হবে তা নির্ধারণ করতে।
  3. <foreach>: একটি লুপের মাধ্যমে অনেক মান পাস করার জন্য ব্যবহৃত হয়।
  4. <trim>: অপ্রয়োজনীয় স্পেস বা কমা মুছে ফেলার জন্য ব্যবহৃত হয়।

Dynamic SQL Example:

এখানে, আমরা দেখব কিভাবে iBATIS (MyBatis) XML Mapper ফাইলে Dynamic SQL তৈরি করা যায়। উদাহরণ হিসেবে একটি Employee টেবিল এবং তার জন্য ডাইনামিক SELECT, INSERT, UPDATE কুয়েরি তৈরি করা হবে।


1. SELECT Query with Dynamic SQL

ধরা যাক, আমাদের একটি Employee টেবিল আছে এবং আমরা বিভিন্ন শর্তের ভিত্তিতে কর্মচারী খুঁজে বের করতে চাই।

EmployeeMapper.xml - Dynamic SELECT Example:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//iBATIS//DTD Mapper 3.0//EN" "http://ibatis.apache.org/dtd/sql-map-3.dtd">
<mapper namespace="com.example.mapper.EmployeeMapper">

    <!-- Dynamic SELECT Query to find employees based on conditions -->
    <select id="findEmployees" resultType="com.example.model.Employee">
        SELECT id, name, department, salary
        FROM employee
        WHERE 1 = 1
        <if test="name != null">
            AND name = #{name}
        </if>
        <if test="department != null">
            AND department = #{department}
        </if>
        <if test="salary != null">
            AND salary = #{salary}
        </if>
    </select>

</mapper>

ব্যাখ্যা:

  • <if> ট্যাগ: এখানে তিনটি শর্ত (name, department, এবং salary) সহ SQL কুয়েরি তৈরি করা হয়েছে। যদি কোন শর্তের মান null না হয়, তবে তা SQL কুয়েরিতে যোগ হবে।
  • WHERE 1 = 1: এটি SQL কুয়েরির জন্য একটি বেস শর্ত দেয়, যাতে পরবর্তী শর্তগুলোকে যোগ করা সহজ হয়।

Java Code to Call the Dynamic SQL:

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.example.model.Employee;
import java.util.List;

public class EmployeeApp {

    public static void main(String[] args) {
        // Step 1: Build SqlSessionFactory from the configuration file
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder()
                .build(EmployeeApp.class.getResourceAsStream("/sql-map-config.xml"));

        // Step 2: Open a session
        try (SqlSession session = sessionFactory.openSession()) {

            // Step 3: Execute dynamic SQL query using the Mapper
            EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
            
            // Call the dynamic query with some parameters
            List<Employee> employees = mapper.findEmployees("John Doe", "HR", null);
            for (Employee employee : employees) {
                System.out.println("Employee: " + employee.getName() + ", " + employee.getDepartment());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

এখানে:

  • findEmployees মেথডটি name, department, এবং salary প্যারামিটার দিয়ে ডাইনামিক SQL কুয়েরি চালায়।
  • যদি কোন প্যারামিটার null না হয়, তাহলে সেই শর্ত SQL কুয়েরিতে যোগ করা হয়।

2. Dynamic INSERT Query Example

ধরা যাক, আমরা একটি নতুন Employee ইনসার্ট করতে চাই, এবং কেবলমাত্র নির্দিষ্ট ফিল্ডগুলো ইনপুট হিসেবে প্রদান করব। Dynamic INSERT কুয়েরি ব্যবহার করলে আমরা ফিল্ডগুলি শর্ত অনুসারে যুক্ত করতে পারি।

Dynamic INSERT Query:

<insert id="insertEmployee" parameterType="com.example.model.Employee">
    INSERT INTO employee (name, department, salary)
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="name != null">name,</if>
        <if test="department != null">department,</if>
        <if test="salary != null">salary,</if>
    </trim>
    <trim prefix="VALUES (" suffix=")" suffixOverrides=",">
        <if test="name != null">#{name},</if>
        <if test="department != null">#{department},</if>
        <if test="salary != null">#{salary},</if>
    </trim>
</insert>

ব্যাখ্যা:

  • <trim>: এখানে prefix, suffix, এবং suffixOverrides ব্যবহার করে SQL কুয়েরির অতিরিক্ত কমা সরিয়ে ফেলা হচ্ছে।
  • <if>: ফিল্ডের মান null না থাকলে তা কুয়েরিতে যোগ হবে।

Java Code to Insert Employee:

Employee newEmployee = new Employee();
newEmployee.setName("Jane Doe");
newEmployee.setDepartment("IT");
newEmployee.setSalary(75000);

mapper.insertEmployee(newEmployee);
session.commit();  // Commit transaction

এখানে, insertEmployee মেথডটি ডাইনামিক SQL কুয়েরি চালায় এবং ইনপুট ফিল্ডগুলো যদি null না হয়, তবে সেগুলো SQL কুয়েরিতে যোগ হয়।


3. Dynamic UPDATE Query Example

আমরা যদি ডাইনামিকভাবে কোনো Employee এর তথ্য আপডেট করতে চাই, তবে আমরা <set> ট্যাগ ব্যবহার করে আপডেট স্টেটমেন্টটি তৈরি করতে পারি।

Dynamic UPDATE Query:

<update id="updateEmployee" parameterType="com.example.model.Employee">
    UPDATE employee
    <set>
        <if test="name != null">name = #{name},</if>
        <if test="department != null">department = #{department},</if>
        <if test="salary != null">salary = #{salary},</if>
    </set>
    WHERE id = #{id}
</update>

ব্যাখ্যা:

  • <set>: এটি একটি UPDATE কুয়েরির জন্য ব্যবহার করা হয়, যাতে কেবলমাত্র পরিবর্তিত ফিল্ডগুলো আপডেট হয়।
  • <if>: কেবলমাত্র যদি মান null না হয়, তাহলে সেই ফিল্ডটি আপডেট করা হবে।

Java Code to Update Employee:

Employee employeeToUpdate = new Employee();
employeeToUpdate.setId(1);
employeeToUpdate.setName("Updated Name");
employeeToUpdate.setDepartment("Sales");

mapper.updateEmployee(employeeToUpdate);
session.commit();  // Commit transaction

4. Dynamic DELETE Query Example

যখন আমরা একটি Employee রেকর্ড ডিলিট করতে চাই, তবে আমরা সেই রেকর্ডের ID অথবা অন্যান্য শর্তের ভিত্তিতে ডিলিট কুয়েরি তৈরি করতে পারি।

Dynamic DELETE Query:

<delete id="deleteEmployee" parameterType="int">
    DELETE FROM employee
    WHERE id = #{id}
</delete>

Java Code to Delete Employee:

mapper.deleteEmployee(1);  // Delete employee with ID 1
session.commit();  // Commit transaction

iBATIS (MyBatis) তে Dynamic SQL ব্যবহার করা অনেক সহজ এবং এটি আপনাকে বিভিন্ন শর্তের ভিত্তিতে SQL কুয়েরি পরিবর্তন করতে সক্ষম করে। এখানে উল্লেখিত কিছু গুরুত্বপূর্ণ Dynamic SQL ট্যাগ:

  1. <if>: শর্ত ভিত্তিক SQL অংশ যোগ করার জন্য।
  2. <choose>, <when>, <otherwise>: একাধিক শর্তের মধ্যে একটি নির্বাচন করতে।
  3. <foreach>: লুপের মাধ্যমে মান পাস করার জন্য।
  4. <trim>: অপ্রয়োজনীয় স্পেস বা কমা সরিয়ে ফেলার জন্য।

এই কৌশলগুলি আপনার ডেটাবেস অপারেশনগুলোকে আরও নমনীয়, কার্যকরী এবং স্কেলেবল করতে সহায়ক হবে।

Content added By

iBATIS (বর্তমানে MyBatis নামে পরিচিত) SQL কোডে dynamic SQL ব্যবহারের জন্য বিভিন্ন ট্যাগ প্রদান করে। এগুলি আপনাকে SQL কোয়েরি ডাইনামিকভাবে তৈরি করতে সহায়তা করে, যেখানে আপনি কন্ডিশনাল স্টেটমেন্ট, লিস্ট প্রসেসিং, এবং অন্যান্য ডাইনামিক ফিল্টারিং কার্যকরভাবে ব্যবহার করতে পারেন। এই ট্যাগগুলি হল:

  1. <if>: কন্ডিশনাল লজিক তৈরি করার জন্য ব্যবহার করা হয়।
  2. <choose>: if-else লজিকের জন্য ব্যবহৃত হয়, যেখানে একটি শর্ত মেলালে পরবর্তী শর্তগুলোর পরীক্ষা হয় না।
  3. <foreach>: একটি লিস্ট বা অ্যারে থেকে একাধিক মানের সাথে IN কন্ডিশন তৈরি করতে ব্যবহৃত হয়।
  4. <where>: SQL WHERE ক্লজ তৈরিতে ব্যবহৃত হয়, যেখানে স্বয়ংক্রিয়ভাবে AND যোগ করা হয়।

এখানে এই ট্যাগগুলির বিস্তারিত ব্যবহার এবং উদাহরণ দেওয়া হলো।


1. IF Tag

<if> ট্যাগটি SQL কোডে একটি শর্ত নির্ধারণ করার জন্য ব্যবহৃত হয়। যখন একটি কন্ডিশন মেট হবে, তখন সেই অংশ SQL কোয়েরিতে অন্তর্ভুক্ত হবে।

Example: Using <if> for Conditional SQL

<select id="getEmployeeByConditions" resultType="Employee">
    SELECT * FROM employees
    <where>
        <if test="name != null">
            AND name = #{name}
        </if>
        <if test="email != null">
            AND email = #{email}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>

Explanation:

  • <if test="name != null">: যদি name প্যারামিটারটি null না হয়, তবে AND name = #{name} এই SQL শর্তটি কুয়েরিতে যোগ হবে।
  • <where>: where ব্লকটি AND শর্ত যোগ করার ক্ষেত্রে অতিরিক্ত AND যোগ করা এড়ায়, যাতে অপ্রয়োজনীয় AND কন্ডিশন না থাকে।

Usage:

Map<String, Object> params = new HashMap<>();
params.put("name", "John");
params.put("email", "john@example.com");

List<Employee> employees = sqlSession.selectList("getEmployeeByConditions", params);

2. CHOOSE Tag

<choose> ট্যাগটি if-else লজিকের মতো কাজ করে, যেখানে আপনি একাধিক শর্তের মধ্যে প্রথম সত্য শর্তটি নির্বাচন করতে পারেন।

Example: Using <choose> for Conditional SQL

<select id="getEmployeeByType" resultType="Employee">
    SELECT * FROM employees
    <where>
        <choose>
            <when test="status == 'active'">
                AND status = 'active'
            </when>
            <when test="status == 'inactive'">
                AND status = 'inactive'
            </when>
            <otherwise>
                AND status IS NULL
            </otherwise>
        </choose>
    </where>
</select>

Explanation:

  • <choose>: এটি একটি if-else ব্লকের মতো কাজ করে, যেখানে <when> এবং <otherwise> অংশ রয়েছে।
  • <when>: প্রথম সত্য শর্ত মেললেই পরবর্তী শর্তগুলো পরীক্ষা করা হয় না।
  • <otherwise>: সব শর্ত ভুল হলে এই অংশটি কার্যকর হয়।

Usage:

Map<String, String> params = new HashMap<>();
params.put("status", "active");

List<Employee> employees = sqlSession.selectList("getEmployeeByType", params);

3. FOREACH Tag

<foreach> ট্যাগটি একটি লিস্ট বা অ্যারের মাধ্যমে একাধিক মান নিয়ে IN কন্ডিশন তৈরি করার জন্য ব্যবহৃত হয়। এটি ডাইনামিকভাবে ইনপুট মানগুলিকে একটি SQL কোয়েরির অংশে যোগ করে।

Example: Using <foreach> for IN Clause

<select id="getEmployeesByIds" resultType="Employee">
    SELECT * FROM employees
    WHERE id IN
    <foreach item="id" collection="ids" open="(" close=")" separator=",">
        #{id}
    </foreach>
</select>

Explanation:

  • <foreach>: এটি একটি লুপের মতো কাজ করে এবং ids লিস্টের প্রতিটি উপাদানকে IN কন্ডিশনে যোগ করে।
  • open="(" এবং close=")": এটি SQL কোয়েরির IN ক্লজে () যোগ করে।
  • separator=",": এটি লিস্টের মধ্যে কমা যোগ করে।

Usage:

List<Integer> ids = Arrays.asList(1, 2, 3, 4);

Map<String, Object> params = new HashMap<>();
params.put("ids", ids);

List<Employee> employees = sqlSession.selectList("getEmployeesByIds", params);

4. WHERE Tag

<where> ট্যাগটি WHERE ক্লজে ডাইনামিক শর্ত যোগ করার জন্য ব্যবহৃত হয়। এটি স্বয়ংক্রিয়ভাবে AND বা OR যোগ করে এবং প্রয়োজনে অতিরিক্ত শর্তও বাদ দেয়।

Example: Using <where> for SQL Conditions

<select id="getEmployeesByConditions" resultType="Employee">
    SELECT * FROM employees
    <where>
        <if test="name != null">AND name = #{name}</if>
        <if test="age != null">AND age = #{age}</if>
        <if test="email != null">AND email = #{email}</if>
    </where>
</select>

Explanation:

  • <where>: এটি একটি SQL কুয়েরির মধ্যে WHERE ক্লজ তৈরি করে এবং শর্তগুলো AND দিয়ে যুক্ত হয়।
  • <if>: যদি কোনো শর্ত থাকে, তবে সেটি SQL কুয়েরিতে যোগ হবে, অন্যথায় তা বাদ যাবে।

Usage:

Map<String, Object> params = new HashMap<>();
params.put("name", "John");
params.put("age", 30);

List<Employee> employees = sqlSession.selectList("getEmployeesByConditions", params);

Combining All Tags in a Single Query

আপনি সমস্ত ডাইনামিক SQL ট্যাগ ব্যবহার করে একটি জটিল কুয়েরি তৈরি করতে পারেন।

Example: Combining IF, CHOOSE, FOREACH, and WHERE

<select id="getEmployeesByComplexConditions" resultType="Employee">
    SELECT * FROM employees
    <where>
        <if test="name != null">AND name = #{name}</if>
        <if test="age != null">AND age = #{age}</if>
        <choose>
            <when test="status == 'active'">
                AND status = 'active'
            </when>
            <when test="status == 'inactive'">
                AND status = 'inactive'
            </when>
            <otherwise>
                AND status IS NULL
            </otherwise>
        </choose>
        <if test="ids != null and ids.size() > 0">
            AND id IN
            <foreach item="id" collection="ids" open="(" close=")" separator=",">
                #{id}
            </foreach>
        </if>
    </where>
</select>

Explanation:

  • <if>: ডাইনামিক কন্ডিশনাল শর্ত যোগ করতে ব্যবহৃত হয়।
  • <choose>: status এর জন্য if-else লজিক প্রয়োগ করা হয়।
  • <foreach>: একাধিক আইডি দিয়ে IN কন্ডিশন তৈরি করা হয়।

iBATIS (MyBatis) এর Dynamic SQL ট্যাগগুলো SQL কোয়েরি তৈরি করার ক্ষেত্রে খুবই কার্যকরী। আপনি <if>, <choose>, <foreach>, এবং <where> ব্যবহার করে কোয়েরি কোডকে আরও ফ্লেক্সিবল এবং ডাইনামিক করে তুলতে পারেন, যা অ্যাপ্লিকেশনের পারফরম্যান্স উন্নত করতে সাহায্য করে।

  • <if>: কন্ডিশনাল শর্ত যোগ করতে ব্যবহৃত হয়।
  • <choose>: if-else শর্ত তৈরির জন্য ব্যবহৃত হয়।
  • <foreach>: একাধিক মান দিয়ে IN কন্ডিশন তৈরি করার জন্য ব্যবহৃত হয়।
  • <where>: WHERE ক্লজ তৈরি করার জন্য ব্যবহৃত হয়, যাতে অপ্রয়োজনীয় AND বাদ যায়।

এই ট্যাগগুলির সাহায্যে MyBatis-এ SQL কোড আরও শক্তিশালী এবং কার্যকরী করা সম্ভব।

Content added By

iBATIS (MyBatis) একটি শক্তিশালী SQL ম্যাপিং ফ্রেমওয়ার্ক যা SQL এবং Java objects-এর মধ্যে সম্পর্ক স্থাপন করে। Dynamic SQL হল একটি শক্তিশালী বৈশিষ্ট্য যা iBATIS/MyBatis এ ব্যবহার করা হয়, যা SQL কুয়েরিগুলিকে চলাকালীন সময়ে তৈরি করার সুযোগ দেয়। এই পদ্ধতিটি conditional, optional, বা parameterized কুয়েরি তৈরির ক্ষেত্রে বিশেষভাবে উপকারী, এবং এটি বিভিন্ন পরিস্থিতিতে complex SQL queries তৈরি করতে সাহায্য করে।

Dynamic SQL এর মাধ্যমে, আপনি SQL কুয়েরি তৈরি করতে পারেন যা কোড রান করার সময় ভিন্ন ভিন্ন শর্তাবলী (conditions) অনুযায়ী পরিবর্তিত হতে পারে।

iBATIS/MyBatis Dynamic SQL

iBATIS বা MyBatis এ Dynamic SQL তৈরির জন্য বিভিন্ন XML tags এবং annotations ব্যবহার করা যায়। এখানে কিছু সাধারণ কৌশল এবং পদ্ধতি দেওয়া হয়েছে।


1. Using <if> and <where> for Dynamic SQL

a) <if> Tag:

<if> ট্যাগের সাহায্যে আপনি SQL কুয়েরির অংশ যোগ বা বাদ করতে পারেন, যা নির্ভর করে কিছু শর্তের উপর। এটি খুবই উপকারী যখন কিছু কন্ডিশনাল লজিক প্রয়োগ করতে হয়, যেমন WHERE ক্লজের মধ্যে কিছু অংশ যোগ করা।

Example: Using <if> Tag in SQL
<select id="selectStudent" resultType="com.example.Student">
    SELECT * FROM student
    <where>
        <if test="id != null">
            AND id = #{id}
        </if>
        <if test="name != null">
            AND name = #{name}
        </if>
        <if test="course != null">
            AND course = #{course}
        </if>
    </where>
</select>

Explanation:

  • <if test="id != null">: যদি id null না হয়, তবে AND id = #{id} অংশটি SQL কুয়েরিতে যোগ হবে।
  • <where>: এটি AND বা OR এর মতো যুক্তি যোগ করার জন্য ব্যবহৃত হয়। এটি ডাইনামিকভাবে কুয়েরি জেনারেট করতে সাহায্য করে এবং সঠিকভাবে SQL ফর্ম্যাটিং নিশ্চিত করে।

2. Using <choose>, <when>, and <otherwise> for Conditional SQL

<choose>, <when>, and <otherwise> ট্যাগগুলি SQL কুয়েরির মধ্যে switch-case বা if-else শর্তাবলী তৈরি করতে ব্যবহৃত হয়। এটি ব্যবহারকারী থেকে multiple conditions অনুযায়ী সঠিক SQL কুয়েরি নির্বাচন করতে সাহায্য করে।

Example: Using <choose> for Conditional Logic
<select id="selectStudentByCourse" resultType="com.example.Student">
    SELECT * FROM student
    <where>
        <choose>
            <when test="course != null">
                AND course = #{course}
            </when>
            <when test="name != null">
                AND name = #{name}
            </when>
            <otherwise>
                AND id > 0
            </otherwise>
        </choose>
    </where>
</select>

Explanation:

  • <choose>: একাধিক শর্তের মধ্যে থেকে একটি শর্ত সঠিক হলে তা কার্যকর হবে, যদি কোন শর্ত পূর্ণ না হয় তবে <otherwise> ব্লকটি কার্যকর হবে।
  • <when>: এটি if-else শর্তের মতো কাজ করে, যেখানে প্রথম true শর্তটি কার্যকর হবে।

3. Using <trim> for Removing Unwanted SQL Parts

<trim> ট্যাগটি বিশেষভাবে leading এবং trailing SQL অংশগুলি (যেমন AND বা OR) সরাতে ব্যবহৃত হয়। এটি খুবই উপকারী যখন আপনি একাধিক কন্ডিশনাল অপারেটর তৈরি করেন এবং অবাঞ্ছিত AND বা OR অপারেটরগুলি বাদ দিতে চান।

Example: Using <trim> to Remove Leading and Trailing SQL Parts
<select id="selectStudent" resultType="com.example.Student">
    SELECT * FROM student
    <trim prefix="WHERE" suffixOverrides="AND">
        <if test="id != null">
            AND id = #{id}
        </if>
        <if test="name != null">
            AND name = #{name}
        </if>
        <if test="course != null">
            AND course = #{course}
        </if>
    </trim>
</select>

Explanation:

  • <trim prefix="WHERE" suffixOverrides="AND">: এটি কুয়েরি শুরুতে WHERE যোগ করবে, এবং শেষে AND বাদ দিবে।
  • suffixOverrides="AND": যদি কুয়েরির শেষে AND থাকে, তাহলে তা সরিয়ে দেওয়া হবে।

4. Using <foreach> for Iterating Collections (Lists or Arrays)

<foreach> ট্যাগটি ব্যবহারকারী ইনপুটের জন্য list বা array ব্যবহার করার জন্য উপকারী। আপনি এটি একটি ইনপুট হিসাবে একটি list of values ব্যবহার করতে পারেন এবং IN SQL কুয়েরি তৈরি করতে পারেন।

Example: Using <foreach> to Handle Collections
<select id="selectStudentsByIds" resultType="com.example.Student">
    SELECT * FROM student
    WHERE id IN
    <foreach item="id" collection="ids" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

Explanation:

  • <foreach>: এটি id গুলোর একটি list বা array নিয়ে SQL কুয়েরির IN ক্লজ তৈরি করে।
  • separator=",": এটি কুয়েরির মধ্যে আইটেমগুলির মধ্যে কমা (,) সেপারেটর হিসেবে ব্যবহার করে।

5. Using @SelectProvider, @InsertProvider, @UpdateProvider, and @DeleteProvider for Dynamic SQL in Annotations (MyBatis)

MyBatis-এ আপনি annotations ব্যবহার করে dynamic SQL তৈরি করতে পারেন, যেখানে SQL কুয়েরি তৈরি করার জন্য প্রোভাইডার ব্যবহার করা হয়।

Example: Using Annotations for Dynamic SQL
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;

public interface StudentMapper {

    @SelectProvider(type = StudentSqlProvider.class, method = "selectStudent")
    Student selectStudent(int id);

    @UpdateProvider(type = StudentSqlProvider.class, method = "updateStudent")
    void updateStudent(Student student);
}
import org.apache.ibatis.jdbc.SQL;

public class StudentSqlProvider {

    public String selectStudent(final int id) {
        return new SQL() {{
            SELECT("*");
            FROM("student");
            WHERE("id = #{id}");
        }}.toString();
    }

    public String updateStudent(final Student student) {
        return new SQL() {{
            UPDATE("student");
            SET("name = #{name}, course = #{course}");
            WHERE("id = #{id}");
        }}.toString();
    }
}

Explanation:

  • @SelectProvider: এটি StudentSqlProvider ক্লাসের selectStudent মেথড থেকে SQL কুয়েরি নিয়ে আসে।
  • @UpdateProvider: এটি StudentSqlProvider ক্লাসের updateStudent মেথড থেকে SQL আপডেট কুয়েরি তৈরি করে।

6. Combining Dynamic SQL for Complex Queries

এখন আমরা একটি উদাহরণ দেখব যেখানে ডাইনামিক SQL ব্যবহার করে একটি complex SQL query তৈরি করা হবে, যাতে SELECT, WHERE, JOIN এবং ORDER BY কন্ডিশনগুলির মতো অংশ যুক্ত করা হয়।

<select id="selectStudents" resultType="com.example.Student">
    SELECT s.id, s.name, s.course
    FROM student s
    <join>
        <if test="enrolled != null">
            JOIN enrollment e ON e.student_id = s.id
        </if>
    </join>
    <where>
        <if test="name != null">
            AND s.name = #{name}
        </if>
        <if test="course != null">
            AND s.course = #{course}
        </if>
    </where>
    <orderBy>
        <if test="order != null">
            ORDER BY s.name
        </if>
    </orderBy>
</select>

Explanation:

  • <join>: এটি ডাইনামিকালি JOIN যোগ করে যদি enrolled পরামিতি থাকে।
  • <where>: কন্ডিশন যোগ করার জন্য WHERE ক্লজ ব্যবহার করা হয়।
  • <orderBy>: ORDER BY ক্লজ যোগ করা হয় যদি order পরামিতি দেওয়া থাকে।

Dynamic SQL iBATIS/MyBatis-এ একটি গুরুত্বপূর্ণ বৈশিষ্ট্য যা SQL কোয়েরি তৈরির জন্য অত্যন্ত কার্যকরী। <if>, <choose>, <foreach>, <trim>, এবং <where> ট্যাগগুলির মাধ্যমে আপনি SQL কুয়েরির অংশগুলো ডাইনামিকভাবে যোগ করতে পারেন এবং জটিল কুয়েরি তৈরি করতে সক্ষম হন। এই পদ্ধতিগুলি বিশেষভাবে উপকারী যখন conditional বা parameterized SQL queries তৈরি করতে হয়। MyBatis (iBATIS) ব্যবহার করে আপনি SQL কোয়েরিগুলিকে আরও দক্ষভাবে এবং কাস্টমাইজযোগ্যভাবে তৈরি করতে পারবেন।

Content added By
Promotion

Are you sure to start over?

Loading...