1. ๊ฐ์
Spring Boot์ MyBatis๋ฅผ ์ฐ๋ํ ๋ ๊ฐ์ฅ ํํ ๋ง์ฃผ์น๋ ์ค์ ์ค๋ฅ ์ค ํ๋์ธ SqlSessionFactory ์์ฑ ์คํจ ์ด์๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ๋์ง,
๊ทธ๋ฆฌ๊ณ resultMap์ ์ธ์ ๊ผญ ์จ์ผ ํ๋์ง๋ ์ค์ ์ฌ๋ก ๊ธฐ๋ฐ์ผ๋ก ์ ๋ฆฌ
2. ๋ฌธ์ ๋ฐ์ : SqlSessionFactory ์ด๊ธฐํ ์คํจ
โ ์๋ฌ ๋ฉ์์ง
Failed to parse config resource: class path resource [sql-map-config.xml]
๐ ์์ธ ๋ถ์
• sql-map-config.xml ํ์ผ์ด ์ค์ ๋ก ์กด์ฌํ์ง ์๊ฑฐ๋,
• application.yml์์ ์๋ชป๋ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๊ฑฐ๋,
• ํน์ xml ๋ด๋ถ ๋ฌธ๋ฒ ์ค๋ฅ (์: ํ๊ทธ ๋๋ฝ, ์คํ ๋ฑ)
โ ํด๊ฒฐ ๋ฐฉ๋ฒ
• sql-map-config.xml์ด ์ ๋ง ์กด์ฌํ๋์ง resources/ ํ์ ํ์ธ
• ๋ฌธ๋ฒ ์ค๋ฅ๊ฐ ์๋์ง IDE์์ ํ์ธ (<configuration>, <mappers> ๋ฑ)
• ๊ตณ์ด ์ค์ ํ์ผ์ด ํ์ ์๋ค๋ฉด application.yml์์ ์ค์ ์ ๊ฑฐ
# ํ์ ์์ผ๋ฉด ์ด๊ฑฐ ์ ๊ฑฐ
mybatis:
config-location: classpath:sql-map-config.xml
โ ๋ณธ ํ๋ก์ ํธ ์ค๋ฅ ์์ธ
→ .xml ์์ ์ค์ ํ resource = ".xmlํ์ผ" ์ ์ด๋ฆ๊ณผ ์ค์ ์ ์ฅ๋ ํ์ผ์ ์ด๋ฆ์ด ๋ค๋ฆ (์ค์ ํ์ผ์ _๋ฅผ ์ฌ์ฉ .xml์์๋ - ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ผ์ ์ฐพ์ง ๋ชปํจ
3. resultType๋ง์ผ๋ก ์ถฉ๋ถํ๊ฐ? resultMap ๊ผญ ์จ์ผ ํ๋?
๐ค ์๋ฌธ
Spring Boot + MyBatis์์ resultType์ผ๋ก๋ ์๋ ๋งคํ์ด ๋๋๋ฐ ๊ตณ์ด resultMap์ ์จ์ผ ํ๋?
โ ๊ฒฐ๋ก
์ปฌ๋ผ๋ช ๊ณผ VO ํ๋๋ช ์ด ์ ํํ ์ผ์นํ๋ฉด resultType๋ง์ผ๋ก๋ ์ถฉ๋ถ
๋ค๋ง ์๋ ์กฐ๊ฑด์์ resultMap์ด ํ์
4. resultMap์ด ๊ผญ ํ์ํ ์ํฉ
โ ๊ณ์ฐ ์ปฌ๋ผ์ด ํฌํจ๋ ๊ฒฝ์ฐ (VO์๋ง ์๊ณ DB์๋ ์๋ ํ๋)
SELECT MEMBER_ID, (SELECT COUNT(*) FROM PURCHASE WHERE MEMBER_ID = M.MEMBER_ID) AS PURCHASE_COUNT
FROM MEMBER M
→ PURCHASE_COUNT๋ DB ํ ์ด๋ธ ์ปฌ๋ผ์ด ์๋๋ผ์, VO์๋ง ์๋ purchaseCount์ ์๋ ๋งคํ๋์ง ์์
โ ์กฐ์ธ ๊ฒฐ๊ณผ๊ฐ ํฌํจ๋ ๋
SELECT REVIEW.*, MEMBER.MEMBER_NAME, MEMBER.IS_WITHDRAW
FROM REVIEW JOIN MEMBER ON REVIEW.MEMBER_ID = MEMBER.MEMBER_ID
→ memberName, memberIsWithdraw ๋ฑ์ JOIN์ผ๋ก ๊ฐ์ ธ์จ ์ธ๋ถ ์ปฌ๋ผ์ด๋ผ resultMap ํ์
5. ์์ ์ฝ๋
โ resultType์ผ๋ก ์ถฉ๋ถํ ๊ฒฝ์ฐ
<select id="SELECTALL" resultType="member">
SELECT MEMBER_NUMBER, MEMBER_ID, MEMBER_NAME FROM MEMBER
</select>
โ resultMap์ ๋ฐ๋์ ์จ์ผ ํ๋ ๊ฒฝ์ฐ
<resultMap id="memberMap" type="MemberVO">
<id property="memberNumber" column="MEMBER_NUMBER"/>
<result property="memberId" column="MEMBER_ID"/>
<result property="purchaseCount" column="PURCHASE_COUNT"/>
</resultMap>
<select id="SELECTWITHCOUNT" resultMap="memberMap">
SELECT M.MEMBER_NUMBER, M.MEMBER_ID,
(SELECT COUNT(*) FROM PURCHASE WHERE MEMBER_NUMBER = M.MEMBER_NUMBER) AS PURCHASE_COUNT
FROM MEMBER M
</select>
โ ๋ณธ ํ๋ก์ ํธ ์ค๋ฅ ์์ธ
→ ์ค๋ผํด 11g ๋ฒ์ ์ ์ฌ์ฉํ๋ฉด์ ๋ฐ์ํ ๋ณ์นญ ๊ธธ์ด ์ ํ์ผ๋ก ์ธํด,
๊ธฐ์กด์ ์ฌ์ฉํ๋ ์ปฌ๋ผ๋ช PRODUCT_COMBO_DISCOUNTED_PRICE์์ COMBO_DISCOUNTED_PRICE๋ก ๋ณ๊ฒฝํจ
→ MyBatis๊ฐ ์๋ ๋งคํ์ ์คํจํ์ฌ ํ(row) ์์ฒด๋ฅผ null๋ก ๋ฐํํ์ฌ ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ null๋ก ๋ฐํ
→ List ์์ฒด๊ฐ null์ด์ด์ ๋ฐ์ดํฐ ์ถ์ถ ์คํจ
→ resultMap์ ์ฌ์ฉํ์ฌ property = "VO์์ ์ฌ์ฉํ๋ ๋ฉค๋ฒ๋ณ์" / column = "SQL๋ฌธ์์ ์ฌ์ฉํ๋ ์ปฌ๋ผ๋ช "์ 1:1๋ก ๋งคํํด์ฃผ์ด ๋ฐ์ดํฐ ์ถ์ถ
6. ๋ง๋ฌด๋ฆฌ
์ด๋ฒ ์ค์ ํธ๋ฌ๋ธ์ํ ์ ํตํด,
• MyBatis ์ค์ ์๋ฌ(SqlSessionFactory)์ ์์ธ๊ณผ ๋์ฒ๋ฒ
• resultType๊ณผ resultMap์ ์ ์ฉ ๊ธฐ์ค์ ๋ช ํํ ์ ๋ฆฌ ๊ฐ๋ฅ