
아래는 1편의 링크이다.
[Mybatis] 마이바티스 파헤쳐보기 - 1 -
1. MyBatis란? 관계형 데이터베이스 프로그래밍을 보다 쉽게 도와주는 프레임워크로 JDBC의 근간을 두고 있다. 마이바티스는 개발자가 지정한 SQL, 저장프로시저 그리고 몇가지 고급 매핑을 지원하
egu99.tistory.com
5. ResultMap
resultType이 아닌 resultMap을 언제 사용하는지 알아보자.
(1) 매핑할 VO클래스의 멤버변수명과 DB 테이블의 컬럼명이 다른 경우 매핑하는 역할
- 앞서 resultType을 썼을 때 VO클래스의 멤버변수와 DB컬럼명이 같을 경우는 알아서 매핑되었지만 다를 경우 매핑이 되지 않았다.
- 같게 해주면 되지만 개발하다보면 항상 같을 수 없고 컬럼마다 alias를 붙여주면 해결이 되나 번거롭다는 단점이 있다.
- 이 때 resultMap으로 쉽게 해결이 가능하다.
1) 앞선 간단 예제에서 vo클래스의 맴버변수 명을 살짝 수정해서 db 테이블의 컬럼명과 다르게 한다.

2) resultMap을 설정해준다.

resultType이 아닌 resultMap으로 바꾸고 이제 만들 resultMap의 id와 같게 넣어준다.
속성 | 설명 |
<resultMap>.type | 결과를 저장할 클래스 이름 (저기선 지정해둔 alias) |
<resultMap>.id | resultMap의 id |
<result> | VO의 프로퍼티 setter와 DB 테이블의 컬럼과의 연결을 정의 |
<result>.column | DB테이블의 컬럼명 |
<result>.property |
객체 프로퍼티명 (setter에서 set을 빼고 첫 알파벳을 소문자로) |
3) 결과

(2) Association
Association은 has one 관계를 다룰 때 사용한다.
한 명의 사원은 하나의 부서를 가지고 있으므로 employees 테이블의 사원번호를 통해 dept_emp 테이블에서 부서코드를 조회해보자.

(테이블 크기가 너무 커 limit을 썼다.)
간단하게 dept_no만 조회해보도록 하자.
1 ) dept_emp 테이블과 매핑할 DeptEmp라는 VO클래스를 만들어준다.
package VO;
public class DeptEmpVO {
private int e_no;
private String dept_no;
public int getE_no() {
return e_no;
}
public void setE_no(int e_no) {
this.e_no = e_no;
}
public String getDept_no() {
return dept_no;
}
public void setDept_no(String dept_no) {
this.dept_no = dept_no;
}
}
2 ) 기존 사원 정보 VO에 DeptEmpVO를 추가한다.
한 사원당 그 사원의 dept_emp 정보들이 함께 담기 위해서이다.
이제 그 정보들을 채워보자.
package VO;
public class EmployeeVO {
private int e_no;
private String f_name;
private String l_name;
private String emp_gender;
private DeptEmpVO dmp;
public DeptEmpVO getDmp() {
return dmp;
}
public void setDmp(DeptEmpVO dmp) {
this.dmp = dmp;
}
public int getE_no() {
return e_no;
}
public void setE_no(int emp_no) {
this.e_no = emp_no;
}
public String getF_name() {
return f_name;
}
public void setF_name(String f_name) {
this.f_name = f_name;
}
public String getL_name() {
return l_name;
}
public void setL_name(String l_name) {
this.l_name = l_name;
}
public String getEmp_gender() {
return emp_gender;
}
public void setEmp_gender(String emp_gender) {
this.emp_gender = emp_gender;
}
}
3) mapper에서 association 태그를 추가한다.
<?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="employee">
<select id="selectList" resultMap="empMap">
select * from employees where gender = 'M' order by emp_no limit 0,10;
</select>
<!-- 1.매핑할 VO클래스의 멤버변수명과 DB 테이블의 컬럼명이 다른 경우 -->
<!-- 2. association -->
<resultMap type="EmpVO" id="empMap">
<result property="e_no" column="emp_no"/>
<result property="f_name" column="first_name" />
<result property="l_name" column="last_name" />
<result property="emp_gender" column="gender" />
<association property="dmp" select="Dept_emp" javaType="VO.DeptEmp" column="emp_no"/>
</resultMap>
<select id="Dept_emp" resultType="VO.DeptEmp" parameterType="int">
select * from current_dept_emp where emp_no = #{eno};
</select>
</mapper>
속성 | 설명 |
<association>.property | 채워넣을 VO객체의 프로퍼티명(멤버변수의 이름) |
<association>.select | property를 채워넣기 위해 로드할 select 태그의 id값 |
<association>.javaType | property에 채워넣을 객체의 타입 |
<association>.column | 파라미터로 전달될 컬럼값. 여러 값을 보낼 때 중괄호와 ,를 써 구분한다. { value1=x , value2 =y} |
dmp에 사원-부서 정보를 채우기 위해 Dept_emp를 select 조회하는데 이 때 column값인 emp_no가 인자로 가게 된다.
emp_no는 int값이므로 parameterType을 int로 해준 후 #{eno}에 꽂아주게 되면 그 결과값이 DeptEmp 클래스에 매핑하여 dmp로 채워넣어진다.
4) 결과 확인

(2) Collection
association이 has one 관계였다면 collection은 has many 관계를 다룰 수 있다.
하나의 부서에는 여러 사원들이 존재한다. 부서별로 몇명의 사원이 있는지 확인해보자.
department 테이블에는 부서코드와 그에 따른 부서 이름이, dept_emp에는 사원이 어떤 부서에 있는지 알 수 있다.

