반응형

오늘은 MyBatis를 사용하여 1:N 관계를 매핑하는 방법을 배워보겠습니다. 1:N 관계는 하나의 엔티티가 여러 개의 다른 엔티티와 연결될 때 사용됩니다. 예를 들어, 부서와 직원의 관계를 들 수 있습니다.


1. 1:N 관계의 예제

(1) 테이블 구조

다음은 departments 테이블과 employees 테이블입니다.

departments 테이블

Column Name Type Description

department_id INT 부서 ID
department_name VARCHAR 부서명

employees 테이블

Column Name Type Description

employee_id INT 사원 ID
first_name VARCHAR 이름
last_name VARCHAR
department_id INT 부서 ID (FK)

(2) 자바 객체 구조

package com.example.model;

import java.util.List;

public class Department {
    private int departmentId;
    private String departmentName;
    private List<Employee> employees; // 1:N 관계

    // Getters and Setters
}

public class Employee {
    private int employeeId;
    private String firstName;
    private String lastName;

    // Getters and Setters
}

2. ResultMap으로 1:N 관계 매핑

DepartmentMapper.xml 파일에서 ResultMap을 정의합니다.

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

    <resultMap id="DepartmentResultMap" type="com.example.model.Department">
        <id property="departmentId" column="department_id"/>
        <result property="departmentName" column="department_name"/>
        <collection property="employees" ofType="com.example.model.Employee">
            <id property="employeeId" column="employee_id"/>
            <result property="firstName" column="first_name"/>
            <result property="lastName" column="last_name"/>
        </collection>
    </resultMap>

    <select id="findAllDepartments" resultMap="DepartmentResultMap">
        SELECT 
            d.department_id, d.department_name,
            e.employee_id, e.first_name, e.last_name
        FROM departments d
        LEFT JOIN employees e ON d.department_id = e.department_id
    </select>

</mapper>

3. Mapper 인터페이스 작성

package com.example.mapper;

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

public interface DepartmentMapper {
    List<Department> findAllDepartments();
}

4. 테스트 코드 작성

findAllDepartments 메서드를 호출해 부서와 해당 부서의 직원 정보를 조회합니다.

package com.example;

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

import java.util.List;

@Component
public class TestRunner implements CommandLineRunner {

    @Autowired
    private DepartmentMapper departmentMapper;

    @Override
    public void run(String... args) throws Exception {
        List<Department> departments = departmentMapper.findAllDepartments();

        if (!departments.isEmpty()) {
            System.out.println("부서 목록:");
            departments.forEach(department -> {
                System.out.println("부서 ID: " + department.getDepartmentId());
                System.out.println("부서명: " + department.getDepartmentName());
                if (department.getEmployees() != null && !department.getEmployees().isEmpty()) {
                    System.out.println("직원 목록:");
                    department.getEmployees().forEach(employee -> {
                        System.out.println("- " + employee.getFirstName() + " " + employee.getLastName());
                    });
                } else {
                    System.out.println("직원이 없습니다.");
                }
                System.out.println("----------------------------");
            });
        } else {
            System.out.println("부서 정보가 없습니다.");
        }
    }
}

5. 실행 결과

위 코드를 실행하면 다음과 같은 출력 결과를 얻을 수 있습니다.

부서 목록:
부서 ID: 1
부서명: HR
직원 목록:
- Alice Johnson
- Bob Smith
----------------------------
부서 ID: 2
부서명: IT
직원 목록:
- Charlie Brown
----------------------------

6. 오늘의 요약

  • ResultMap의 <collection> 태그를 사용하여 1:N 관계를 매핑할 수 있습니다.
  • 조인을 통해 하나의 SQL 쿼리로 관련 데이터를 가져와 효율적으로 매핑할 수 있습니다.
  • 실무에서는 N+1 문제를 방지하기 위해 쿼리 튜닝 및 캐시를 활용할 수 있습니다.
반응형

+ Recent posts