<association>는 MyBatis에서 일대일 또는 일대다 관계를 처리하는 매핑 요소로, 쿼리 결과의 중첩 데이터를 Java 객체의 속성에 매핑하는 데 사용됩니다. 복잡한 데이터베이스 쿼리 결과를 중첩 객체로 매핑해야 할 때 특히 유용합니다.
1. 기능과 용도
- 일대일 관계: 객체가 하나의 연결 객체를 포함할 때(예:
Employee는 하나의Department에만 속함)<association>를 사용하여 일대일 관계를 매핑합니다. - 일대다 관계: 객체가 여러 연결 객체를 포함할 때(예:
Department에 여러Employee가 소속됨)<association>를 사용하여 일대다 관계를 매핑합니다. - 다중 중첩 매핑: 여러 연결 객체가 포함된 쿼리 시
<association>가 쿼리 결과를 Java 객체에 자동으로 채워주어 복잡한 매핑 코드 작성을 방지합니다.
2. <association> 기본 사용법
property: Java 객체에서 연결 객체를 저장할 속성 이름resultMap: 쿼리 결과의 필드를 해당 연결 객체에 매핑하는 방법을 지정하는resultMapcolumnPrefix: 데이터베이스 열에 접두사를 추가하여 열 이름 충돌을 방지
3. 예시 설명: 일대일 및 일대다 매핑
두 개의 엔티티인 Employee와 Department, 그리고 Company와 여러 Department를 가정하여 <association>를 사용한 일대일 및 일대다 매핑을 각각 설명합니다.
4. 예시 1: 일대일 관계 매핑
데이터 테이블 구조
데이터베이스에 employees와 departments 두 개의 테이블이 있다고 가정합니다.
- employees 테이블: 직원 정보 저장
| emp_id | emp_name | dept_id |
|---|---|---|
| 101 | 김철수 | 1 |
| 102 | 이영희 | 2 |
- departments 테이블: 부서 정보 저장
| dept_id | dept_name | location |
|---|---|---|
| 1 | 개발부 | 서울 |
| 2 | 기획부 | 부산 |
1.1 Java 클래스 정의
// Employee.java
public class Employee {
private int id;
private String name;
private Department department; // 일대일 연결
// getters and setters
}
// Department.java
public class Department {
private int id;
private String name;
private String location;
// getters and setters
}
1.2 resultMap 생성
<!-- Department resultMap -->
<resultMap id="departmentResultMap" type="com.example.Department">
<result property="id" column="dept_id"/>
<result property="name" column="dept_name"/>
<result property="location" column="location"/>
</resultMap>
<!-- Employee resultMap -->
<resultMap id="employeeResultMap" type="com.example.Employee">
<id property="id" column="emp_id"/>
<result property="name" column="emp_name"/>
<association property="department" resultMap="departmentResultMap"/>
</resultMap>
1.3 SQL 쿼리
<select id="findEmployeeWithDepartment" resultMap="employeeResultMap">
SELECT e.emp_id, e.emp_name, d.dept_id, d.dept_name, d.location
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.dept_id
WHERE e.emp_id = #{empId}
</select>
1.4 결과 매핑
emp_id=101을 쿼리하면 다음과 같은 데이터가 반환됩니다:
| emp_id | emp_name | dept_id | dept_name | location |
|---|---|---|---|---|
| 101 | 김철수 | 1 | 개발부 | 서울 |
결과는 다음과 같이 매핑됩니다:
Employee employee = new Employee();
employee.setId(101);
employee.setName("김철수");
Department department = new Department();
department.setId(1);
department.setName("개발부");
department.setLocation("서울");
employee.setDepartment(department);
5. 예시 2: 일대다 관계 매핑
데이터 테이블 구조
두 개의 테이블: companies와 departments가 있다고 가정합니다.
- companies 테이블: 회사 정보 저장
| comp_id | comp_name |
|---|---|
| 1001 | 삼성전자 |
| 1002 | LG전자 |
- departments 테이블: 부서 정보 저장
| dept_id | dept_name | comp_id |
|---|---|---|
| 1 | 연구개발 | 1001 |
| 2 | 마케팅 | 1001 |
| 3 | 인사 | 1002 |
2.1 Java 클래스 정의
// Department.java
public class Department {
private int deptId;
private String deptName;
// getters and setters
}
// Company.java
public class Company {
private int compId;
private String compName;
private List<Department> departments; // 일대다 연결
// getters and setters
}
2.2 resultMap 생성
<!-- Department resultMap -->
<resultMap id="departmentResultMap" type="com.example.Department">
<result property="deptId" column="dept_id"/>
<result property="deptName" column="dept_name"/>
</resultMap>
<!-- Company resultMap -->
<resultMap id="companyResultMap" type="com.example.Company">
<result property="compId" column="comp_id"/>
<result property="compName" column="comp_name"/>
<association property="departments" resultMap="departmentResultMap"/>
</resultMap>
2.3 SQL 쿼리
<select id="findCompanyWithDepartments" resultMap="companyResultMap">
SELECT c.comp_id, c.comp_name, d.dept_id, d.dept_name
FROM companies c
LEFT JOIN departments d ON c.comp_id = d.comp_id
</select>
2.4 결과 매핑
쿼리 결과:
| comp_id | comp_name | dept_id | dept_name |
|---|---|---|---|
| 1001 | 삼성전자 | 1 | 연구개발 |
| 1001 | 삼성전자 | 2 | 마케팅 |
| 1002 | LG전자 | 3 | 인사 |
다음과 같이 매핑됩니다:
List<Company> companies = new ArrayList<>();
// company 1
Company company1 = new Company();
company1.setCompId(1001);
company1.setCompName("삼성전자");
Department dept1 = new Department();
dept1.setDeptId(1);
dept1.setDeptName("연구개발");
Department dept2 = new Department();
dept2.setDeptId(2);
dept2.setDeptName("마케팅");
company1.setDepartments(Arrays.asList(dept1, dept2));
// company 2
Company company2 = new Company();
company2.setCompId(1002);
company2.setCompName("LG전자");
Department dept3 = new Department();
dept3.setDeptId(3);
dept3.setDeptName("인사");
company2.setDepartments(Arrays.asList(dept3));
// 리스트에 추가
companies.add(company1);
companies.add(company2);
6. 요약
<association>용도:
- 일대일 관계:
<association>를 사용하여 한 객체의 다른 객체 속성으로 매핑 - 일대다 관계:
<association>를 사용하여 여러 객체를 컬렉션 속성으로 매핑 - 중첩 결과 매핑: 다중 중첩 쿼리 지원, 복잡한 쿼리 결과를 다중 중첩 Java 객체로 매핑
- 주요 속성:
property: 채울 Java 클래스 속성 지정resultMap: 해당 연결 객체 매핑을 처리하는resultMap가리킴columnPrefix: 데이터베이스 열 이름에 접두사 추가하여 열 이름 충돌 방지
- 쿼리 결과 매핑:
<association>는 쿼리 반환 결과에 따라 중첩 객체를 Java 객체에 자동으로 채워주어 복잡한 쿼리 결과 처리를 단순화합니다.
적절히 <association>를 사용하면 일대일 및 일대다 객체 관계를 쉽게 처리할 수 있어 복잡한 결과 매핑 코드 작성을 피하고 코드의 유지보수성과 가독성을 향상시킬 수 있습니다.