1 ) department 테이블과 매핑할 Department라는 VO클래스를 만들어준다.
부서명과 부서 코드가 있는 department 테이블이다.
하나의 부서에는 여러 사원들이 존재한다는 것은 하나의 DepartmentVO 객체 안에 여럿의 EmployeeVO가 있는 것이므로 List<EmployeeVO>를 넣어준다.
package VO;
import java.util.List;
public class DepartmentVO {
private String dept_no;
private String dept_name;
private List<EmployeeVO> emplist;
public String getDept_no() {
return dept_no;
}
public void setDept_no(String dept_no) {
this.dept_no = dept_no;
}
public String getDept_name() {
return dept_name;
}
public void setDept_name(String dept_name) {
this.dept_name = dept_name;
}
public List<EmployeeVO> getEmplist() {
return emplist;
}
public void setEmplist(List<EmployeeVO> emplist) {
this.emplist = emplist;
}
}
2 ) 부서 정보를 조회할 DeptDAO를 만들어준다.
앞에서 만들었던 EmployeeDAO와 거의 흡사하다.
커넥터 클래스로부터 factory를 받아서 SqlSessionFactory를 만들고 openSession을 통해 SqlSession을 만들어 dept라는 네임스페이스를 가진 Mybatis mapper를 찾아 id가 selectList라는 select 태그로 조회한다.
그럼 dept.selectList를 만들어보자.
package dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import VO.DepartmentVO;
import VO.DeptEmpVO;
import connector.MybatisConnector;
public class DeptDao {
private static DeptDao dao;
SqlSessionFactory factory;
private DeptDao() {
factory = MybatisConnector.getInstance().getfactory();
}
public static DeptDao getInstance() {
if(dao == null)
dao = new DeptDao();
return dao;
}
public List<DepartmentVO> selectList(){
List<DepartmentVO> list = null;
SqlSession session = factory.openSession();
list = session.selectList("dept.selectList");
session.close();
return list;
}
}
3 ) department.xml을 만들어준다.
<collection> 태그를 쓰기 위해 이번에도 resultMap을 사용한다.
emplist 프로퍼티를 EmpVO객채들로 채우기 위해 selectListEmp라는 select 조회를 할 건데 dept_no를 column 지정을 통해 인자로 보낼 것이다.
selectListEmp에서는 dept_emp 테이블에서, 인자로 받은 dept_no와 같은 dept_no를 가진 사원들을 추려 emplist에 채워진다.
<?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="dept">
<select id="selectList" resultMap="deptMap">
select * from departments;
</select>
<resultMap type="DeptVO" id="deptMap">
<id property="dept_no" column="dept_no"/>
<collection property="emplist"
ofType="EmpVO"
select="selectListEmp"
column="{value=dept_no}">
</collection>
</resultMap>
<select id="selectListEmp" resultType="EmpVO" parameterType="String">
select * from dept_emp where dept_no = #{value};
</select>
</mapper>
속성 | 설명 |
<collection>.property | 채워넣을 VO객체의 프로퍼티명(멤버변수의 이름) |
<collection>.select | property를 채워넣기 위해 로드할 select 태그의 id값 |
<collection>.ofType | property에 채워넣을 객체의 타입 (collection은 javaType이 아닌 ofType이다.) |
<collection>.column | 파라미터로 전달될 컬럼값. 여러 값을 보낼 때 중괄호와 ,를 써 구분한다. {value1=x_column ,value2 =y_column} |
4 ) 제대로 동작하는지 서블릿에서 DAO의 selectList()를 호출하여 for문을 통해 확인해본다.
해당 부서의 사원을 담은 list의 size()를 이용하면 부서의 인원을 알 수 있다.
package servlet;
@WebServlet("/DepartmentListServlet")
public class DepartmentListServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<DepartmentVO> list = DeptDao.getInstance().selectList();
for(DepartmentVO emp : list) {
System.out.printf("부서코드 : %s | 부서 이름 : %s | 부서인원 %s",
emp.getDept_no(), emp.getDept_name(), emp.getEmplist().size());
System.out.println("");
}
}
}
5 ) 결과 확인

♣ 참고 및 인용
- www.youtube.com/watch?v=vE8Y751aCj8&list=PLa4r6B21Ny5kkldNKTJkKzVYDalsGLeV4&index=84&ab_channel=%EC%9D%B8%ED%81%AC%EB%A0%88%ED%8C%8C%EC%8A%A4%EC%9C%B5%ED%95%A9SW%EA%B5%90%EC%9C%A1%EC%84%BC%ED%84%B0
- mybatis.org/mybatis-3/ko/index.html
- atoz-develop.tistory.com/entry/MyBatis-%EC%84%A4%EC%A0%95-%ED%8C%8C%EC%9D%BC-SQL-Mapper-%EC%9E%91%EC%84%B1-%EB%B0%A9%EB%B2%95
'웹 개발 한걸음' 카테고리의 다른 글
[Javascript] 정규표현식 유효성 검사 + 비밀번호 재확인 구현해보기 (0) | 2021.05.06 |
---|---|
[Mybatis + Ajax] 로그인 구현 해보기 (0) | 2021.05.03 |
[Mybatis] 마이바티스 파헤쳐보기 - 1 - (0) | 2021.04.22 |
[Design Pattern] 싱글톤 패턴 배워보기 (0) | 2021.04.15 |
[JavaScript] AJAX / XMLHttpRequest 파헤쳐보기 (0) | 2021.04.14 |