IT'S YU
[MyBatis] 설정 파일 - SQL Mapper 작성 방법 본문
MyBatis 설정 파일 - SQL Mapper 작성 방법
MyBatis 사용 목적 중 하나는 DAO로부터 SQL문을 분리하는 것이다.
분리된 SQL문은 SQL mapper 파일에 작성하며 DAO에서는 SqlSession 객체가 SQL mapper 파일을 참조하게 된다.
다음은 MyBatis SQL mapper 파일의 예이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<mapper namespace="com.atoz_develop.spms.dao.ProjectDao">
<resultMap type="project" id="projectResultMap">
<id column="PNO" property="no" />
<result column="PNAME" property="title" />
<result column="CONTENT" property="content" />
<result column="STA_DATE" property="startDate" javaType="java.sql.Date" />
<result column="END_DATE" property="endDate" javaType="java.sql.Date" />
<result column="STATE" property="state" />
<result column="CRE_DATE" property="createdDate" javaType="java.sql.Date" />
<result column="TAGS" property="tags" />
</resultMap>
<select id="selectList" resultMap="projectResultMap">
select PNO, PNAME, STA_DATE, END_DATE, STATE
from PROJECTS
order by PNO desc
</select>
<insert id="insert" parameterType="project">
insert into PROJECTS(PNAME, CONTENT, STA_DATE, END_DATE, STATE, CRE_DATE, TAGS)
values (#{title}, #{content}, #{startDate}, #{endDate}, 0, NOW(), #{tags})
</insert>
<select id="selectOne" parameterType="int" resultMap="projectResultMap">
select PNO, PNAME, CONTENT, STA_DATE, END_DATE, STATE, CRE_DATE, TAGS
from PROJECTS
where PNO = #{no}
</select>
<update id="update" parameterType="project">
update PROJECTS set
PNAME = #{title},
CONTENT = #{content},
STA_DATE = #{startDate},
END_DATE = #{endDate},
STATE = #{state},
TAGS = #{tags}
where PNO = #{no}
</update>
<delete id="delete" parameterType="int">
delete from PROJECTS
where PNO = #{no}
</delete>
</mapper>
|
cs |
1. XML과 DTD 선언
SQL mapper 파일은 XML이기 때문에 가장 먼저 XML 선언이 온다.
다음으로 태그 규칙을 정의한 DTD 선언이 온다.
2. Root Element - <mapper>
SQL mapper 파일은 루트 엘리먼트 <mapper>를 작성하는 것으로 시작한다.
<mapper>의 namespace 속성은 자바의 패키지처럼 여러개의 SQL문을 묶는 용도로 사용한다.
mapper 파일에 작성하는 모든 SQL문은 <mapper> 하위에 놓여야 한다.
3. <select>, <insert>, <update>, <delete>
SQL 명령어에 따라 SELECT문은 <select>, INSERT문은 <insert>, UPDATE문은 <update>, DELETE문은 <delete>에 작성한다.
속성 | 설명 |
id | 각 SQL문을 구분 |
resultType | SELECT문 실행 결과를 담을 객체 패키지 이름을 포함한 클래스 이름 또는 객체 alias 지정 |
resultMap | SELECT문 실행 결과를 담을 객체를 resultMap으로 지정 <resultMap>을 따로 선언해줘야 한다. resultType과 resultMap 중 하나를 택해서 설정한다. |
parameterType |
이 속성에 지정한 객체의 프로퍼티값이 SQL문의 입력 파라미터에 지정된다. |
resultType 속성
SELECT문을 실행하면 결과가 생성되는데 이 결과를 담을 객체를 resultType 속성에 지정한다.
resultType에는 패키지 이름을 포함한 전체 클래스명을 지정하던지 객체의 alias를 지정할 수 있다.
alias는 MyBatis 설정파일에 설정한다.
다음 두 설정은 동일한 의미를 가진다.
패키지 이름을 포함한 전체 클래스명 지정
1
2
3
4
5
|
<select id="selectList" resultMap="com.atoz_develop.spms.vo.Project">
select PNO, PNAME, STA_DATE, END_DATE, STATE
from PROJECTS
order by PNO desc
</select>
|
cs |
객체의 alias 지정
1
2
3
4
5
6
7
8
9
10
11
|
<!-- MyBatis 설정파일 -->
<typeAliases>
<typeAliase type="com.atoz_develop.spms.vo.Project" alias="project"/>
</typeAliases>
<!-- SQL Mapper 파일 -->
<select id="selectList" resultMap="project">
select PNO, PNAME, STA_DATE, END_DATE, STATE
from PROJECTS
order by PNO desc
</select>
|
cs |
MyBatis는 SELECT 결과를 저장하기 위해 resultType에 지정된 클래스의 인스턴스를 생성한다.
그리고 각 컬럼에 대응하는 setter를 호출한다.
컬럼명이 PNO, PNAME, STA_DATE, END_DATE, STATE이면 각각 setPno(), setPname(), setSta_date(), setEnd_date(), setState()를 호출한다.
컬럼에 맞는 setter가 없으면 그 컬럼의 값은 객체에 저장되지 않는다.
컬럼명과 setter 이름이 달라서 값이 저장되지 않는 문제를 해결하려면 SELECT문의 각 컬럼에 as로 alias를 붙이면 된다.
예를 들어 컬럼명이 PNO인데 setter가 setNo()라면 SELECT PNO as NO... 와 같이 작성한다.
resultMap 속성과 <resultMap> 엘리먼트
resultType 속성을 사용하면 setter와 매칭되지 않는 경우 각 컬럼마다 alias를 붙여야하는 번거로움이 있다.
resultMap 속성을 사용하면 이 문제를 해결할 수 있다.
다음과 같이 <resultMap>에 컬럼과 매칭되는 setter 메소드를 지정한다.
각 엘리먼트와 속성의 의미는 다음과 같다.
- <resultMap>.type: SELECT 결과를 저장할 클래스 이름 또는 MyBatis 설정파일에 설정된 alias
- <resultMap>.id: resultMap의 id
- <id>: 객체 식별자로 사용되는 프로퍼티
- <id>.column: 컬럼명
- <id>.property: 객체 프로퍼티명(setter 메소드 이름에서 set을 빼고 첫 알파엣을 소문자로 만든 이름)
- <result>: 컬럼-setter 연결 정의
- <result>.column: 컬럼명
- <result>.property: 객체 프로퍼티명(setter 메소드 이름에서 set을 빼고 첫 알파엣을 소문자로 만든 이름)
- <result>.javaType: 컬럼 값을 특정 자바 객체로 변환할때 사용
정의한 <resultMap>은 <select>의 resultMap 속성에 <resultMap>의 id를 지정해서 사용할 수 있다.
<id> 엘리먼트와 MyBatis의 SELECT 결과 캐싱
특히 <id> 엘리먼트는 설정 방법은 <result> 엘리먼트와 동일하지만 특별한 의미를 가진다.
MyBatis는 <id>를 이용해서 한 번 생성된 객체를 버리지 않고 보관해 두었다가 재사용한다.
SELECT문을 실행하면 레코드 값을 저장하기 위해 결과 객체가 생성된다. 이 때 SELECT문을 실행할 때 마다 매번 결과 객체를 생성하는게 아니라 결과 객체들을 객체 pool에 caching(캐싱)해두고 다음 SELECT를 실행할 때 재사용한다. 이렇게 객체 pool에 저장된 객체를 구분하는 값으로 <id>에서 지정한 프로퍼티를 사용한다.
parameterType 속성과 SQL문의 입력 파라미터 처리
JDBC에서 PreparedStatement 객체를 사용해서 SQL문을 실행할때 '?'로 파라미터를 표시하고 setXXX() 메소드를 호출해서 파라미터에 값을 지정한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
pstmt = connection.prepareStatement(
"INSERT INTO STUDENT(STUDENT_NO, DEPARTMENT, STUDENT_NAME, GRADE, GENDER, AGE, PHONE_NUMBER, ADDRESS, PASSWORD)" +
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
);
pstmt.setString(1, student.getStudentNo());
pstmt.setString(2, student.getDepartment());
pstmt.setString(3, student.getStudentName());
pstmt.setInt(4, student.getGrade());
pstmt.setString(5, student.getGender());
pstmt.setInt(6, student.getAge());
pstmt.setString(7, student.getPhoneNumber());
pstmt.setString(8, student.getAddress());
pstmt.setString(9, student.getPassword());
|
cs |
MyBatis에서는 입력 파라미터를 '#{프로퍼티}'로 표시한다.
#{프로퍼티}에 지정되는 값은 <select>, <insert>, <update>, <delete>의 parameterType에 지정된 객체의 프로퍼티값이다.
즉 #{title}에는 객체의 getTitle() 반환값이 지정된다.
입력 파라미터에 값 공급
DAO에서 SqlSession의 메소드를 호출할때 VO를 전달해서 입력 파라미터에 값을 공급한다.
위와 같이 insert()를 호출하면 SQL mapper 파일에서 'com.atoz_develop.spms.dao.ProjectDao.insert' id를 가진 SQL문을 찾아 실행한다.
project는 해당 SQL문을 실행할 때 입력 파라미터에 값을 공급할 객체이다.
값을 공급하는 객체가 기본 타입인 경우
위와 같이 기본 타입을 전달하면 auto-boxing으로 wrapper 객체를 생성해서 전달된다.
wrapper 타입은 getter가 존재하지 않으므로 프로퍼티명도 존재하지 않는다.
따라서 SQL mapper에서 어떤 이름을 사용해도 무방하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<!-- 이렇게 해도 되고 -->
<select id="selectOne" parameterType="int" resultMap="projectResultMap">
select PNO, PNAME, CONTENT, STA_DATE, END_DATE, STATE, CRE_DATE, TAGS
from PROJECTS
where PNO = #{no}
</select>
<!-- 이렇게 해도 된다 -->
<select id="selectOne" parameterType="int" resultMap="projectResultMap">
select PNO, PNAME, CONTENT, STA_DATE, END_DATE, STATE, CRE_DATE, TAGS
from PROJECTS
where PNO = #{value}
</select>
|
cs |
4. MyBatis 설정 파일에 등록
작성한 SQL mapper 파일은 MyBatis가 인식할 수 있도록 파일 경로를 MyBatis 설정 파일에 등록해주어야 한다.
MyBatis 설정 파일의 <mappers> 태그 하위에 위와 같이 작성해주면 된다.
MyBatis 설정 파일 작성 가이드 문서는 라이브러리 압축 파일 내에 mybatis-x.x.x.pdf 와 같이 PDF 파일로도 제공된다.
해당 문서를 함께 참조하면 더 자세한 정보를 얻을 수 있다.
'DB > MyBatis' 카테고리의 다른 글
[MyBatis] Mapper XML 파일 설정 (0) | 2022.02.22 |
---|---|
[MyBatis] sqlMapper - 실제 쿼리문(CRUD)를 작성할 xml문서의 문법 (1) | 2022.02.10 |
[MyBatis] XML 기초문법 (0) | 2022.02.10 |