MyBatis ์ค์ ํ์ผ - SQL Mapper ์์ฑ ๋ฐฉ๋ฒ
- ๊ด๋ จ ๊ธ
- [JAVA/WEB] ์น ํ๋ก์ ํธ์ MyBatis ์ธํ ๋ฐ ์ ์ฉํ๊ธฐ
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"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<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 ํ์ผ๋ก๋ ์ ๊ณต๋๋ค.
ํด๋น ๋ฌธ์๋ฅผ ํจ๊ป ์ฐธ์กฐํ๋ฉด ๋ ์์ธํ ์ ๋ณด๋ฅผ ์ป์ ์ ์๋ค.
- ๊ด๋ จ ๊ธ
- [JAVA/WEB] ์น ํ๋ก์ ํธ์ MyBatis ์ธํ ๋ฐ ์ ์ฉํ๊ธฐ
References
์ดํ๊ฐ์ ์๋ฐ ์น ๊ฐ๋ฐ ์ํฌ๋ถ(ํ๋ฆฌ๋ , 2016, ์์ง์)