반응형

오늘은 MyBatis에서 동적 SQL을 작성하는 방법에 대해 알아보겠습니다. 동적 SQL은 조건에 따라 SQL 문을 유연하게 변경할 수 있도록 도와주는 기능으로, 다양한 상황에서 유용하게 사용됩니다.


1. 동적 SQL의 필요성

데이터를 조회하거나 업데이트할 때 조건에 따라 SQL의 일부를 변경해야 하는 경우가 있습니다. 예를 들어, 특정 필터 조건에 따라 검색하거나, 파라미터에 따라 다르게 쿼리를 실행하는 경우입니다.


2. 동적 SQL의 기본 요소

MyBatis에서 동적 SQL을 작성할 때 사용하는 주요 태그는 다음과 같습니다.

  1. <if>: 조건문을 작성할 때 사용합니다.
  2. <choose>, <when>, <otherwise>: 여러 조건 중 하나를 선택합니다.
  3. <where>: 조건문 앞뒤로 적절히 WHERE 키워드를 추가합니다.
  4. <set>: UPDATE 쿼리에서 필드를 유동적으로 설정할 때 사용합니다.
  5. <foreach>: 반복문을 구현합니다.

3. 실습: 동적 검색 쿼리 작성

(1) 데이터베이스 테이블

employees 테이블을 기준으로 검색 조건에 따라 데이터를 필터링하는 기능을 구현합니다.

Column Name Description

employee_id 사원 ID
first_name 이름
last_name
department_id 부서 ID
hire_date 입사일

(2) SQL 쿼리

조건에 따라 다른 필터를 적용하는 동적 SQL입니다.

SELECT employee_id, first_name, last_name, department_id, hire_date
FROM employees
WHERE 1=1
<if test="firstName != null">
    AND first_name = #{firstName}
</if>
<if test="lastName != null">
    AND last_name = #{lastName}
</if>
<if test="departmentId != null">
    AND department_id = #{departmentId}
</if>
<if test="hireDate != null">
    AND hire_date = #{hireDate}
</if>

(3) 매퍼 파일 작성

<mapper namespace="com.example.mapper.EmployeeMapper">

    <select id="findEmployees" parameterType="map" resultType="map">
        SELECT employee_id, first_name, last_name, department_id, hire_date
        FROM employees
        WHERE 1=1
        <if test="firstName != null">
            AND first_name = #{firstName}
        </if>
        <if test="lastName != null">
            AND last_name = #{lastName}
        </if>
        <if test="departmentId != null">
            AND department_id = #{departmentId}
        </if>
        <if test="hireDate != null">
            AND hire_date = #{hireDate}
        </if>
    </select>

</mapper>

(4) Mapper 인터페이스 작성

package com.example.mapper;

import java.util.List;
import java.util.Map;

public interface EmployeeMapper {
    List<Map<String, Object>> findEmployees(Map<String, Object> params);
}

(5) 테스트 코드 작성

package com.example;

import com.example.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class TestRunner implements CommandLineRunner {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Override
    public void run(String... args) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("firstName", "John");
        params.put("departmentId", 101);

        List<Map<String, Object>> employees = employeeMapper.findEmployees(params);

        if (!employees.isEmpty()) {
            System.out.println("검색 결과:");
            employees.forEach(System.out::println);
        } else {
            System.out.println("조건에 맞는 결과가 없습니다.");
        }
    }
}

4. 동적 SQL의 동작 원리

  1. MyBatis는 <if> 태그의 조건을 평가하여 해당 부분을 포함하거나 제외합니다.
  2. 조건에 따라 쿼리를 동적으로 생성하며, 불필요한 조건은 쿼리에서 제외됩니다.
  3. Map 객체를 통해 다양한 검색 조건을 유연하게 전달할 수 있습니다.

5. 동적 SQL 확장: 여러 값 검색

IN 조건을 사용해 다수의 값을 검색하려면 <foreach> 태그를 활용합니다.

<if test="ids != null and ids.size() > 0">
    AND employee_id IN
    <foreach item="id" collection="ids" open="(" separator="," close=")">
        #{id}
    </foreach>
</if>

6. 오늘의 요약

  • MyBatis의 동적 SQL은 조건에 따라 SQL을 유연하게 변경할 수 있습니다.
  • <if>, <where>, <foreach>와 같은 태그를 사용해 복잡한 쿼리를 처리할 수 있습니다.
  • 검색 조건을 다양하게 받아 처리할 수 있으므로, 쿼리 작성의 자유도가 높아집니다.
반응형

+ Recent posts