MyBatis์ Result Maps
Result Maps
๐resultMap์ด๋?
resultMap์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋ ์์ฑ๋๋ JDBC์ฝ๋๋ฅผ ๋๋ถ๋ถ ์ค์ฌ์ฃผ๋ ์ญํ ์ ๋ด๋นํ๋ค.
JOIN ๋งคํ๊ณผ ๊ฐ์ ๋ณต์กํ ์ฝ๋๋ ๋ง์ ์์ ์ฝ๋๊ฐ ํ์ํ๋ค.
ํ์ง๋ง resultMap์ ๊ฐ๋จํ ๊ตฌ๋ฌธ์์๋ ๋งคํ์ด ํ์ํ์ง ์๊ณ ๋ณต์กํ ๊ตฌ๋ฌธ์์ ๊ด๊ณ๋ฅผ ์์ ํ๊ธฐ ์ํด ํ์ํ๋ค.
๐DB์ ์นผ๋ผ๋ช ๊ณผ ํ๋กํผํฐ๋ช ์ด ๊ฐ์ ๊ฒฝ์ฐ
- resultMap์ ์ฐ์ง์์ ์์
<select id="selectUsers" resultType="map">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
- JavaBean ์์
- property : id, username, hashedPassword
package com.someapp.model;
public class User {
private int id;
private String username;
private String hashedPassword;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getHashedPassword() {
return hashedPassword;
}
public void setHashedPassword(String hashedPassword) {
this.hashedPassword = hashedPassword;
}
}
- ์์ ์ฟผ๋ฆฌ(select)์ ์นผ๋ผ๋ช ์ด ์ ํํ ์ผ์นํ๋ค. โ ๋ฐ๋ผ์ ์๋ฐ๋น์ HashMap๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋งค์ฐ ์ฝ๊ฒ ResultMap์ ๋งคํ๋ ์ ์๋ค.
<select id="selectUsers" resultType="com.someapp.model.User">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
๐DB์ ์นผ๋ผ๋ช ๊ณผ ํ๋กํผํฐ๋ช ์ด ๊ฐ์ง ์์ ๊ฒฝ์ฐ
- ์นผ๋ผ๋ช ๊ณผ ํ๋กํผํฐ๋ช ์ด ๋ค๋ฅด๋ค๋ฉด SQL๊ตฌ๋ฌธ์ ๋ณ์นญ์ ์ง์ ํ๋ค.
<select id="selectUsers" resultType="User">
select
user_id as "id",
user_name as "userName",
hashed_password as "hashedPassword"
from some_table
where id = #{id}
</select>
- resultMap์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
-
- id :
userResultMap
- type :
User.java
- id :
resultMap="userResultMap"
์ผ๋ก ์ฐธ์กฐํ๋ค.
<select id="selectUsers" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>
๐๋ณต์กํ ๊ฒฐ๊ณผ๋งคํ
<!-- ๋งค์ฐ ๋ณต์กํ ๊ตฌ๋ฌธ -->
<select id="selectBlogDetails" resultMap="detailedBlogResultMap">
select
B.id as blog_id,
B.title as blog_title,
B.author_id as blog_author_id,
A.id as author_id,
A.username as author_username,
A.password as author_password,
A.email as author_email,
A.bio as author_bio,
A.favourite_section as author_favourite_section,
P.id as post_id,
P.blog_id as post_blog_id,
P.author_id as post_author_id,
P.created_on as post_created_on,
P.section as post_section,
P.subject as post_subject,
P.draft as draft,
P.body as post_body,
C.id as comment_id,
C.post_id as comment_post_id,
C.name as comment_name,
C.comment as comment_text,
T.id as tag_id,
T.name as tag_name
from Blog B
left outer join Author A on B.author_id = A.id
left outer join Post P on B.id = P.blog_id
left outer join Comment C on P.id = C.post_id
left outer join Post_Tag PT on PT.post_id = P.id
left outer join Tag T on PT.tag_id = T.id
where B.id = #{id}
</select>
- ResultMap ์์
<!-- Very Complex Result Map -->
<resultMap id="detailedBlogResultMap" type="Blog">
<constructor>
<idArg column="blog_id" javaType="int"/>
</constructor>
<result property="title" column="blog_title"/>
<association property="author" javaType="Author">
<id property="id" column="author_id"/>
<result property="username" column="author_username"/>
<result property="password" column="author_password"/>
<result property="email" column="author_email"/>
<result property="bio" column="author_bio"/>
<result property="favouriteSection" column="author_favourite_section"/>
</association>
<collection property="posts" ofType="Post">
<id property="id" column="post_id"/>
<result property="subject" column="post_subject"/>
<association property="author" javaType="Author"/>
<collection property="comments" ofType="Comment">
<id property="id" column="comment_id"/>
</collection>
<collection property="tags" ofType="Tag" >
<id property="id" column="tag_id"/>
</collection>
<discriminator javaType="int" column="draft">
<case value="1" resultType="DraftPost"/>
</discriminator>
</collection>
</resultMap>
- resultMap
constructor
- ์ธ์คํด์คํ๋๋ ํด๋์ค์ ์์ฑ์์ ๊ฒฐ๊ณผ๋ฅผ ์ฝ์ ํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.idArg
- ID์ธ์. ID์ ๊ฐ์ ๊ฒฐ๊ณผ๋ ์ ๋ฐ์ ์ผ๋ก ์ฑ๋ฅ์ ํฅ์์ํจ๋ค.arg
- ์์ฑ์์ ์ฝ์ ๋๋ ์ผ๋ฐ์ ์ธ ๊ฒฐ๊ณผ
result
- ํ๋๋ ์๋ฐ๋น ํ๋กํผํฐ์ ์ฝ์ ๋๋ ์ผ๋ฐ์ ์ธ ๊ฒฐ๊ณผassociation
- ๋ณต์กํฉ ํ์ ์ ์ฐ๊ด๊ด๊ณ. ๋ง์ ๊ฒฐ๊ณผ๋ ํ์ ์ผ๋ก ๋ํ๋๋ค.- ์ค์ฒฉ๋ ๊ฒฐ๊ณผ ๋งคํ - resultMap ์ค์ค๋ก์ ์ฐ๊ด๊ด๊ณ
collection
- ๋ณต์กํ ํ์ ์ ์ปฌ๋ ์ - ์ค์ฒฉ๋ ๊ฒฐ๊ณผ ๋งคํ - resultMap ์ค์ค๋ก์ ์ฐ๊ด๊ด๊ณ
discriminator
- ์ฌ์ฉํ resultMap์ ํ๋จํ๊ธฐ ์ํ ๊ฒฐ๊ณผ๊ฐ์ ์ฌ์ฉ- case - ๋ช ๊ฐ์ง ๊ฐ์ ๊ธฐ์ดํ ๊ฒฐ๊ณผ ๋งคํ
- ์ค์ฒฉํ ๊ฒฐ๊ณผ ๋งคํ - ์ด ๊ฒฝ์ฐ ๋ํ ๊ฒฐ๊ณผ๋งคํ ์์ฒด์ด๊ณ ์ด๋ฌํ ๋์ผํ ์๋ฆฌ๋จผํธ๋ฅผ ๋ง์ด ํฌํจํ๊ฑฐ๋ ์ธ๋ถresultMap์ ์ฐธ์กฐํ ์ ์๋ค.
์์ฑ ์ค๋ช id ๊ฒฐ๊ณผ๋งคํ์ ์ฐธ์กฐํ๊ธฐ ์ํด ์ฌ์ฉํ ์ ์๋ ๊ฐ์ผ๋ก ๋ค์์คํ์ด์ค์์ ์ ์ผํ ์๋ณ์ type ํจํค์ง๋ฅผ ํฌํจํ ์๋ฐ ํด๋์ค๋ช ์ด๋ ํ์ ๋ณ์นญ autoMapping ์ด ์ค์ ์ ์ฌ์ฉํ๋ฉด Mybatis๋ ๊ฒฐ๊ณผ๋งคํ์ ์๋๋งคํ์ผ๋ก ์ฒ๋ฆฌํ ์ง ๋ง์ง๋ฅผ ์ฒ๋ฆฌํ๋ค. ์ด ์์ฑ์ autoMappingBehavior๋ผ๋ ์ ์ญ์ค์ ์ ๋ฎ๋๋ค. ๋ํดํธ๋ unset์ด๋ค. - case - ๋ช ๊ฐ์ง ๊ฐ์ ๊ธฐ์ดํ ๊ฒฐ๊ณผ ๋งคํ
๐id, result
<id property="id" column="post_id"/>
<result property="subject" column="post_subject"/>
id์ result ๋ชจ๋ ํ ๊ฐ์ ์ปฌ๋ผ์ ํ๊ฐ์ ํ๋กํผํฐ๋ ๊ฐ๋จํ ๋ฐ์ดํฐ ํ์ ์ ํ๋์ ๋งคํํ๋ค.
- id์ result์ ์ฐจ์ด์
- id๊ฐ์ ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ๋น๊ตํ ๋ ์ฌ์ฉ๋๋ ๊ตฌ๋ถ์ ํ๋กํผํฐ๋ก ์ฒ๋ฆฌ๋๋ ์ ์ด ์ฐจ์ด์ ์ด๋ค. ์ด ๋ถ๋ถ์ ์ผ๋ฐ์ ์ผ๋ก ์ฑ๋ฅ์ ํฅ์์ํค์ง๋ง ํนํ ์บ์์ ๋ดํฌ๋(nested)๊ฒฐ๊ณผ ๋งคํ(์กฐ์ธ ๋งคํ)์ ๊ฒฝ์ฐ์ ๋ ๊ทธ๋ ๋ค.
- id์ result ์๋ฆฌ๋จผํธ ์์ฑ
์์ฑ | ์ค๋ช |
---|---|
property | ๊ฒฐ๊ณผ ์ปฌ๋ผ์ ๋งคํํ๊ธฐ ์ํ ํ๋๋ ํ๋กํผํฐ. ์๋ฐ๋น ํ๋กํผํฐ๊ฐ ํด๋น ์ด๋ฆ๊ณผ ์ผ์นํ๋ค๋ฉด ๊ทธ ํ๋กํผํฐ๊ฐ ์ฌ์ฉ๋ ๊ฒ์ด๋ค. ๋ฐ๋ฉด์ MyBatis๋ ํด๋น ์ด๋ฆ์ด ํ๋๋ฅผ ์ฐพ์ ๊ฒ์ด๋ค. ์ (.) ํ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋ณต์กํ ๋งคํ๋กํผํฐ ๊ฒ์์ ์ฌ์ฉํ ์ ์๋ค. |
์) โusernameโ๊ณผ ๊ฐ์ด ๊ฐ๋จํ๊ฒ ๋งคํ๋ ์ ์๊ฑฐ๋ โaddress.street.numberโ์ฒ๋ผ ๋ณต์กํ๊ฒ ๋งคํ๋ ์๋ ์๋ค. | ย |
column | ย |
javaType | ย |
jdbcType | ย |
typeHadnler | ย |
๐์ฐธ์กฐ
[MyBatis โ ๋ง์ด๋ฐํฐ์ค 3 | ๋งคํผ XML ํ์ผ](https://mybatis.org/mybatis-3/ko/sqlmap-xml.html#result-maps) |