ํ๋ฒ ์ฐ๋ฆฌ๊ฐ ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํฐ์ ์ ์ฅ์ ํ๋ค๊ณ ํด๋ณด์. ์ฐ๋ฆฌ๋ ๊ด๊ณํ DB, NoSQL, ํ์ผ ๋ฑ ๋ค์ํ ํ์์ผ๋ก ๊ฐ์ฒด๋ฅผ ์๊ตฌ์ ์ผ๋ก ๋ณด๊ดํ ์ ์๋ค. ํ์ง๋ง ๊ฐ์ฅ ํ์ค์ ์ด๊ณ ํ๋ช ํ ๋ฐฉ๋ฒ์ ๊ด๊ณํ DB์ด๋ค. No SQL๋ ๋ฐฉ๋ฒ์ด ๋ ์ ์์ง๋ง, ์์ง๊น์ง๋ ์ฃผ ๋ฉ์ธ์ผ๋ก ๋์ง๋ ์๋๋ค.
์ด์ ์ฐ๋ฆฌ๊ฐ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด๋ฅผ ์ ์ฅํด๋ณธ๋ค๊ณ ์๊ฐํด๋ณด์. ์ฐ์ ํ๋ฆ์ '1. ๊ฐ์ฒด๋ฅผ SQL๋ฌธ์ผ๋ก ๋ณํ -> 2. SQL์ RDB(๊ด๊ณํ DB)์ ์ ์ฅ' ์์ด๋ค. ์ด๋ฅผ ๊ฐ์ฒด๋ฅผ SQL๋ก ๋งคํํ๋ค๊ณ ๋งํ๋ค. ์ด๋ฌํ ๋งคํ ๊ณผ์ ์ ๋งค์ฐ ๋ฐฉ๋ณต์ ์ธ ๋ฐฉ๋ฒ์ด๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ๋ก์ง์ ์งค ์๊ฐ์ ๋งคํ์ ํ๋ฉฐ ์๊ฐ์ ๋ญ๋นํ๋ ๋ฌธ์ ์ ์ด ์๊ธด๋ค.
์ฒซ ๋ฒ์งธ ์ด์ : ๋ฌดํ ๋ฐ๋ณต๊ณผ ์ง๋ฃจํ ์ฝ๋ - Java ๊ฐ์ฒด์ sql ์๋ก ์ ํ ํ๊ธฐ, CRUD์ง๊ธฐ ๋ฑ ๋งค์ฐ ๋ง์ ์ฝ๋๋ฅผ ์ผ์ผํ ์์ฑํด์ผํ๋ค. ๋ํ ์์ ํ๊ธฐ๋ ๋งค์ฐ ๋ฒ๊ฑฐ๋กญ๋ค. ์ด๋ฌ๋ค ๋ณด๋ฉด ์ฝ๋๋ฅผ ๋นผ๋๋ ๊ฒฝ์ฐ์ฒ๋ผ ์ค์๊ฐ ์๊ธด๋ค.
๋ ๋ฒ์งธ ์ด์ : ํจ๋ฌ๋ค์์ ๋ถ์ผ์น. - ๊ฐ์ฒด๊ฐ ๋์จ ์ฌ์๊ณผ ๊ด๊ณํ ๋ฐ์ดํฐ ๋ฒ ์ด์ค๊ฐ ๋์จ ์ด์ (์ฌ์)์ด ๋ค๋ฅด๋ค. ๊ด๊ณํ DB๋ ์ ๊ตํํด์ ๋ณด๊ด์ ํ๋ ๊ฒ์ด ๋ชฉ์ ์ด์ง๋ง, ๊ฐ์ฒด๋ ํ๋์ ๋ฉ์๋๋ฅผ ์ ์บก์ํํด์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ฌธ์ ์ด๋ค. ํ์ง๋ง ์ด๋ฅผ ์๋ก ์ตํฉํ๋ ค๋ค๋ณด๋ ํจ๋ฌ๋ค์์ด ์ผ์นํ์ง ์์ ๋ฌธ์ ๊ฐ ์๊ธด๋ค. ์ด๋ค ๋ฌธ์ ๊ฐ ์์๊น?
๊ฐ์ฒด์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐจ์ด:
-
์์: ๊ฐ์ฒด์๋ ์์ ๊ด๊ณ๊ฐ ์๋ค. ํ์ง๋ง DB๋ ์์ ๊ด๊ณ์ ์ ์ฌํ ๊ฐ๋ ์ด ์์ง๋ง ์์ฐํ ๋ค๋ฅธ ๊ฐ๋ ์ด๊ธฐ ๋๋ฌธ์ ์๋ค๊ณ ๋ณด๋ ๊ฒ์ด ์ข๋ค.
์ด๋ ๊ฒ ์์ ๊ฐ๋ ๊ฐ์ ์ฐจ์ด์๋ ๋ถ๊ตฌํ๊ณ ๊ฐ์ฒด๋ฅผ DB์ ๋ฐ์ด ๋ฃ์ผ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ๋ ๊น? ๋๋ถ๋ถ ์ด๋ฅผ ํฌ๊ธฐํด๋ฒ๋ฆฐ๋ค. DB์์ ๊ฐ์ฒด์ ์์ ๊ด๊ณ์ ๊ฐ์ฅ ์ ์ฌํ ๋ฐฉ๋ฒ์ Table ์ํผํ์ ์๋ธํ์ ๊ด๊ณ์ด๋ค.
์๋ฅผ ํ๋ฒ ๋ค์ด๋ณด์. ์ฐ๋ฆฌ๋ ์ผํ๋ชฐ์ ์ด์ํ๋ ค๊ณ ํ๋ค. ๊ทธ๋ฌ๋ฉด Java์ ๊ฐ์ฒด๋ก ๊ตฌ์กฐ๋ฅผ ์งค ๋, ์ฐ๋ฆฌ๋ 'Item(์ํ)-id, ์ด๋ฆ, ๊ฐ๊ฒฉ'์ด๋ผ๋ ๋ถ๋ชจ ํด๋ ์ค๋ฅผ ๋ง๋ ํ, ์ด๋ฅผ ์์๋ฐ์ 'Album-์๊ณก๊ฐ', 'Movie-๊ฐ๋ , ๋ฐฐ'์ฐ,' Book-์๊ฐ, ISBN' ๋ฑ ์๋ธ ํด๋์ค๋ฅผ ๋ง๋ค ๊ฒ์ด๋ค. ์ด๋ฌํ ๊ฐ์ฒด ๊ตฌ์กฐ๋ฅผ DB๋ก ๋ชจ๋ธ๋งํด๋ณด์. ๋ชจ๋ธ๋ง์ ํ๋ฉด์ ๋ฐ์ํ๋ ๋ฌธ์ ๊ฐ ์๋ค.
- ๋ฐ๋ณต ๋ฌธ์ : Item ID๋ฅผ ๋ชจ๋ ํ ์ด๋ธ๋ง๋ค ์ฝ์ ํด์ผํ๋ ๋ฐ๋ณต ๋ฌธ์ ๊ฐ ์๊ธด๋ค.
- ์กฐํ ๋ฌธ์ : DB์์๋ ๊ฐ๊ฐ์ ํ ์ด๋ธ์ ๋ฐ๋ฅธ JOIN SQL์ ์์ฑํด์ผํ๊ณ , ๊ฐ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ผํ๋ค. ํ์ง๋ง ์๋ฐ๋ get๋ง ์ฌ์ฉํด์ ์์ฝ๊ฒ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ์ ์๋ค.
โ => ์ฆ RDB์ ๋ฃ๋ ์๊ฐ SQL๋งคํ ์์ ์ด ๋๋ฌด ๋ณต์กํด์ง๊ธฐ ๋๋ฌธ์, DB์ ์ ์ฅํ ๊ฐ์ฒด๋ ์์ ๊ด๊ณ๋ฅผ ์ฌ์ฉํ์ง ์๋๋ค.
-
์ฐ๊ด๊ด๊ณ: ๊ฐ์ฒด๋ ์ฐธ์กฐ(๋ ํผ๋ฐ์ค)๊ฐ์ ๊ฐ์ง๊ณ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์จ๋ค. ์ฆ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด memer.getTeam() ์ ์ฌ์ฉํ์ฌ ๊ฐํธํ๊ฒ ๋ฐ์ดํฐ ์กฐํ๋ฅผ ํ ์ ์๋ค. ํ์ง๋ง DB๋ ๋ค๋ฅธ ํ ์ด๋ธ์ FK๋ฅผ Join์ ํ์ฌ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์ ์ ์๋ค. ์ด๋ ๋ฌด์์ด ๋ฌธ์ ์ผ๊น?
์๋ฐ์ ๊ฐ์ฒด๋ ์ผ๋ฐฉํฅ์ฑ์ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ Member์์ Team์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ์ ์์ง๋ง, Team์์๋ Member๋ฅผ ์กฐํํ ์ ์๋ค. ๋ฐ๋ฉด, DB๋ ์๋ฐฉํฅ์ฑ์ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ์๋ก ๊ฐ์ ์กฐํ๊ฐ ๊ฐ๋ฅํ๋ค.
์ด๋ฌํ ํน์ง์ ๋ฐ์ํ๊ธฐ ์ํด ์ฐ๋ฆฌ๋ ๊ฐ์ฒด๋ฅผ ๋ชจ๋ธ๋งํ ๋ Member์ Team ํ๋๋ฅผ ๊ฐ์ ธ์ ์ฐธ์กฐ๋ก ์ฐ๊ด๊ด๊ณ๋ฅผ ๋งบ๋๋ค. ์ด๋ฅผ INSERT INTO MEMBER์์ TEAM_ID์ ๊ฐ์ ๋ฃ์ ๋ ์ฐ๋ฆฌ๋ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. ์ฐ๋ฆฌ๊ฐ ํ๋์ ์ ์ฅํ TEAM์ ๊ฐ์ ์ฐธ์กฐ ๊ฐ์ด์ง DB์ PK๊ฐ์ด ์๋๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ member.getTema().getId()๋ฅผ ์ฌ์ฉํ์ฌ ์ด์ฐ์ด์ฐ ํด์ ํด๊ฒฐํ ์ ์๋ค. '
// ์ฌ์ง
ํ์ง๋ง, ์ด๋ฅผ ์กฐํํ ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ๋ค. sql์ ์คํํ ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์กฐํํ ํ์, ํ์ ๊ด๋ จ๋ ์ ๋ณด๋ฅผ ๋ชจ๋ ์ ๋ ฅํ๋ค. ๊ทธ๋ค์์ ํ์๊ณผ ํ ๊ฐ์ ๊ด๊ณ๋ฅผ ์ค์ ํด ์ค ํ member๋ฅผ ๋ฐํํด์ค๋ค.
// ์ฌ์ง
๊ทธ๋ฌ๋ ๊ฐ์ฒด์ ์๋ฐ ์ปฌ๋ ์ ์ ์ฌ์ฉํ๋ฉด ๊ฐ๋จํ ์ฝ๋๋ง์ ์ฌ์ฉํด๋ ์กฐํ๊ฐ ๊ฐ๋ฅํ๋ค. ์ฆ, ์์ ๊ฐ์ด DB์ ์ฐ๊ด ์ํค๋ ค๋ ์๊ฐ ์ปค๋ค๋ ๋ฌธ์ ๋ค์ด ๋ง์ด ๋ฐ์ํ๋ค๋ ๊ฒ์ด๋ค.
๋ ๋์๊ฐ, ๊ฐ์ฒด๋ ์์ ๋กญ๊ฒ ๊ฐ์ฒด ๊ทธ๋ํ๋ฅผ ํ์ํ ์ ์์ด์ผํ๋ค. member.getTeam()์ฒ๋ผ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ๋ชจ๋ ์ฝ๊ฒ ํ์ํ ์ ์์ด์ผ ํ๋ค๋ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ์๊น ์ ์ ์์ ์คํํ SQL์ ๋ฐ๋ผ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ์๊ธฐ ๋๋ฌธ์, member.getTeam()์ ์๋ํ์ง๋ง ์์ง ๋งคํํ์ง ์์ ๋ค๋ฅธ ๊ฐ์ฒด๋ ์กฐํํ ์ ์๋ค. ์ด๋ ์ํฐํฐ์ ์ ๋ขฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. ์ฐ๋ฆฌ๊ฐ getTeam() ๋ฉ์๋๋ ์๊ณ , getOrder ๋ฉ์๋๋ ์์ง๋ง, ์ด ๋ฐํ๋ ๊ฐ์ฒด๊ฐ ์ค์ ๋ก ๋งคํ์ด ๋์๋์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ์ง์ ๋ค ๊น๋ณด์ง ์๋ ์ด์ ๊ฐ์ฒด(์ํฐํฐ)์ ๋ํ ์ค๋ขฐํ ์ ์์ด ๋ฉ์๋๋ฅผ ์๊ฐ์์ด ์ฌ์ฉํ ์ ์๋ค.
**๋ฐ๋ผ์ ๊ณ์ธตํ ์ํคํ ์ฒ๊ฐ ํ์ํ ๊ฒฝ์ฐ์ ์ง์ ํ ์๋ฏธ์ ๊ณ์ธต ๋ถํ ์ด ์ด๋ ต๋ค. ๊ฐ์ฒด๋ต๊ฒ ๋ชจ๋ธ๋ง ํ ์๋ก ๋งคํ ์์ ๋ง ๋์ด๋๋ ๊ฒ์ด๋ค. **
๊ทธ๋ผ ๊ฐ์ฒด๋ฅผ ์๋ฐ ์ปฌ๋ ์ ์ ์ ์ฅ ํ๋ฏ์ด DB์ ์ ์ฅํ ์๋ ์์๊น? ๋ผ๋ ๋ฌผ์์ด ๋์ฌ ๊ฒ์ด๋ค.
JPA๋?
JPA๋ Java Persistence API์ ์ค๋ง์ด๋ค. ์ด๋ ์๋ฐ ์ง์์ ORM ๊ธฐ์ ํ์ค์ด๋ค. ORM์ Object-relational mapping(๊ฐ๊ฒ ๊ด๊ณ ๋งคํ)์ผ๋ก ๊ฐ์ฒด๋ ๊ฐ์ฒด๋ฐ๋ก ์ค๊ณ๋ฅผ ํ๊ณ , ๊ด๊ณํ DB๋ ๊ด๊ณํ DB๋๋ก ์ค๊ณ๋ฅผ ํ๋ฉด ORM ํ๋์์ํฌ๊ฐ ๊ทธ ์ค๊ฐ์์ ์๋ก ๊ฐ์ ๋งคํ์ ํด์ค๋ค. ๋์ค์ ์ธ ์ธ์ด์๋ ๋๋ถ๋ถ ORM๊ธฐ์ ์ด ์กด์ฌํ๋ค. TypeScript๋ TypeORM์ผ๋ก ์ ๊ณต์ ํด์ค๋ค.
JPA๋ Java ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ JDBC API ์ฌ์ด์์ ๋์์ ํ๋ค. ํ์ง๋ง ๊ฐ๋ฐ์๋ JDBC๋ฅผ ์ง์ ์ฌ์ฉํ์ง๋ ์๊ณ JPA๋ฅผ ์ฌ์ฉํ์ฌ JDBC API์ ์ ๊ทผํ์ฌ DB์ ์ํธ์์ฉ์ ํ๋ค. JDBC API๋ SQL๋ฌธ์ DB์ ์ ๊ณตํ๊ณ DB๋ ๊ฒฐ๊ณผ๋ฅผ JDBC API์ ๋ฐํํด์ค๋ค.
JPA ๋์ ๋ฐฉ์
-
์ ์ฅ: MemberDAO(java ์ ํ๋ฆฌ์ผ์ด์ )์์ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๊ณ ์ถ์ด์ ๋ฉค๋ฒ ๊ฐ์ฒด๋ฅผ ๋๊ธด๋ค. ๊ทธ๋ฌ๋ฉด JPA๊ฐ Entity๋ฅผ ๋ถ์ํ๊ณ , INSERT SQL์ ์์ฑํ์ฌ JDBC API๋ฅผ ์ฌ์ฉํ๋ค. ํ์ง๋ง ์ค์ํ ๊ฒ์ ํจ๋ฌ๋ค์์ ๋ถ์ผ์น๋ฅผ ํด๊ฒฐํ๋ค๋ ์ ์ด ๊ฐ์ฅ ํฐ ๋ชฉ์ ์ด์ ์ฅ์ ์ด๋ค.
-
์กฐํ: java ์ ํ๋ฆฌ์ผ์ด์ ์์ find(id)๋ฅผ ์๊ตฌํ๋ฉด JPA๋ SELECT SQL๋ฅผ ์์ฑํ์ฌ JDBC API๋ฅผ ํตํ์ฌ SQL์ DB์ ๋ณด๋ด๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ ResultSet์ ๋งคํํ์ฌ ๋ฐํํด์ค๋ค.
JPA๋ฅผ ์ฌ์ฉํ๋ ์ด์
-
์์ฐ์ฑ: JPA๋ก CRUD๋ฅผ ํ๋ ๊ฒ์ ์ฝ๋ ํ์ค๋ก ํ ์ ์์ ์ ๋๋ก ๋งค์ฐ ๊ฐ๋จํ๋ค.
-
์ ์ง๋ณด์: ๊ธฐ์กด์ ํ๋๋ฅผ ๋ณ๊ฒฝํด๋ ๋ชจ๋ SQL๋ฅผ ์์ ํ ํ์๊ฐ ์๋ค. ํ๋๋ง ์ถ๊ฐํ๋ฉด sql์ jpa๊ฐ ์์์ ์ฒ๋ฆฌํด์ค๋ค.
-
ํจ๋ฌ๋ค์์ ๋ถ์ผ์น ํด๊ฒฐ: JPA๊ฐ ์์์ฒ๋ฆฌ๋ฅผ ๊ธฐ๊ฐ๋งํ๊ฒ ํ๋ค. ์ ๋ขฐํ ์ ์๋ ์ํฐํฐ, ๊ณ์ธต. - ์์ ๋ก์ด ๊ฐ์ฒด ํ์์ด ๊ฐ๋ฅํด์ง๋ค. ๋ํ ๋์ผํ ํธ๋์ ์ ์์ ์กฐํํ ์ํฐํฐ๋ ๊ฐ์์ ๋ณด์ฅํด์ค๋ค.
-
์ฑ๋ฅ: JPA์ ์ฑ๋ฅ ์ต์ ํ ๊ธฐ๋ฅ์ด ์๋ค.
-
1์ฐจ ๊ฐ์์ ๋์ผ์ฑ ๋ณด์ฅ:
- ๊ฐ์ ํธ๋์ ์ ์์์๋ ๊ฐ์ ์ํฐํฐ๋ฅผ ๋ฐํํ๋ค - ์ฝ๊ฐ์ ์กฐํ ์ฑ๋ฅ ํฅ์
- DB Isolation Level์ด Read Commit์ด์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ Repeatable Read๋ฅผ ๋ณด์ฅํ๋ค.
-
ํธ๋์ญ์ ์ ์ง์ํ๋ ์ฐ๊ธฐ
- ํธ๋์ญ์ ์ ์ปค๋ฐํ ๋๊ฐ์ง INSERT SQL์ ๋ชจ์๋ค
- ๊ทธํ JDBC BAT SQL ๊ธฐ๋ฅ์ ์ฌ์ฉํด์ ํ๋ฒ์ SQL์ ์ ์กํ๋ค.
๋ฐ๋ผ์ ์ฌ๋ฌ๋ฒ์ ํธ๋์ง์ ์ด ๋ฐ์ํ์ง ์๊ณ 1๋ฒ๋ง ๋ฐ์ํ์ฌ ์ฑ๋ฅ์ด ์ข๋ค.
-
์ฆ์ ๋ก๋ฉ๊ณผ ์ง์ฐ ๋ก๋ฉ
- ์ง์ฐ ๋ก๋ฉ: ๊ฐ์ฒด๊ฐ ์ค์ ์ฌ์ฉ๋ ๋ ๋ก๋ฉ๋๋ค.
- ์ฆ์ ๋ก๋ฉ: JOIN SQL๋ก ํ๋ฒ์ ์ฐ๊ด๋ ๊ฐ์ฒด๊น์ง ๋ฏธ๋ฆฌ ์กฐํํ๋ค. ์๋ฅผ ๋ค์ด ๋ฉค๋ฒ๋ฅผ ์กฐํํ ๋ ํญ์ ํ๋ ์กฐํํด์ผ๋๋ค๋ฉด ์ค์ ์ ์ผ์ ํญ์ ๋์ด ํ๋ฒ์ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ํด์ค๋ค.
-
-
๋ฐ์ดํฐ ์ ๊ทผ ์ถ์ํ์ ๋ฒค๋ ๋ ๋ฆฝ์ฑ
-
ํ์ค
-
JPA๋ ํน์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ข ์๋์ด ์์ง ์๋ค. ๊ทน๋จ์ ์ธ ์๋ก MySQL์์ ORACLE๋ก DB๋ฅผ ๋ฐ๊ฟ๋ ํฌ๊ฒ ์ ๋ณผ ๊ฒ์ด ์๋ค.
-
๊ธฐ์กด์๋ ๊ฐ๊ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ ๊ณตํ๋ SQL ๋ฌธ๋ฒ๊ณผ ํจ์๋ ์๋ก ์กฐ๊ธ์ฉ ๋ค๋ฅด๋ค. ์๋ฅผ ๋ค์ด,
- ๊ฐ๋ณ ๋ฌธ์: MySQL์ VARCHAR - Oracle์ VARCHAR2
- ๋ฌธ์์ด์ ์๋ฅด๋ ํจ์: SQL ํ์ค์ SUBSTRING(), Oracle์ SUBSTR()
- ํ์ด์ง: MySQL์ LIMIT, Oracle์ ROWNUM ์ผ๋ก ์๋ก ์ฐจ์ด๊ฐ ์๋ค.
-
๋ฐฉ์ธ์ด๋: SQL ํ์ค์ ์งํค์ง ์๋ ํน์ ๋ฐ์ดํฐ๋ฉ์ด์ค๋ง์ ๊ณ ์ ํ ๊ธฐ๋ฅ์ด๋ค. ์ด๊ฒ์ JPA ์ ์ฅ์์ ๋ฐฉ์ธ์ด๋ผ๊ณ ํํํ๋ ๊ฒ์ด๋ค. ํ์ฌ H2 ๋ฐ์ดํฐ ๋ฒ ์ด์ค๋ฅผ ์ฐ๊ณ ์๋ค. ์ด๋ SQL ํ์ค ๋ฌธ๋ฒ์ ์ฌ์ฉํ์ง ์๊ณ H2๋ง์ ๋ฐฉ์ธ์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ค๋ฉด, JPA๊ฐ ์์์ ํ์ค์ผ๋ก ๋ฒ์ญํด์ ์ ๋ฌํด ์ค๋ค.
- Jpa๋ Persistence๋ผ๋ ํด๋์ค์์ ์์์ ํ๋ค.
- Persistence๋ ๊ฐ์ฅ ๋ง์ META-INF/persistence.xml ์์ ์ค์ ์ ๋ณด๋ฅผ ์กฐํํ๋ค.
- ์กฐํํ ์ค์ ์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก EntityManagerFactory๋ผ๋ ํด๋์ค๋ฅผ ๋ง๋ ๋ค
- ๊ทธ๋ฆฌ๊ณ ํ์ํ ๋๋ง๋ค Factory(๊ณต์ฅ)์์ EntityManager์ด๋ผ๋ ๊ฒ์ ์ฐ์ด๋ด์ ์ฌ์ฉํ๋ค.
โ ์ฃผ์!
-
JPA๋ ํธ๋ ์ ์ ๋จ์๋ก ์๋์ํค๋ ๊ฒ์ด ๋งค์ฐ ์ค์ํ๋ค. ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๋ชจ๋ ์์ ์ ํธ๋ ์ ์ ์์์ ์คํ๋์ด์ผํ๋ค. ๋ฐ๋ผ์ em.getTransaction์ ์์ํ๊ณ ๋๋๋ ์ง์ ์ ์ ํด์ค์ ํ๋์ ํธ๋ ์ ์ ์ ์ ์ธํด์ฃผ์ด์ผํ๋ค.
-
EntitiyManagerFactory๋ ๋งจ ์ฒ์ ๋ก๋ฉ ์์ ์ ๋ฑ ํ๋ฒ๋ง ๋ง๋ค์ด ๋์์ผํ๋ค.
-
์ํฐํฐ ๋งค๋์ ๋ ์ฐ๋๋๊ฐ ๊ณต์ X (์ฌ์ฉํ๊ณ ๋ฒ๋ ค์ผ ํ๋ค.) ๋ฐ๋ผ์ DB์ ์ ์ฅ๋๋ ํธ๋์ ์ ๋จ์๋ฅผ ํ ๋๋ง๋ค EntityManager์ ๋ง๋ค์ด ์ฃผ์ด์ผํ๋ค.
โ *ํธ๋ ์ ์ : ex) ๊ณ ๊ฐ์ด ๋ค์ด์์ ์ด๋ค ํ์๋ฅผ ํ๊ณ ๋๊ฐ๋๋ง๋ค ์ฐ๋ฆฌ๋ ๊ณ ๊ฐ์ ๋๋น ์ปค๋ต์ ์ ์ป์ด์ ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฆฌ๊ณ ์ข ๋ฃํด์ผํ๋ค. ์ด๋ ๊ฒ ์ด๋ค ํ์๋ฅผ ํ ๋ ๋ ๋น๋ฅผ ๊ฐ์ ธ์ค๊ณ ์ข ๋ฃํ ๋๊น์ง๋ฅผ ํ ๋ฌถ์์ผ๋ก ์ผ๊ด๋๋ ๋จ์
create table Member(
id bigint not null,
name varchar(255),
primary key (id)
);MEMBER
;
@Entity
public class Member {
@Id
private Long id; // pk ๊ฐ
private String name;
}
- ์ด๊ธฐ ์์ฑ ํ์
// Entity ๊ณต์ฅ ์์ฑ - ๊ณต์ฅ ์์ฑ์ ํ๋ฒ๋ง.
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello");// ํ๋ผ๋ฏธํฐ ์์๋ persistense.xml์ ์๋ unit ์ด๋ฆ์ ๋ฃ์ด์ค๋ค.
// Entity Manager ๊ฐ์ฒด ์์ฑ - ํธ๋ ์ ์
๋จ์๋ก ๋งค๋ฒ ์์ฑ.
EntityManager entityManager = entityManagerFactory.createEntityManager();
// ํ์ํ Entity Manager ์ฝ๋ ์์ฑ
EntityTransaction transaction = entityManager.getTransaction(); // ํธ๋ ์ ์
์ ์ธ
try { // ์ค๋ฅ๋ฅผ ๋๋นํ๊ธฐ ์ํด try, catch๋ฌธ ์ฌ์ฉ.
transaction.begin(); // ํธ๋ ์ ์
์์.
// ์ฝ๋ ์์ฑํ๊ธฐ
transaction.commit(); // ํธ๋ ์ ์
์ข
๋ฃ - ์ปค๋ฐ ์์ ์ ์์์ฑ ์ปจํ
์คํธ์ ์๋ ๋ด์ฉ์ด DB์ ์ ์ฅ๋๋ค.
} catch(Exception e){
transaction.rollback(); // ์ค๋ฅ ๋ฐ์์ ๋กค๋ฐฑ ํด์ฃผ๊ธฐ
} finally{
entityManager.close();
}
- ๋ฉค๋ฒ ์ ์ฅ
try { // ์ค๋ฅ๋ฅผ ๋๋นํ๊ธฐ ์ํด try, catch๋ฌธ ์ฌ์ฉ.
transaction.begin(); // ํธ๋ ์ ์
์์.
Member member = new Member();
member.setId(3L);
member.setName("HelloC");
entityManager.persist(member); // ๊ฐ์ฒด๋ฅผ ์์์ฑ ์ปจํ
์คํธ์ ์ ์ฅ. ๊ทธํ ๋๋น ์ ์ฅ.
transaction.commit(); // ํธ๋ ์ ์
์ข
๋ฃ - ์ปค๋ฐ ์์ ์ ์์์ฑ ์ปจํ
์คํธ์ ์๋ ๋ด์ฉ์ด DB์ ์ ์ฅ๋๋ค.
} catch(Exception e){
transaction.rollback(); // ์ค๋ฅ ๋ฐ์์ ๋กค๋ฐฑ ํด์ฃผ๊ธฐ
} finally{
entityManager.close();
}
- ๋ฉค๋ฒ ์กฐํ
try { // ์ค๋ฅ๋ฅผ ๋๋นํ๊ธฐ ์ํด try, catch๋ฌธ ์ฌ์ฉ.
transaction.begin(); // ํธ๋ ์ ์
์์.
Member findMember = entityManager.find(Member.class, 1L); // ํด๋ ์ค ์ด๋ฆ, ID๊ฐ์ ๋ฃ์ด์ฃผ๋ฉด ์ฐพ๋๋ค
System.out.println("findMember.id = " + findMember.getId());
System.out.println("findMember.Name = " + findMember.getName());
transaction.commit(); // ํธ๋ ์ ์
์ข
๋ฃ - ์ปค๋ฐ ์์ ์ ์์์ฑ ์ปจํ
์คํธ์ ์๋ ๋ด์ฉ์ด DB์ ์ ์ฅ๋๋ค.
} catch(Exception e){
transaction.rollback();
} finally{
entityManager.close();
}
- ๋ฉค๋ฒ ์์
try { // ์ค๋ฅ๋ฅผ ๋๋นํ๊ธฐ ์ํด try, catch๋ฌธ ์ฌ์ฉ.
transaction.begin(); // ํธ๋ ์ ์
์์.
Member findMember = entityManager.find(Member.class, 1L); // ํด๋ ์ค ์ด๋ฆ, ID๊ฐ์ ๋ฃ์ด์ฃผ๋ฉด ์ฐพ๋๋ค
findMember.setName("HelloJPA"); // ๋ณ๊ฒฝ๋ ๊ฒ์ด ์์ผ๋ฉด jPA๊ฐ ์
๋ฐ์ดํธ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ ์์์ ์ฒ๋ฆฌํ๋ค.
transaction.commit(); // ํธ๋ ์ ์
์ข
๋ฃ - ์ปค๋ฐ ์์ ์ ์์์ฑ ์ปจํ
์คํธ์ ์๋ ๋ด์ฉ์ด DB์ ์ ์ฅ๋๋ค.
} catch(Exception e){
transaction.rollback();
} finally{
entityManager.close();
}
- ๋ฉค๋ฒ ์ญ์
try { // ์ค๋ฅ๋ฅผ ๋๋นํ๊ธฐ ์ํด try, catch๋ฌธ ์ฌ์ฉ.
transaction.begin(); // ํธ๋ ์ ์
์์.
entityManager.remove(findMember);
transaction.commit(); // ํธ๋ ์ ์
์ข
๋ฃ - ์ปค๋ฐ ์์ ์ ์์์ฑ ์ปจํ
์คํธ์ ์๋ ๋ด์ฉ์ด DB์ ์ ์ฅ๋๋ค.
} catch(Exception e){
transaction.rollback();
} finally{
entityManager.close();
}
JPA์์๋ SQL์ ์ถ์ํํ JPQL์ด๋ผ๋ ๊ฐ์ฒด ์งํฅ ์ฟผ๋ฆฌ ์ธ์ด๋ฅผ ์ ๊ณตํ์ฌ ์ฟผ๋ฆฌ๋ฅผ ์ฝ๊ฒ ์์ฑํ๊ฒ ํด์ค๋ค. ์ด๋ SQL๊ณผ ๋ฌธ๋ฒ์ด ์ ์ฌํ๋ค. SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN ๋ฑ์ ์ง์ํ๋ค.
์ฐจ์ด์ :
- JPQL์ ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ๋์์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ค.
- SQL์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์ ๋์์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ค.
JPQL์ ์ฌ์ฉํ๋ฉด ๋ฌด์์ด ๋ฉ๋ฆฌํธ์ธ๊ฐ?
-
ํ์ด์ง ๋ฑ ๋ค์ํ ์์ ์ ํ ๋ DB ๋ฐฉ์ธ์ ์์์ ๋ง์ถฐ์ ์ฌ์ฉํด์ค๋ค. ๋ฐ๋ผ์ DB๋ฅผ ๋ฐ๊ฟ๋ ์ฝ๋๋ฅผ ๊ฑฐ์ ๋ณ๊ฒฝํ ํ์๊ฐ ์๋ค.
-
๊ฐ์ฒด ์งํฅ ์ฟผ๋ฆฌ ์์ฑ์ด๋ค.
-
ํญ์ ๋ฌธ์ ๋ ๊ฒ์ ์ฟผ๋ฆฌ์์ ์๋๋ฐ, DB๊ฐ ์๋ Entity ๊ฐ์ฒด๋ฅผ ๋์์ผ๋ก ๊ฒ์ํ๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
-
๊ธฐ์กด์๋ ๋ชจ๋ DB ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ๋ณํํด์ ๊ฒ์ํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํ๋ค
-
์ ํ๋ฆฌ์ผ์ด์ ์ด ํ์ํ ๋ฐ์ดํฐ๋ง DB์์ ๋ถ๋ฌ์ค๋ ค๋ฉด ๊ฒฐ๊ตญ ๊ฒ์ ์กฐ๊ฑด์ด ํฌํจ๋ SQL์ด ํ์ํ๋ค. ํ์ง๋ง RDB์ ์ค์ ๋ฌผ๋ฆฌ์ ์ธ ํ ์ด๋ธ์ ๊ฐ์ ธ์ค๋ฉด ์ข ์์ ์ผ๋ก ์ค๊ณ๊ฐ ๋์ด ์์ข๋ค. ๋ฐ๋ผ์ JPA๋ SQl์ ์ถ์ํํ JPQL์ด๋ผ๋ ๊ฐ์ฒด ์งํฅ ์ฟผ๋ฆฌ ์ธ์ด๋ฅผ ์ ๊ณตํ์ฌ ์ข ์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
- ๊ฐ์ฅ ๋จ์ํ ์กฐํ ๋ฐฉ๋ฒ
- EntityManager.find()
- ๊ฐ์ฒด ๊ทธ๋ํ ํ์(a.getB().getC())
- ํ์ง๋ง ๋์ด๊ฐ 18์ด ์ด์์ธ ํ์์ ๋ชจ๋ ๊ฒ์ํ๊ณ ์ถ๋ค๋ฉด?
์ค์ต
JPA ์ ์ฅ์์๋ DB ํ ์ด๋ธ์ ๊ธฐ์ค์ผ๋ก ์ ๋ ์ฝ๋๋ฅผ ์ง์ง ์๋๋ค. JPA๋ ๊ฐ์ฒด๋ฅผ ๋์์ผ๋ก ์ฝ๋๋ฅผ ์ง ๋ค.
- ์กฐํ:
List<Member> result = em.createQuery("select m from Member as m", Member.class).getResultList();
JPA๋ฅผ ์ดํดํ๋ ค๋ฉด ์์์ฑ ์ปจํ ์คํธ๋ผ๋ ๊ฒ์ ๋จผ์ ์ดํดํด์ผ ํ๋ค.
JPA์์ ๊ฐ์ฅ ์ค์ํ 2๊ฐ์ง:
-
๊ฐ์ฒด์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋งคํํ๊ธฐ - ์ค๊ณ/์ ์ ์ธ ๋ถ๋ถ
-
์์์ฑ ์ปจํ ์คํธ - ์ค์ JPA ๋ด๋ถ ๋์ ๋ฐฉ์์ ๋ํ ๋ถ๋ถ
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ๋ ์์
-
์ํฐํฐ ๋งค๋์ ํฉํ ๋ฆฌ์์๋ ๊ณ ๊ฐ์ ์์ฒญ์ด ๋ค์ด์ฌ ๋๋ง๋ค ์ํฐํฐ ๋งค๋์ ๋ฅผ ์์ฑํ๋ค.
-
๋ง๋ค์ด ์ง ์ํฐํฐ ๋ฉ์ด์ ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ปค๋ฅ์ ํ์ ์๋ ์ปค๋ต์ ์ ์ฌ์ฉํด์ ๋๋น๋ฅผ ์ฌ์ฉํ๋ค.
JPA๋ฅผ ์ดํดํ๋๋ฐ ๊ฐ์ฅ ์ค์ํ ์ฉ์ด์ด๋ค.
์๋ฏธ: "์ํฐํฐ๋ฅผ ์๊ตฌ ์ ์ฅํ๋ ํ๊ฒฝ"์ด๋ผ๋ ๋ป. ํ์ง๋ง ๋ ผ๋ฆฌ์ ์ธ ๊ฐ๋ ์ด๊ธฐ ๋๋ฌธ์ ๋์ ๋ณด์ด์ง ์๋๋ค.
์ฝ๋: EntityManager.persist(entity); // ์ํฐํฐ๋ฅผ ์์์ฑ ์ปจํ ์คํธ๋ผ๋ ๊ณณ์ ์ ์ฅ์ ํ๋ค๋ ์๋ฏธ.
์ํฐํฐ์ ์๋ช ์ฃผ๊ธฐ
-
๋น์์(new/transient): ์์์ฑ ์ปจํ ์คํธ์ ์ ํ ๊ด๊ณ๊ฐ ์๋ ์๋ก์ด ์ํ
-
๊ฐ์ฒด๋ง ์์ฑํ ์ํ
-
Member member = new Member(); member.setId("member1"); member.setUsername("ํ์1");
-
-
์์(managed): ์์์ฑ ์ปจํ ์คํธ์ ๊ด๋ฆฌ๋๋ ์ํ
-
๊ฐ์ฒด๋ฅผ ์์ฑํ ํ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ์ํ(์์)
-
Member member = new Member(); member.setId("member1"); member.setUsername("ํ์1"); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); em.persist(member); // ๊ฐ์ฒด๋ฅผ ์ ์ํ ์ํ(์์)
-
DB์ ์ฅ์ ํธ๋ ์ ์ ์ commit ํ๋ ๊ฒฝ์ฐ์ ๋๋น์ ์ฟผ๋ฆฌ๊ฐ ๋ ๋ผ๊ฐ๊ฒ๋๋ค.
-
-
์ค์์(detached): ์์์ฑ ์ปจํ ์คํธ์ ์ ์ฅ๋์๋ค๊ฐ ๋ถ๋ฆฌ๋ ์ํ
-
em.detach(member);
-
-
์ญ์ (removed): ์ญ์ ๋ ์ํ
-
em.remove(member);
-
์ด๋ DBํ๊ณ ์ดํ๋ฆฌ์ผ์ด์ ์ค๊ฐ์ ๋ฌด์ธ๊ฐ๊ฐ ํ๋ ์๋ ๊ฒ์ด๋ค.
์์์ฑ ์ปจํ ์คํธ์ ์ด์ :
- 1์ฐจ ์บ์
- ๋์ผ์ฑ ๋ณด์ฅ
- ํธ๋์ญ์ ์ ์ง์ํ๋ ์ฐ๊ธฐ ์ง์ฐ
- ๋ณ๊ฒฝ ๊ฐ์ง
- ์ง์ฐ ๋ก๋ฉ
@Entiti: @Entity๊ฐ ๋ถ์ ํด๋์ค๋ JPA๊ฐ ๊ด๋ฆฌ, ์ํฐํฐ๋ผ ํ๋ค. JPA๋ฅผ ์ฌ์ฉํด์ ํ ์ด๋ธ๊ณผ ๋งคํํ ํด๋์ค๋ @Entity๊ฐ ํ์๋ก ์์ฑ๋์ด์ผ ํ๋ค.
์ฃผ์:
- ๊ธฐ๋ณธ ์์ฑ์ ํ์(ํ๋ผ๋ฏธํฐ๊ฐ ์๋ public ๋๋ protected ์์ฑ์)
- final ํด๋์ค, enum, interface, inner ํด๋์ค๋ ์ฌ์ฉํ ์ ์๋ค.
- ์ ์ฅํ ํ๋์ final์ ์ฌ์ฉํ๋ ๊ฒ๋ ๊ธ์ง!!
์ต์ | ์ค๋ช |
---|---|
create | ๊ธฐ์กดํ ์ด๋ธ ์ญ์ ํ ๋ค์ ์์ฑ(DROP+CREATE) |
create-drop | create์ ๊ฐ์ผ๋ ์ข ๋ฃ ์์ ์ ํ ์ด๋ธ DROP |
update | ๋ณ๊ฒฝ๋ถ๋ง ๋ฐ์(์ด์DB์๋ ์ฌ์ฉํ๋ฉด ์๋จ) |
validate | ์ํฐํฐ์ ํ ์ด๋ธ์ด ์ ์ ๋งคํ๋์๋์ง๋ง ํ์ธ |
none | ์ฌ์ฉํ์ง ์์ |
์ฃผ์: ์ด์ ์ฅ๋น์๋ ์ ๋ Create, Create-drop, update๋ฅผ ์ฌ์ฉํ๋ฉด ์๋๋ค!!!!
-
๊ฐ๋ฐ ์ด๊ธฐ ๋จ๊ณ๋ create ๋๋ update
-
ํ ์คํธ ์๋ฒ๋ update ๋๋ validate
-
์คํ ์ด์ง๊ณผ ์ด์ ์๋ฒ๋ validate ๋๋ none - ํ์ง๋ง ์ต๋ํ ์ฐ์ง๋ง ๊ฒ
์์๊ด๊ณ ๋งคํ : ๊ฐ์ฒด์ ์์ ๊ตฌ์กฐ์ DB์ ์ํผํ์ ์๋ธํ์ ๊ด๊ณ๋ฅผ ๋งคํํ๋ ๊ฒ์ด๋ค. ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ๋ ผ๋ฆฌ ๋ชจ๋ธ์ ๋ณด๋ฉด, ๋ฌผํ์ด๋ผ๋ ์ํผ ํ์ ์๋ ์๋ฐ, ์ํ, ์ฑ ์ด๋ผ๋ ์๋ธํ์ ๋ค ๊ฐ์ ๊ณตํต์ ์ธ ์์ฑ ํ์ฉํ์ฌ ๋งคํํ ์ ์๋ค. ๊ฐ์ฒด๋ ๋ช ํํ๊ฒ ์์ ๊ด๊ณ๊ฐ ์์ง๋ง, ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์์ ๊ด๊ณ๊ฐ ์๋ค. ๋ฐ๋ผ์ ์ด์ฒ๋ผ ์ํผํ์ , ์๋ธํ์ ์ด๋ผ๋ ๊ด๊ณ๋ฅผ ํ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ธ๋ง ๊ธฐ๋ฒ์ด ๊ฐ์ฒด ์์๊ณผ ์ต๋ํ ์ ์ฌํ๊ฒ ๊ตฌํํ ์ ์๋๋ก ํด์ฃผ๋ ๊ฒ์ด๋ค. ๋ค์๋งํ์ง๋ง ์ฌ๊ธฐ์ ํฌ์ธํธ๋, ์ํผ ํ์ ํ ์ด๋ธ์ด ์๋ธ ํ์ ํ ์ด๋ธ์ ๋ด์ฉ ํน์ ์๋ธ ํ์ ํ ์ด๋ธ์ด ์ํผํ์ ํ ์ด๋ธ์ ๋ด์ฉ์ ์ด๋ป๊ฒ ๊ฐ์ ธ์ฌ์ ์๋๋์ด๋ค. ๊ณตํต์ ์ ์ํผํ์ ์ ๋ค ๋ชฐ์๋ฃ๊ณ ์๋ธ ํ์ ์ ๊ทธ ๊ณตํต์ ์ ์ฌ์ฉํ์ง ์๋ ๊ฒ๋ง์ด ๋ฐฉ๋ฒ์ ์๋๋ค.
์์๊ด๊ณ ๋งคํ ๊ตฌํํ๋ 3๊ฐ์ง ๋ฐฉ๋ฒ(=๋ ผ๋ฆฌ ๋ชจ๋ธ์ ๋ฌผ๋ฆฌ ๋ชจ๋ธ๋ก ๊ตฌํํ๋ ๋ฐฉ๋ฒ)
- ์กฐ์ธ ์ ๋ต: ๊ฐ๊ฐ ํ ์ด๋ธ๋ก ๋ณํ - DB JOIN์ ํ์ฉํ์ฌ ์๋ธ๋ชจ๋ธ์ ๋ด์ฉ์ ๊ฐ์ ธ์จ๋ค. ์ด๋ ์๋ธ ํ์ ์ ๊ณตํต์ ์ ์ํผํ์ ์๋ง ์ ์ฅํด ๋๊ณ ์ฌ์ฉํ๋, ์ฐ๋ฆฌ๊ฐ ์๋ ๊ฐ์ฅ ํํ ๋ฐฉ๋ฒ์ด๋ค. ์ด๋ ์๋ธ ํ ์ด๋ธ๋ค์ ๊ตฌ๋ณํ๊ธฐ ์ํด์ ์ํผํ์ ์ ์์ฑ์๋ Dtype๊ณผ ๊ฐ์ ์์ฑ์ ์ถ๊ฐํด์ค๋ค.
@Entity
@Inheritance(strategy = InheritanceType.JOINED) // join ์ ๋ต์ ์ฌ์ฉํ๋ ๋ฒ
@DiscriminatorColumn // ์ํผ ํ์
์ Dtype ์์ฑ์ ์ถ๊ฐํด์ฃผ๊ณ ์๋ธ ํ์
์ ํ
์ด๋ธ ์ด๋ฆ์ ๋ด์ฉ์ผ๋ก ์ถ๊ฐํด์ฃผ๋ ์ด๋
ธํ
์ด์
์ด๋ค.
// ์๋ธ ํ์
์๋ @DiscriminatorValue()๋ฅผ ์ฌ์ฉํด์ฃผ์ด์ผ ํ๋ค. ๊ธฐ๋ณธ ๊ฐ์ ํด๋ ์ค ๋ช
์ด์ง๋ง, ๋ง์ฝ์ dtype ๋ด์ฉ์ ํน์ ํ ๋ด์ฉ์ผ๋ก ๋ฐ๊พธ๊ณ ์ถ๋ค๋ฉด @DiscriminatorValue("A")์ ๊ฐ์ด ์จ์ฃผ๋ฉด ๋๋ค.
public abstract class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
...
- ์กฐ์ธ ์ ๋ต์ ์ฅ์ :
- ํ ์ด๋ธ์ด ์ ๊ทํ ๋์ด์๊ณ
- ์ธ๋ํค ์ฐธ์กฐ ๋ฌด๊ฒฐ์ฑ ์ ์ฝ์กฐ๊ฑด ํ์ฉ์ด ๊ฐ๋ฅํ๋ค. - ์ฃผ๋ฌธ ์์ดํ ์ด ํ์ํ ๋ ์์ดํ ํ ์ด๋ธ๋ง ๋ด๋ ๋๋ค.
- ์ ์ฅ๊ณต๊ฐ์ ํจ์จํ
- ์กฐ์ธ ์ ๋ต์ ๋จ์ :
- ์กฐํ์ ์กฐ์ธ์ ๋ง์ด ์ฌ์ฉํ๊ฒ ๋์ด ์ฑ๋ฅ์ด ์ ํ๋๋ค.
- ์กฐํ ์ฟผ๋ฆฌ๊ฐ ๋ณต์กํ๋ค.
- ๋ฐ์ดํฐ ์ ์ฅ ์ Insert SQL์ด 2๋ฒ ํธ์ถ๋๋ค.
- ๋จ์ผ ํ ์ด๋ธ์ ๋นํด์ ๊ด๋ฆฌํ๊ธฐ ๋ณต์กํ๋ค๋ ๋จ์ ์ด ์๋ค. ํ์ง๋ง ๋ค ๋ชจ๋ ํฐ ๋จ์ ์ด ์๋๊ธฐ ๋๋ฌธ์, ์กฐ์ธ ์ ๋ต์ ๋ฉ์ธ์ผ๋ก ์ค๊ณํ๋ ๊ฒ์ด ์ข๋ค.
- ๋จ์ผ ํ ์ด๋ธ ์ ๋ต(@inheritance(strategy=InheritanceType.SINGLE_TABLE): ํตํฉ ํ ์ด๋ธ๋ก ๋ณํ - ์๋ธ ํ์ ์ ๋ชจ๋ ์์ฑ์ ์ํผํ์ ์ ๋ชจ๋ ๋ฃ์ด์ ํ ์ด๋ธ ํ๋๋ก ์ฌ์ฉํ๋ ๊ฒ์ด๋ค. ์ด๋ dtype์ผ๋ก ์๋ธํด๋์ค๋ฅผ ๊ตฌ๋ถํ๋ค. ๋จ์ผ ํ ์ด๋ธ์ @DiscriminatorColumn์ด ์์ด๋ ํ์๋ก dtype์ด ์์ฑ๋๋ค.
- ๋จ์ผ ํ
์ด๋ธ ์ ๋ต์ ์ฅ์ :
- ์กฐ์ธ์ด ํ์์๊ณ select ํ๋ฒ๋ง ์ฌ์ฉํ๋ฉด ๋๋ฏ๋ก ์ผ๋ฐ์ ์ผ๋ก ์กฐํ ์ฑ๋ฅ์ด ๋น ๋ฅด๋ค.
- ์กฐํ ์ฟผ๋ฆฌ๊ฐ ๋จ์ํ๋ค.
- ๋จ์ผ ํ
์ด๋ธ ์ ๋ต์ ๋จ์ :
- **์์ ์ํฐํฐ๊ฐ ๋งคํํ ์ปฌ๋ผ์ ๋ชจ๋ null ํ์ฉํด์ผํ๋ค๋ ์น๋ช ์ ์ธ ๋จ์ ์ด ์๋ค. ๋ฐ๋ผ์ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ์ ์ฅ์์๋ ์ ๋งคํ๋ค.
- ๋จ์ผ ํ ์ด๋ธ์ ๋ชจ๋ ๊ฒ์ ์ ์ฅํ๋ฏ๋ก ํ ์ด๋ธ์ด ์ปค์ง์ ์์ด์, ์ํฉ์ ๋ฐ๋ผ ์กฐํ ์ ๋ต๋ณด๋ค ์ฑ๋ฅ์ด ์์ข์์ง ์ ์๋ค.
- ๊ตฌํ ํด๋์ค๋ง๋ค ํ ์ด๋ธ ์ ๋ต(@inheritance(strategy=InheritanceType.TABLE_PER_CLASS): ์๋ธํ์ ํ ์ด๋ธ๋ก ๋ณํ - ๊ฐ ์๋ธ ํ์ ๋ค์ด ๊ณตํต์ ์ ์ํผ ํ์ ์ ๋ฃ์ด๋๋ ๊ฒ์ด ์๋๋ผ, ๊ฐ์ ๋ชจ๋ ๋ค ๊ฐ์ง๋๋ก ์ค๋ณต์ ํ์ฉํด์ฃผ๋ ๊ฒ์ด๋ค. ํ์ง๋ง ์ด ์ ๋ต์ ์๋ก ๋ฌถ์ด๋ ๊ฒ์ด ์์ด์ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ์์ ORM ์ ๋ฌธ๊ฐ ๋ชจ๋ ์ถ์ฒํ์ง ์๋ ์ ๋ต์ด๋ค
- ๊ตฌํ ํด๋์ค ์ ๋ต์ ์ฅ์ :
- ์๋ธ ํ์ ์ ๋ช ํํ๊ฒ ๊ตฌ๋ถํด์ ์ฒ๋ฆฌํ ๋ ํจ๊ณผ์ ์ด๋ค.
- not null ์ ์ฝ์กฐ๊ฑด์ ์ฌ์ฉํ ์ ์๋ค.
- ๊ตฌํ ํด๋์ค ์ ๋ต์ ๋จ์ :
- ์ฌ๋ฌ ์์ ํ ์ด๋ธ์ ํจ๊ป ์กฐํํ ๋ ์ฑ๋ฅ์ด ๋๋ฆฌ๋ค(UNION SQL)
- ์์ ํ ์ด๋ธ์ ํตํฉํด์ ์ฟผ๋ฆฌํ๊ธฐ ์ด๋ ต๋ค.
- ์๋ก์ด ํ์ ์ด ์ถ๊ฐ๊ฐ ๋ ๋(=๋ณ๊ฒฝ์ด ๋ ๋) ๋ณ๊ฒฝํ๊ธฐ๊ฐ ๋งค์ฐ ๋ฒ๊ฑฐ๋กญ๊ณ ํ๋ค๋ค.
=> ์ด ์ค ์ด๋ค ๋ฐฉ๋ฒ์ผ๋ก ๊ด๊ณ๋งคํ์ ํ๋๋ผ๋ JPA๋ ๋ชจ๋ ํ์ฉํ ์ ์๊ฒ ํด์ค๋ค.
@MappedSuperclass๋ ๊ฐ์ฒด ์ ์ฅ์์ name, id์ ๊ฐ์ ์์ฑ์ด ๋ง์ ํด๋์ค์์ ๊ณ์ ๋์ฌ ๊ฒฝ์ฐ, ์ด ๋ถํธํจ์ ํด๊ฒฐํ๊ธฐ ์ํด ๊ณตํต ๋งคํ ์ ๋ณด๋ฅผ ์ฌ์ฉํ ๋ ์ฌ์ฉ๋๋ ์ด๋ ธํ ์ด์ ์ด๋ค. ๋ฑ ๊ณตํต ๋งคํ ์ ๋ณด๋ฅผ ๋ฟ๋ ค์ฃผ๊ธฐ ์ํ ๋๊ตฌ ์ ๋์ผ ๋ฟ์ด๋ค.
-
ํ ์ด๋ธ๊ณผ ๊ด๊ณ๊ฐ ์๊ณ , ๋จ์ํ ์ํฐํฐ๊ฐ ๊ณตํต์ผ๋ก ์ฌ์ฉํ๋ ๋งคํ ์ ๋ณด๋ฅผ ๋ชจ์ผ๋ ์ญํ ์ด๋ค.
-
์ฃผ๋ก ๋ฑ๋ก์ผ, ์์ ์ผ, ๋ฑ๋ก์, ์์ ์ ๊ฐ์ ์ ์ฒด ์ํฐํฐ์์ ๊ณตํต์ ์ผ๋ก ์ ์ฉํ๋ ์ ๋ณด๋ฅผ ๋ชจ์ ๋ ์ฌ์ฉํ๋ค.
-
cf) @Entity ํด๋์ค๋ ์ํฐํฐ๋ @MappedSuperclass๋ก ์ง์ ํ ํด๋์ค๋ง ์์ ๊ฐ๋ฅํ๋ค.
-
ํน์ง:
- ์์๊ด๊ณ์ ๋งคํ๋์ง ์๋๋ค
- ์ํฐํฐ๊ฐ ์๋๊ธฐ๋๋ฌธ์, ํ ์ด๋ธ๊ณผ ๋งคํ๋์ง ์๋๋ค.
- ๋ถ๋ชจ ํด๋์ค๋ฅผ ์์ ๋ฐ๋ ์์ ํด๋์ค์ ๋งคํ ์ ๋ณด๋ง์ ์ ๊ณตํ๋ค.
- ์กฐํ, ๊ฒ์์ด ๋ถ๊ฐ๋ฅํ๋ค. em.find(BaseEntity) ์ฌ์ฉ ๋ถ๊ฐ๋ฅํ๋ค.
- ์ง์ ์์ฑํด์ ์ฌ์ฉํ ์ผ์ด ์์ผ๋ฏ๋ก ์ถ์ ํด๋์ค๋ก ๋ง๋ค๊ธธ ๊ถ์ฅํ๋ค.
@MappedSuperclass
public abstract class BaseEntity {
private String createBy;
private LocalDateTime createdDate;
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
public String getCreatedBy() {
return createBy;
}
// ๊ฐ ์์ฑ์ getter, setter ๊ธฐ์
...
}
@Entity
public class Member extends BaseEntity {
// ์ด์ ๋ด์ฉ๊ณผ ๋์ผ
...
// JpaMain.class
// ์ด์ ๋ด์ฉ๊ณผ ๋์ผ
...
try {
Member member = new Member();
member.setUsername("user1");
member.setCreatedBy("kim");
member.setCreatedDate(localDateTime.new());
em.persist(member);
em.flush();
em.clear();
tx.commit();
}
// ์ด์ ๋ด์ฉ๊ณผ ๋์ผ
...
์ด๋ ๊ฒ ํ๋์ ํด๋์ค์ ํ์ํ ์์ฑ์ ์ง์ด๋ฃ๊ณ ๊ฐ ํด๋์ค์์ ์ฌ์ฉํ๊ฒ ๋๋ฉด, ๊ฐ ํด๋์ค๋ ์ถ๊ฐ์ ์ธ ์ฝ๋๊ฐ ํ์์์ด ํด๋น ์์ฑ๋ค์ ์ฌ์ฉํ๊ธฐ๋ง ํ๋ฉด ๋๋ค. ์ฝ๋ฉํ ๋ ๊ต์ฅํ ์ฌ์ฉํ๊ธฐ ์ข์ ๊ฒ ๊ฐ๋ค.
##ํ๋ก์!! ํ๋ก์๋ฅผ ์ ์ฌ์ฉํด์ผํ ๊น? ์ฐ๋ฆฌ๋ ์ฝ๋๋ฅผ ์งค๋ Member๊ณผ Team์ผ๋ก(์ฒ๋ผ) ์ฐ๊ด๋์ด ์๋ ํ ์ด๋ธ์ด ์์ ๊ฒ์ด๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๊ฐ Member๋ง ์ถ๋ ฅํ๋ฉด ๋๋ ๋น์ฆ๋์ค ๋ชจ๋ธ์ผ ๊ฒฝ์ฐ๊ฐ ์๊ณ , Member์ Team์ ํจ๊ป ์ฌ์ฉํด์ผ๋๋ ๋น์ฆ๋์ค ๋ชจ๋ธ์ผ ๊ฒฝ์ฐ๊ฐ ์๋ค. Member๋ง ์ถ๋ ฅํด์ผ๋ ๋๋ ๊ทธ๋ผ ๋ญ๋น๊ฐ ๋ฐ์ํ๋ค. ์ด ๋ญ๋น๋ฅผ ๋ง๊ธฐ ์ํด ํ๋ก์๋ผ๋ ๊ฒ์ด ์กด์ฌํ๋ค.
- ๊ธฐ์กด์ em.find()์ em.**getReference()**๋ฅผ ๋น๊ตํด๋ณด์.
- em.find()๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ํตํด์ ์ค์ ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ์กฐํํ๋ ๊ธฐ๋ฅ์ ํ๋ค.
- em.getReference()๋ **๋ฐ์ดํฐ๋ฒ ์ด์ค ์กฐํ๋ฅผ ๋ฏธ๋ฃจ๋ ๊ฐ์ง(ํ๋ก์) ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ์กฐํํ๋ ์ญํ ์ ํ๋ค. ์ด๋ ๋๋น์ ์ฟผ๋ฆฌ๊ฐ ์๋๊ฐ๋๋ฐ๋ ๊ฐ์ฒด๊ฐ ์กฐํ๊ฐ ๋๋ค. ์ด๋ ํ์ด๋ฒ๋ค์ดํธ๊ฐ ์๊ธฐ ๋ด๋ถ์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด์ ๋ง๋ ๋ค.
์ด๊ธฐ์๋ ์ ์ฌ์ง ์ฒ๋ผ target์ ํ ํ ๋น ๊ป๋ฐ๊ธฐ๋ง ์๋ ์ฑ๋ก ์์ฑ์ด ๋๊ณ ๋ฐํ์ด ๋๋ค.
ํ๋ก์์ ํน์ง
- ํ๋ก์๋ ๋ด๋ถ ํ์ด๋ฒ๋ค์ดํธ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ ์ค์ ํด๋์ค๋ฅผ ์๋์ผ๋ก ์์ ๋ฐ์์ ๋ง๋ค์ด์ง๋ค.
- ๋ฐ๋ผ์ ์ค์ ํด๋์ค์ ๊ฒ ๋ชจ์์ด ๊ฐ๋ค.
- ์ฌ์ฉํ๋ ์ ์ฅ์์๋ ์ง์ง ๊ฐ์ฒด์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๊ตฌ๋ถํ์ง ์๊ณ ์ฌ์ฉ๋ง ํ๋ฉด ๋๋ค(์ด๋ก ์)
- ํ๋ก์ ๊ฐ์ฒด๋ ์ค์ ๊ฐ์ฒด์ ์ฐธ์กฐ(target)๋ฅผ ๋ณด๊ดํ๊ณ ์๋ค.
- ํ๋ก์ ๊ฐ์ฒด๋ฅผ ํธ์ถํ๋ฉด ํ๋ก์ ๊ฐ์ฒด๋ ์ค์ ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค.
ํ๋ก์ ๊ฐ์ฒด์ ์ด๊ธฐํ Member member = em.getReference(Member.class, "id1"); member.getName(); ์์ ๊ฐ์ ์ฝ๋๊ฐ ์์ ๊ฒฝ์ฐ, ํ๋ก์๋ ์์์ฑ ์ปจํ ์คํธ์ target์ ์ด๊ธฐํ ํ๊ธฐ์ํด ์ด๊ธฐํ๋ฅผ ์์ฒญํ๋ค. ๊ทธ ํ ์์์ฑ ์ปจํ ์คํธ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์กฐํํ์ฌ ์ค์ Entity๋ฅผ ์์ฑํ๋ค. ๊ทธ๋ฆฌ๊ณ target์ memberName ๋ด์ฉ๋ฌผ์ ๊ฐ์ ธ์์ ์ด๊ธฐํ ํ๊ฒ๋๋ค.
- ํ๋ก์ ๊ฐ์ฒด๋ ์ฒ์ ์ฌ์ฉํ ๋ ํ ๋ฒ๋ง ์ด๊ธฐํ ๋๋ค! - ๋๋ฒ ํธ์ถํ ๊ฒฝ์ฐ ๋๋น๋ฅผ ๋์ด์ ํธ์ถํ์ง ์๊ณ ๋ ๋ถ๋ฌ์จ๋ค
- ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํ ํ ๋, ํ๋ก์ ๊ฐ์ฒด๊ฐ ์ค์ ์ํฐํฐ๋ก ๋ฐ๋๋ ๊ฒ์ ์๋๋ค. ์ด๊ธฐํ๋๋ฉด ํ๋ก์ ๊ฐ์ฒด๋ฅผ ํตํด์ ์ค์ ์ํฐํฐ์ ์ ๊ทผ์ด ๊ฐ๋ฅํ ๊ฒ์ด๋ค.
- ํ๋ก์ ๊ฐ์ฒด๋ ์๋ณธ ์ํฐํฐ๋ฅผ ์์๋ฐ๋๋ค. ๋ฐ๋ผ์ ํ์ ์ฒดํฌ์ ์ฃผ์ํด์ผํ๋ค. == ๋น๊ต ๋์ instance of๋ฅผ ์ฌ์ฉํด์ผํ๋ค.
- ์์์ฑ ์ปจํ ์คํธ๋ฅผ ์ฐพ๋ ์ํฐํฐ๊ฐ ์ด๋ฏธ ์์ผ๋ฉด em.getReference()๋ฅผ ํธ์ถํด๋ ์ค์ ์ํฐํฐ๋ฅผ ๋ฐํํ๋ค.
- ์์์ฑ ์ปจํ ์คํธ์ ๋์์ ๋ฐ์ ์ ์๋ ์ค์์ ์ํ์ผ ๋, ํ๋ก์๋ฅผ ์ด๊ธฐํํ๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. (ํ์ด๋ฒ๋ค์ดํธ๋ org.hibernate.LazyInitializationException ์์ธ๋ฅผ ํฐํธ๋ฆฐ๋ค. ์ด๋ฌธ์ ๋ ์ค์ ๋ก ์ค๋ฌด์์ ๋ง์ด ๋ง๋ฑ๋จ๋ฆฌ๊ฒ ๋๋ค. em.close() ํน์ em.detach()๋ฅผ ํ๊ณ ํ๋ก์๋ฅผ ์ด๊ธฐํ ํ๋ ค๊ณ ํ๋ฉด ์๋ฌ๊ฐ ๋๋๊ฒ์ด๋ค.
public class JpaMain{
public class void main(String[] args) {
...
try {
Member member = new Member();
member.setUsername("Hello);
em.persist(member);
em.flush();
em.clear();
Member findMember = em.find(Member.class, member.getId());
System.out.println("FindMember = " + findMember.getUId());
System.out.println("FindMember = " + findMember.getUsername());
tx.commit();
}
...
์ด๋ ๊ฒ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋ฉด, ์กฐ์ธ ์ฟผ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ํด์์ member๋ง ํ์ํจ์๋ ๋ถ๊ตฌํ๊ณ , Team ์ฟผ๋ฆฌ๋ ๊ฐ์ด ๊ฐ์ ธ์จ ๊ฒ์ ๋ณผ ์ ์๋ค. ํ์ง๋ง em.find() ๋ถ๋ถ์ ์๋์ ๊ฐ์ด ๊ณ ์น๋ฉด, select ์ฟผ๋ฆฌ๊ฐ ์๋๊ฐ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
// Member findMember = em.find(Member.class, member.getId());
Member findMember = em.getReference(Member.class, member.getId());
// System.out.println("FindMember = " + findMember.getUId());
// System.out.println("FindMember = " + findMember.getUsername());
์ด๋ ๊ฒ getID ๋ฑ ์ค์ ๋ก ์ฌ์ฉํ๋ ์ฝ๋๊ฐ ์์ผ๋ฉด member, team์ ์ฟผ๋ฆฌ๊ฐ ํ๋๋ ๋์ค์ง ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
ํ์ง๋ง ์ค์ ๋ก system.out.println ์ ์ฃผ์์ ํ๊ณ ์ฌ์ฉํ๊ฒ๋๋ฉด, ์๋์ ๊ฐ์ด ์ฟผ๋ฆฌ๊ฐ ๋ถ๋ฌ์ ์ง๋ ๊ฒ์ ์ ์ ์๋ค.
ํ๋ก์๋ ์ค์ ์ฌ์ฉ๋๋ ์์ ์ ๋๋น์ ์ฟผ๋ฆฌ๋ฅผ ์กฐํํ๋ค
- ํ๋ก์ ์ธ์คํด์ค์ ์ด๊ธฐํ ์ฌ๋ถ ํ์ธ: PersistenceUil.isLoaded(Object ํ์ํ entity)
- ํ๋ก์ ํด๋์ค ํ์ธ ๋ฐฉ๋ฒ: System.out.println(ํ์ํ entity.getClass().getName());
- ํ๋ก์ ๊ฐ์ ์ด๊ธฐํ: org.hibernate.Hibernate.initialize(ํ์ํ entity); cf) JPA ํ์ค์ ๊ฐ์ ์ด๊ธฐํ๊ฐ ์๋ค. ๊ฐ์ ํธ์ถ: member.getName()
- ์ง์ฐ ๋ก๋ฉ: ์ฐ๊ด๊ด๊ณ๊ฐ ๋งคํ ๋์ด์๋ TEAM๊ณผ MEMBER ์ด ์์ ๋ TEAM์ด ๋ง์ด ์ฌ์ฉ๋์ง ์๋๋ค๊ณ ํ๋ฉด ์ง์ฐ๋ก๋ฉ์ ์ฌ์ฉํ๋ค. Entity์์ ์ฐ๊ด๊ด๊ณ ์ค์ ์ fetch๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. ์ง์ฐ๋ก๋ฉ์ผ๋ก ์ธํ ํ๋ฉด ํ๋ก์๋ก ์ด ๋ด์ฉ์ ๊ฐ์ ธ์ค๊ฒ ๋๋ ๊ฒ์ด๋ค. ๋ก์ง์ด ์ค์ ๋ก ์ฌ์ฉ๋ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ ํ๋ก์๊ฐ ๋๋น์ ์ ๊ทผํด์ ์ด๊ธฐํ๋ฅผ ํ๋ค. ํ์ ๊ฐ์ ธ์ฌ๋๊ฐ ์๋๋ผ ํ์ ์ฌ์ฉํ ๋๋ค!! team.getName(); ํ ๋ ์ด๊ธฐํ๊ฐ ์ด๋ฃจ์ด์ง๋ค.
@Entity
public class Member {
@Id
@GenerateValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne(fetch= FetchType.LAZY) // ์ง์ฐ ๋ก๋ฉ
@JoinColumn(name "TEAM_ID")
private TEAM team;
}
- ์ฆ์ ๋ก๋ฉ: MEMBER์ TEAM์ด ๋์์ ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ ๊ฒฝ์ฐ์ ์ฆ์ ๋ก๋ฉ์ ์ฌ์ฉํ๋ค. ์ฆ์ ๋ก๋ฉ์ EAGER๋ฅผ ์ฌ์ฉํด์ ์กฐํ ํ ์ ์๋ค. ์ฆ์๋ก๋ฉ์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ํ๋ฒ์ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ํ๋ก์๊ฐ ํ๋ฒ์ ์ฆ์ ์ด๊ธฐํ ๋๋ค.
@Entity
public class Member {
@Id
@GenerateValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne(fetch= FetchType.EAGER) // ์ฆ์ ๋ก๋ฉ
@JoinColumn(name "TEAM_ID")
private TEAM team;
}
- ๊ฐ๊ธ์ ์ง์ฐ ๋ก๋ฉ๋ง ์ฌ์ฉํ๊ธฐ!!(ํนํ ์ค๋ฌด์์๋ ๋๋์ฑ์ด ๊ทธ๋ ๋ค)
- ์ฆ์ ๋ก๋ฉ์ ์ ์ฉํ๋ฉด ์์ํ์ง ๋ชปํ SQL์ด ๋ฐ์๋๊ธฐ ๋๋ฌธ์ด๋ค.
- ์ฆ์ ๋ก๋ฉ์ JPQL์์ N+1 ๋ฌธ์ ๋ฅผ ์ผ์ผํจ๋ค. ex) sql์์ member์ ํ์ํ๋ค๊ฐ TEAM์ด๋ผ๋ ์์ฑ์ด ์๊ณ , eagerํ์ ์ผ๋ก ๋์ด์์ผ๋ฉด TEAM๋ ํธ์ถํ๊ฒ ๋๋ค. ์ด๋ ๊ฒ ๋๋ฉด ์ค๋ณต๋๋ ์ฟผ๋ฆฌ๋ฅผ ๋ง์ด ์์ฑ๋๊ฒ ๋๋ค. ์ต์ด ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ ธ๋๋ฐ ์ถ๊ฐ์ ์ผ๋ก ๋๊ฐ์ ์ฟผ๋ฆฌ๊ฐ ๋๊ฐ๋ ๊ฒ์ ์์ ๋งํ N+1์ฟผ๋ฆฌ๋ผ๊ณ ํ๋ค. ์ฌ๊ธฐ์ 1์ด ์ต์ด ์ฟผ๋ฆฌ, n์ด ์ค๋ณต ์ฟผ๋ฆฌ์ด๋ค. cf) ์ฆ์๋ก๋ฉ์ ์ฌ์ฉํ๊ณ ์ถ์ง๋ง N+1๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ๋ชจ๋ ์ง์ฐ๋ก๋ฉ์ผ๋ก ๊น๋ค์์, jpql์์ fetchJoin์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค. ์ด๋ join๋์ด์๋ ๋ชจ๋ ์ฟผ๋ฆฌ๋ฅผ 1๋ฒ๋ง ๊ฐ์ ธ์์ ์ฌ์ฉํ๊ฒ ๋๋ค.
- @ManyToOne, @OneToOne์ ๊ธฐ๋ณธ์ด ์ฆ์ ๋ก๋ฉ์ด๊ธฐ๋๋ฌธ์ LAZY๋ก ์ค์ ํด์ฃผ๊ธฐ!!!
- @OneToMany, @ManyToMany๋ ๊ธฐ๋ณธ์ด ์ง์ฐ ๋ก๋ฉ์ด๋ค.
์ง์ฐ๋ก๋ฉ์ ํ์ฉํ๋ ๋ฐฉ๋ฒ! ์ด๊ฒ์ ์ด๋ก ์ ์ธ ๊ฒ์ด๊ณ , ์ค๋ฌด์์๋ ๋ชจ๋ ๋ค ์ง์ฐ๋ก๋ฉ์ผ๋ก ์ฌ์ฉํด์ผํ๋ค.
- Member์ Team์ด ์์ฃผ ์ฌ์ฉ๋๋ฉด ์ฆ์ ๋ก๋ฉ
- Member์ order๋ ๊ฐ๋ ์ฌ์ฉ๋๋ฉด ์ง์ฐ๋ก๋ฉ
- order์ product๋ ์์ฃผ ์ฌ์ฉ๋๋ฉด ์ฆ์๋ก๋ฉ
- ๋ชจ๋ ์ฐ๊ด๊ด๊ณ์ ์ง์ฐ ๋ก๋ฉ์ ์ฌ์ฉํด๋ผ!
- ์ค๋ฌด์์ ์ฆ์๋ก๋ฉ์ ์ฌ์ฉํ์ง ๋ง๋ผ!
- jpql fetch ์กฐ์ธ์ด๋, ์ํฐํฐ ๊ทธ๋ํ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ(๋ค์์ ์ค๋ช )
- ์ฆ์ ๋ก๋ฉ์ ์์ํ์ง ๋ชปํ ์ฟผ๋ฆฌ๊ฐ ๋์จ๋ค.
cf) ์ง์ฐ ๋ก๋ฉ, ์ฆ์๋ก๋ฉ๊ณผ ์ ํ ๊ด๊ณ๊ฐ ์๋ค.
- ํน์ ์ํฐํฐ๋ฅผ ์์ ์ํ๋ก ๋ง๋ค ๋ ์ฐ๊ด๋ ์ํฐํฐ๋ ํจ๊ป ์์ ์ํ๋ก ๋ง๋ค๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
- ex) ๋ถ๋ชจ ์ํฐํฐ๋ฅผ ์ ์ฅํ ๋ ์์ ์ํฐํฐ๋ ํจ๊ป ์ ์ฅํ๊ณ ์ถ์ ๋์ด๋ค. == ๋ถ๋ชจ๋ฅผ ์ ์ฅํ ๋, ์์๋ ๋ชจ๋ persist๋ก ํธ์ถํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค
- ์์์ฑ ์ ์ด(์ ์ฅ) : @OneToMany(mappedBy="parent", cascade=CascadeType.PERSIST)
@Entity
public class Parent {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy="parent", cascade = CascadeType.ALL)
private List<Child> childList = new ArrayList<>();
public void addChild(Child child){
childList.add(child);
child.setParent(this);
}
//getter setter
...
@Entity
public class Child{
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
// getter setter
...
//JpaMain
public class JpaMain{
public static void main(String[] args){
EntityManagerFactory emf = Persistence.createEntityManageFactory("hello');
EntityManager em = emf.createEntityManager();
EntityTransaction tx - em.getTransaction();
try{
Child child1 = new Child();
Child child2 = new Child();
Parant parent = new Parent();
parent.addChild(child1);
parent.addChild(child2);
// ์ด๋ persist๊ฐ 3๋ฒ์ด๋ ํ์ํ๋ค.
em.persist(parent);
em.persist(child1);
em.persist(child2);
// cascade๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ ์ฝ๋๋ง ์ฌ์ฉํ๋ฉด ๋๋ค.
em.persist(parent);
tx.commmit();
}
...
์ฐ๋ฆฌ๋ parent๊ฐ persist ๊ฐ ๋์์ ๋ child๋ ๊ตณ์ด persist ์ํด์ค๋ ์ ์ ๋ก ๋์์ผ๋ฉด ์ข๊ฒ ๋ค! ์ด๋ ์ฌ์ฉํ๋ ๊ฒ์ด ์์์ฑ ์ ์ด(CASCADE)์ด๋ค.
- ์์์ฑ ์ ์ด๋ ์ฐ๊ด๊ด๊ณ๋ฅผ ๋งคํํ๋ ๊ฒ๊ณผ ์๋ฌด ๊ด๋ จ์ด ์๋ค.
- ์ํฐํฐ๋ฅผ ์์ํํ ๋ ์ฐ๊ด๋ ์ํฐํฐ๋ ํจ๊ป ์์ํํ๋ ํธ๋ฆฌํจ์ ์ ๊ณตํ ๋ฟ์ด๋ค.
- ์ผ๋๋ค์ผ๋ ํญ์ ํ๋ ๊ฒ์ด ์๋๋ค. ํ๋์ ๋ถ๋ชจ๊ฐ ๋ชจ๋ ์์๋ค์ ๊ด๋ฆฌํ ๋ ์๋ฏธ๊ฐ ์๋ค. (๋จ์ผ ์์ ์์ผ๋)
- ํ์ง๋ง ์ฌ๋ฌ ํ์ผ์์ ์๋ ์ ์ํฐํฐ๋ฅผ ๊ด๋ฆฌํ ๋, ์ฆ ์ฌ๋ฌ ๋ถ๋ชจ๊ฐ ๊ฐ์ ์์์ ๊ด๋ฆฌํ ๋๋ ์ฌ์ฉํ๋ฉด ์๋๋ค.
- ALL: ํญ์ ๊ฐ์ด ์ ์ฅ๋์ด์ผ ํ ๋ ์ฌ์ฉ
- PERSIST: ๊ทธ๋ฅ ์ ์ฅํ ๋ ์์์ฉ์ผ๋ก ์ฌ์ฉ
- REMOVE: ์ญ์
- MERGE: ๋ณํฉ
- REFRESH: REFRESH
- DETACH: DETACH
- ๊ณ ์ ๊ฐ์ฒด ์ ๊ฑฐ: ๋ถ๋ชจ ์ํฐํฐ์ ์ฐ๊ด๊ด๊ณ๊ฐ ๋์ด์ง ์์ ์ํฐํฐ๋ฅผ ์๋์ผ๋ก ์ญ์ ํ๋ ๊ธฐ๋ฅ์ด๋ค.
- orphanRemoval = true
- Parent parent1 = em.find(Parent.class, id); parent1.getChildren().remove(0); // ์์ ์ํฐํฐ๋ฅผ ์ปฌ๋ ์ ์์ ์ ๊ฑฐ
- DELETE FROM CHILD WHERE ID=?
- ์ฐธ์กฐ๊ฐ ์ ๊ฑฐ๋ ์ํฐํฐ๋ ๋ค๋ฅธ ๊ณณ์์ ์ฐธ์กฐํ์ง ์๋ ๊ณ ์ ๊ฐ์ฒด๋ก ๋ณด๊ณ ์ญ์ ํ๋ ๊ธฐ๋ฅ์ด๋ค.
- ์ฐธ์กฐํ๋ ๊ณณ์ด ํ๋์ผ ๋ ์ฌ์ฉํด์ผํ๋ค!!
- ํน์ ์ํฐํฐ๊ฐ ๊ฐ์ธ ์์ ํ ๋ ์ฌ์ฉ
- @OneToOne, @OneToMany๋ง ๊ฐ๋ฅํ๋ค
- cf) ๊ฐ๋ ์ ์ผ๋ก ๋ถ๋ชจ๋ฅผ ์ ๊ฑฐํ๋ฉด ์์์ ๊ณ ์๊ฐ ๋๋ค. ๋ฐ๋ผ์ ๊ณ ์ ๊ฐ์ฒด ์ ๊ฑฐ ๊ธฐ๋ฅ์ ํ์ฑํ ํ๋ฉด ๋ถ๋ชจ๋ฅผ ์ ๊ฑฐํ ๋ ์์๋ ํจ๊ป ์ ๊ฑฐ๋๋ค. ์ด๊ฒ์ CascadeType.REMOVE์ฒ๋ผ ๋์ํ๋ค.
- CascadeType.ALL + orphanRemovel=true
- ์ค์ค๋ก ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํ๋ ์ํฐํฐ๋ em.persist()๋ก ์์ํ, em.remove()๋ก ์ ๊ฑฐํ๋ค.
- ๋ ์ต์ ์ ๋ชจ๋ ํ์ฑํ ํ๋ฉด ๋ถ๋ชจ ์ํฐํฐ๋ฅผ ํตํด์ ์์์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํ ์ ์๋ค.
- ๋๋งค์ธ ์ฃผ๋ ์ค๊ณ(DDD)์ Aggregate Root ๊ฐ๋ ์ ์ํํ ๋ ์ ์ฉํ๋ค
JPA๋ ๋ฐ์ดํฐ ํ์ ์ ์ํฐํฐ ํ์ ๊ณผ ๊ฐ ํ์ ์ผ๋ก ํฌ๊ฒ 2๊ฐ์ง๋ก ๋ถ๋ฅํ๋ค.
-
์ํฐํฐ ํ์ ์ด๋
- @Entity๋ก ์ ์ํ๋ ํด๋์ค ๊ฐ์ฒด๋ฅผ ๋งํ๋ค.
- ์ด๋ ๋ฐ์ดํฐ๊ฐ ๋ณํด๋ ์๋ณ์(pk)๋ก ์ง์ํด์ ์ถ์ ์ด ๊ฐ๋ฅํ๋ค๋ ํน์ง์ด ์๋ค.
- ex) ํ์ ์ํฐํฐ์ ํค๋ ๋์ด ๊ฐ์ ๋ค ๋ณ๊ฒฝํด๋ ์ด ๋ฐ์ดํฐ๊ฐ ํน์ ์ ์ ์ ๋ฐ์ดํฐ๋ผ๋ ๊ฒ์ ์ธ์ ๊ฐ๋ฅํ๋ค.
-
๊ฐ ํ์ ์ด๋
- int, Integer, String์ฒ๋ผ ๋จ์ํ ๊ฐ์ผ๋ก ์ฌ์ฉํ๋ ์๋ฐ ๊ธฐ๋ณธ ํ์ ์ด๋ ๊ฐ์ฒด๋ฅผ ๋งํ๋ค.
- ์ด๋ ์๋ณ์๊ฐ ์๊ณ ๊ฐ๋ง ์์ผ๋ฏ๋ก ๋ณ๊ฒฝ์ ์ถ์ ์ด ๋ถ๊ฐ๋ฅํ๋ค.
- ex) ์ซ์ 100์ 200์ผ๋ก ๋ณ๊ฒฝํ๋ฉด ์์ ํ ๋ค๋ฅธ ๊ฐ์ ๋์ฒด๋๋ค.
- ๊ธฐ๋ณธ๊ฐ ํ์
- ์๋ฐ ๊ธฐ๋ณธ ํ์ (int, double)
- ๋ํผ ํด๋์ค(Integer, Long)
- String
- **์๋ฒ ์ด๋ ํ์ (embedded type, ๋ณตํฉ ๊ฐ ํ์ )
- ์ปฌ๋ ์ ๊ฐ ํ์
๊ธฐ๋ณธ๊ฐ ํ์
- ex) String name, int age
- ์๋ช
์ฃผ๊ธฐ๋ฅผ ์ํฐํฐ์ ์์กดํ๋ค.
- ex) ํ์์ ์ญ์ ํ๋ฉด ์ด๋ฆ, ๋์ด ํ๋๋ ํจ๊ป ์ญ์ ๋๋ค.
- ๊ฐ ํ์
์ ๊ณต์ ํ๋ฉด ์ ๋ ์๋๋ค.
- ex) ํ์ ์ด๋ฆ ๋ณ๊ฒฝ ์ ๋ค๋ฅธ ํ์์ ์ด๋ฆ๋ ํจ๊ป ๋ณ๊ฒฝ๋๋ฉด ์๋๋ค. == sideEffect
cf) ์๋ฐ์ ๊ธฐ๋ณธ ํ์
์ ์ ๋ ๊ณต์ ๋์ง ์๋๋ค.
- int, double ๊ฐ์ ๊ธฐ๋ณธ ํ์ (primitive type)์ ์ ๋ ๊ณต์ ๋์ง ์๋๋ค.
- ๊ธฐ๋ณธ ํ์ ์ ํญ์ ๊ฐ์ ๋ณต์ฌํ๋ค.
- Integer๊ฐ์ ๋ํผ ํด๋์ค๋ String ๊ฐ์ ํ์ํ ํด๋์ค๋ ๊ณต์ ๊ฐ๋ฅํ ๊ฐ์ฒด์ด์ง๋ง ๋ณ๊ฒฝ์ ๋์ง ์๋๋ค.
- ex) ํ์ ์ด๋ฆ ๋ณ๊ฒฝ ์ ๋ค๋ฅธ ํ์์ ์ด๋ฆ๋ ํจ๊ป ๋ณ๊ฒฝ๋๋ฉด ์๋๋ค. == sideEffect
cf) ์๋ฐ์ ๊ธฐ๋ณธ ํ์
์ ์ ๋ ๊ณต์ ๋์ง ์๋๋ค.
- ์๋ก์ด ๊ฐ ํ์ ์ ์ง์ ์ ์ํ ์ ์๋ค
- JPA๋ ์๋ฒ ๋๋ ํ์ (embedded type)์ด๋ผ๊ณ ํ๋ค.
- ์ฃผ๋ก ๊ธฐ๋ณธ ๊ฐ ํ์ ์ ๋ชจ์์ ๋ง๋ค์ด์ ๋ณตํฉ ๊ฐ ํ์ ์ด๋ผ๊ณ ๋ ํ๋ค.
- ์ด๋ int, String๊ณผ ๊ฐ์ ๊ฐ ํ์ ์ด๋ฏ๋ก ์ถ์ ์ด ์๋๋ค. ๋ณ๊ฒฝํ๋ฉด ๋!
์ธ์ ์ฌ์ฉํ๋์ง ์๋ฅผ ํ๋ฒ ๋ค์ด๋ณด์. ์ฐ๋ฆฌ๋ ํ์ ์ํฐํฐ๋ฅผ ์์ฑํ ๋, ์ด๋ฆ, ๊ทผ๋ฌด ์์์ผ, ๊ทผ๋ฌด ์ข ๋ฃ์ผ, ์ฃผ์ ๋์, ์ฃผ์ ๋ฒ์ง, ์ฃผ์ ์ฐํธ๋ฒํธ๋ฅผ ๊ฐ์ง๋ค. == id, name, startDate, endDate, city, street, zipcode ํ์ง๋ง ์ฌ๊ธฐ์๋ ๋น์ทํ ์์ฑ์ธ ๊ฒ๋ค์ด ์๋ค. startDate์ endDate๋ ๊ธฐ๊ฐ์ ๊ด๋ จ๋ ๊ฒ์ด๊ณ , city, street, zipcode๋ ์ง ์ฃผ์์ ๊ด๋ จ๋์ด์๋ค. ์ด๋ฅผ ํ๋์ ๊ด๋ จ๋ ๊ฒ์ผ๋ก ๋ฌถ๊ณ ์ถ์ ๋ ์ฐ๋ฆฌ๋ ์๋ฒ ๋๋ ํ์ ์ ์ฌ์ฉํ๋ค. startPeriod์ endPeriod๋ workPeriod๋ก, city, street, zipcode๋ homeAddress๋ก ๋ฌถ๊ณ ์ถ๋ค. ๊ทธ๋ ๊ฒ ๋๋ฉด ์๋์ ๊ฐ์ด member์ ์์ฑ์ด ๋งค์ฐ ๊ฐ๋จํด์ง๋ค.
- @Embeddable: ๊ฐ ํ์ ์ ์ ์ํ๋ ๊ณณ์ ํ์ํ๋ค.
- @Embedded: ๊ฐ ํ์ ์ ์ฌ์ฉํ๋ ๊ณณ์ ํ์ํ๋ค.
- ๊ธฐ๋ณธ ์์ฑ์๋ ํ์์ด๋ค!
- ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
- ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ์์ง๋๊ฐ ๋๋ค.
- Period.isWork()์ฒ๋ผ ํด๋น ๊ฐ ํ์ ๋ง ์ฌ์ฉํ๋ ์๋ฏธ ์๋ ๋ฉ์๋๋ฅผ ๋ง๋ค ์ ์๋ค. == ๊ฐ์ฒด ์งํฅ์ ์ข์!!
- ์๋ฒ ๋๋ ํ์ ์ ํฌํจํ ๋ชจ๋ ๊ฐ ํ์ ์, ๊ฐ ํ์ ์ ์์ ํ ์ํฐํฐ์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ์์กดํ๋ค.
@Entity
public class Member {
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
//๊ธฐ๊ฐ period
@Embedded
private Period period;
//์ฃผ์
@Embedded
private Address address;
//getter setter
...
}
@Embeddable
public class Period {
private LocalDateTime startDate;
private LocalDateTime endDate;
public Period() {} // ๊ธฐ๋ณธ ์์ฑ์
//getter setter
...
}
@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;
public Address() {} // ๊ธฐ๋ณธ ์์ฑ์
public Address(String city, String street, String zipcode){
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
//getter setter
...
}
public class JpaMain {
public static void main(String[] args) {
//emf, em
...
try{
Member member = new Memeber();
member.setUsername("Hello");
member.setHomeAddress(new Address("city", "street", "zipcode");
member.setWordPeriod(new Period());
...
}
...
}
}
- ์๋ฒ ๋๋ ํ์ ์ ์ํฐํฐ์ ๊ฐ์ผ ๋ฟ์ด๋ค.
- ์๋ฒ ๋๋ ํ์ ์ ์ฌ์ฉํ๊ธฐ ์ ๊ณผ ํ์ ๋งคํํ๋ ํ ์ด๋ธ์ ๊ฐ๋ค.
- ๊ฐ์ฒด์ ํ ์ด๋ธ์ ์์ฃผ ์ธ๋ฐํ๊ฒ(find-grained) ๋งคํํ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค.
- ์ ์ค๊ณํ ORM ์ ํ๋ฆฌ์ผ์ด์ ์ ๋งคํํ ํ ์ด๋ธ์ ์๋ณด๋ค ํด๋์ค์ ์๊ฐ ๋ ๋ง๋ค.
- ์ด๋ฅผ ์ฐ๋ฉด ์ฉ์ด, ์ฝ๋, ๋๋ฉ์ธ์ ์ธ์ด๋ค์ ๊ณตํต์ผ๋ก ๊ณต์ ํ๋ฉด์ ์ฌ์ฉํ ์ ์๋ ์ฅ์ ์ด ์๋ค.
- ์ํฐํฐ ํ์์ ๊ฐ ํ์ (ADDRESS)์ด ๋ค์ด์ฌํ ๋ฐ ์ด ํ์์ ์ํฐํฐ๊ฐ ๋ค์ด์ฌ ์๋ ์๋ค.
- ๋ง์ฝ์ ํ ์ํฐํฐ์์ ๊ฐ์ ๊ฐ ํ์ ์ ์ฌ์ฉํ๊ฒ ๋๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
@Embedded
private Address homeAddress;
@Embedded
private Address workAddress;
- ์ด๋ ์ค๋ฅ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ๊ฒ์ด AttributeOverride์ด๋ค.
- ์ฌ๋ฌ๊ฐ๋ฉด AttributeOverrides, ํ๋๋ฉด @AttributeOverride๋ฅผ ์ฌ์ฉํด์ ์ปฌ๋ฌ ๋ช ์์ฑ์ ์ฌ์ ์ ํด์ฃผ๋ฉด ๋๋ค.
- ์๋ฒ ๋๋ ํ์ ์ ๊ฐ์ด null์ด๋ฉด ๋งคํํ ์ปฌ๋ผ ๊ฐ์ ๋ชจ๋ null์ด ๋๋ค.
- ๊ฐ ํ์ ์ ๋ณต์กํ ๊ฐ์ฒด ์ธ์์ ์กฐ๊ธ์ด๋ผ๋ ๋จ์ํํ๋ ค๊ณ ๋ง๋ ๊ฐ๋ ์ด๋ค. ๋ฐ๋ผ์ ๊ฐ ํ์ ์ ๋จ์ํ๊ณ ์์ ํ๊ฒ ๋ค๋ฃฐ ์ ์์ด์ผ ํ๋ค. ์ฐ๋ฆฌ๋ ์ํฐํฐ๋ฅผ ๋ณต์ฌํ๋ ๊ฒ์ ๋ถ๋ด์ค๋ฌ์ ํ๋ฉด์ ๊ฐ์ ๋ณต์ฌํ ๋๋ ํฌ๊ฒ ์ ๊ฒฝ์ ์์ฐ๋ฉด์ ์ฝ๋ฉ์ ํ๊ฒ ๋๋ค. - ์ด๋ ๊ฐ ํ์ ์ด ์๋ฐ ์ธ์์์๋ ์์ ํ๊ฒ ์ค๊ณ๋์ด ์์ด์ ๊ด์ฐฎ์ ๊ฒ์ด๋ค. ํ์ง๋ง ๊ฐ ํ์ ์ ๋ณต์ฌํ ๋ ํญ์ ์์ ํ ๊ฒ์ ์๋๋ค.
- ์๋ฒ ๋๋ ํ์ ๊ฐ์ ๊ฐ ํ์ ์ ์ฌ๋ฌ ์ํฐํฐ์์ ๊ณต์ ํ๋ฉด ๋งค์ฐ ์ํํ๋ค.
- ๋ถ์์ฉ(Side Effect)๊ฐ ๋ฐ์ํ๋ค.
- ์๋ ์ฝ๋์ ๊ฐ์ด member1๋ง ๊ฑฐ์ฃผ์ง๋ฅผ ๋ฐ๊พธ๋ ค๊ณ setcity๋ฅผ ํ๋ ค๊ณ ํ๋ฉด, sql์ insert ์ฟผ๋ฆฌ๋ฅผ 2๋ฒ ๋ณด๋ด์ member2์ ๋์๋ newCity๊ฐ ๋์ด๋ฒ๋ฆฐ๋ค.
try {
Address address = new Address("city", "street", "10000");
Member member = new Member();
member.setUsername("member1");
member.setHomeAddress(address);
em.persist(member);
Member member2 = new Member();
member2.setUsername("member2");
member2.setHomeAddress(address);
em.persist(member2);
member.getHomeAddress().setCity("newCity");
- ๊ฐ ํ์ ์ ์ค์ ์ธ์คํด์ค์ธ ๊ฐ์ ๊ณต์ ํ๋ ๊ฒ์ ๋งค์ฐ ์ํํ๋ค.
- ๋ฐ๋ผ์ ์๋ ์ฝ๋์ ๊ฐ์ด ๊ฐ์ ๊ณต์ ํ๋ ๊ฒ ๋์ ์ธ์คํด์ค ๊ฐ์ ๋ณต์ฌํด์ ์ฌ์ฉํด์ผ๋๋ค.
try {
Address address = new Address("city", "street", "10000");
Member member = new Member();
member.setUsername("member1");
member.setHomeAddress(address);
em.persist(member);
Address copyAddresss = new Address(address.getCity(), address.getStreet(), address.getZipcode());
Member member2 = new Member();
member2.setUsername("member2");
member2.setHomeAddress(copyAddress);
em.persist(member2);
member.getHomeAddress().setCity("newCity");
- ํญ์ ๊ฐ์ ๋ณต์ฌํด์ ์ฌ์ฉํ๋ฉด ๊ณต์ ์ฐธ์กฐ(์์ ๊ฐ์ ์ํฉ)๋ก ์ธํด ๋ฐ์ํ๋ ๋ถ์์ฉ์ ํผํ ์ ์๋ค.
- ๋ฌธ์ ๋ ์๋ฒ ๋๋ ํ์ ์ฒ๋ผ ์ง์ ์ ์ํ ๊ฐ ํ์ ์ ์๋ฐ์ ๊ธฐ๋ณธ ํ์ ์ด ์๋๋ผ ๊ฐ์ฒด ํ์ ์ด๋ค.
- ์๋ฐ ๊ธฐ๋ณธ ํ์ ์ ๊ฐ์ ๋์ ํ๋ฉด ๊ฐ์ ๋ณต์ฌํ๋ค.
- ๊ฐ์ฒด ํ์ ์ ์ฐธ์กฐ ๊ฐ์ ์ง์ ๋์ ํ๋ ๊ฒ์ ๋ง์ ๋ฐฉ๋ฒ์ด ์๋ค.
- ๊ฐ์ฒด์ ๊ณต์ ์ฐธ์กฐ๋ ํผํ ์ ์๋ค.
- ๊ฐ์ฒด ๊ณต์ ๋ ์๋ก ๊ฐ์ ์ธ์คํด์ค(์ฃผ์๊ฐ)์ ๊ณต์ ํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๊ฐ์ด ๋ณ๊ฒฝ์ด ๋๋ ๊ฒ์ด๋ค.
- ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์๋ค. ๋ฐ๋ผ์ ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด์ ๊ฐ์ฒด ํ์ ์ ์์ ํ ์ ์๊ฒ ๋ง๋ค์ด ๋ถ์์ฉ์ ์์ฒ ์ฐจ๋จ์์ผ๋ฒ๋ ค์ผ ํ๋ค.
- ๊ฐ ํ์ ์ ๋ถ๋ณ ๊ฐ์ฒด๋ก ์ค๊ณํด์ผํ๋ค.
- ์์ฑ์๋ก๋ง ๊ฐ์ ์ค์ ํ๊ณ ์์ ์(Setter)๋ฅผ ๋ง๋ค์ง ์์ผ๋ฉด ๋๋ค.
- ์ฐธ๊ณ ๋ก, Integer, String์ ์๋ฐ๊ฐ ์ ๊ณตํ๋ ๋ํ์ ์ธ ๋ถ๋ณ ๊ฐ์ฒด์ด๋ค. **๋ถ๋ณ์ด๋ผ๋ ์์ ์ ์ฝ์ผ๋ก ๋ถ์์ฉ์ด๋ผ๋ ํฐ ์ฌ์์ ๋ง์ ์ ์๋ค.
๊ทธ๋ ๋ค๋ฉด setter๊ฐ ์๋ค๋ฉด ๊ฐ์ ์ด๋ป๊ฒ ๋ฐ๊ฟ๊ฒ์ธ๊ฐ?
try {
Address address = new Address("city", "street", "10000");
Member member = new Member();
member.setUsername("member1");
member.setHomeAddress(address);
em.persist(member);
// address๋ฅผ ํต์งธ๋ก ๊ฐ์๋ผ์์ผํ๋ค.
Address newAddresss = new Address("newCity", address.getStreet(), address.getZipcode());
member.setHomeASddress(newAddress);
}
- ๊ฐ ํ์ : ์ธ์คํด์ค๊ฐ ๋ฌ๋ผ๋ ๊ทธ ์์ ๊ฐ์ด ๊ฐ์๋ฉด ๊ฐ์ ๊ฒ์ผ๋ก ๋ด์ผ ํ๋ค.
- ํ์ง๋ง ๊ฐ์ฒด๋ ์ธ์คํด์ค๊ฐ ๋ค๋ฅด๋ฉด ๊ทธ ์์ ๊ฐ์ด ๊ฐ์๋ ๋ค๋ฅธ๊ฒ์ผ๋ก ๋ณธ๋ค.
- ๋์ผ์ฑ(identity)์ ๋น๊ต: ์ธ์คํด์ค์ ์ฐธ์กฐ ๊ฐ์ ๋น๊ตํ๋ค. == ์ฌ์ฉ.
- ๋๋ฑ์ฑ()์ ๋น๊ต: ์ธ์คํด์ค์ ๊ฐ์ ๋น๊ตํ๋ค. equals() ์ฌ์ฉ
- ๊ฐ ํ์ ์ a.equals(b)๋ฅผ ์ฌ์ฉํด์ ๋๋ฑ์ฑ ๋น๊ต๋ฅผ ํด์ผํ๋ค.
- ๊ฐ ํ์ ์ equals() ๋ฉ์๋๋ฅผ ์ ์ ํ๊ฒ ์ฌ์ ์(์ฃผ๋ก ๋ชจ๋ ํ๋ ์ฌ์ฉ)
- ๊ฐ ํ์ ์ ์ปฌ๋ ์ ์ ๋ด์์ ์ฌ์ฉํ๋ ๊ฒ์ ๋งํ๋ค. ์ฐ๋ฆฌ๋ ๊ธฐ์กด์ ์ผ๋๋ค ๋ฑ์ ๋น๋ํ ๋ ์ํฐํฐ๋ฅผ ์ปฌ๋ ์ ์ผ๋ก ์ฌ์ฉํ์๋ค. ํ์ง๋ง ์ปฌ๋ ์ ์ ๊ฐ ํ์์ ๋ด์์ ์ฌ์ฉํ๋ ค๊ณ ํ๋ค. ๊ฐ ํ์ ์ ์ปฌ๋ ์ ์ผ๋ก ๊ฐ์ง๊ณ ์์ ๋, ์ฌ๊ธฐ์ ๋ฐ์ํ๋ ๋ฌธ์ ๋ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ปฌ๋ ์ ์ ํ ์ด๋ธ ์์ ๋ด์ ์ ์๋ ๊ตฌ์กฐ๊ฐ ์๊ณ ๊ฐ๋ง ๋ฃ์ ์ ์๋ค๋ ํน์ฑ์ด๋ค.
- ๊ฐ ํ์ ์ ํ๋ ์ด์ ์ ์ฅํ ๋ ์ฌ์ฉํ๋ค.
- @ElemnetCollection, @CollectionTable์ ์ฌ์ฉํ๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ปฌ๋ ์ ์ ๊ฐ์ ๋ฐ์ด๋ธ์ ์ ์ฅํ ์ ์๋ค.
- ๋ฐ๋ผ์ ์ปฌ๋ ์ ์ ์ ์ฅํ๊ธฐ ์ํ ๋ณ๋์ ํ ์ด๋ธ์ด ํ์ํ๋ค.
- cf) ๊ฐ ํ์ ์ปฌ๋ ์ ์ ์์์ฑ ์ ์ด(Cascade) + ๊ณ ์ ๊ฐ์ฒด ์ ๊ฑฐ ๊ธฐ๋ฅ์ ํ์๋ก ๊ฐ์ง๋ค๊ณ ๋ณผ ์ ์๋ค.
@Entity
public class Member {
...
@Embedded
private Address homeAddress;
@ElementCollection
@CollectionTable(name = "FAVORIT_FOOD", joinColumns = @JoinColumn(name = "MEMBER_ID"))
private Set<String> favoriteFoods = new HashSet<>();
@ElementCollection
@CollectionTable(name = "ADDRESS" , joinColumns = @JoinColumn(name = "MEMBER_ID"))
// address ๊ฐ ํ์
์ ์ฌ๋ฌ๊ฐ ์ ์ฅ
private List<Address> addressHistory = new ArrayList<>();
...
- ๊ฐ ํ์ ์ ์ฅ ์์
public class JpaMain {
public static void main(String[] args) {
...
try{
Member member = new Member();
member.setUsername("member1");
member.setAddress(new Address("HomeCity", "street", "10000"));
member.getFavoritFoods().add("์นํจ");
member.getFavoritFoods().add("ํผ์");
member.getFavoritFoods().add("์กฑ๋ฐ");
member.getAddressHistory().add(new Address("old1", "street", "10000"));
member.getAddressHistory().add(new Address("old2", "street", "10000"));
}}}
- ๊ฐ ํ์ ์กฐํ + ๊ฐ ํ์ ์์ ๋ฐฉ๋ฒ + ๊ฐ ํ์ ์ปฌ๋ ์ ๋ ์ง์ฐ ๋ก๋ฉ ์ ๋ต ์ฌ์ฉ
public class JpaMain {
public static void main(String[] args) {
...
try{
// ์ด์ ์ฝ๋๋ค
...
Member findMember = em.find(Member.class, member.getId()); // ์ปฌ๋ ์
์ ์ง์ฐ๋ก๋ฉ, address ๋
List<Address> addressHistory = findMember.getAddressHistory();
for(Address address : addressHistory) {
System.out.println("address = " + address. getCity());
}
Set<String> favoriteFoods = findMember.getFavoritFoods();
for (String favoriteFood : favoriteFoods) {
System.out.println("favoriteFood = " + favoriteFood);
}
// ๊ฐ ํ์
๋ด์ฉ ์์
// findMember.getHomeAddress().setCity("newcity"); -> ์๋ชป๋ ๋ฐฉ๋ฒ = ์ฌ์ด๋ ์ดํฉํธ
Address a = findMember = em.find(Member.class, member.getId());
// ํต์งธ๋ก ๊ฐ์๋ผ์ฐ๊ธฐ!! = ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ
findMember.setHomeAddress(new Address("newCity", "a.getStreet(), a.getZipcode()));
// ์นํจ์ ํ์์ผ๋ก ๋ฐ๊พธ๊ณ ์ถ๋ค๋ฉด? foodFavorit์ set<String>์ด๊ธฐ ๋๋ฌธ์ ์ ์ด์ ๊ฐํ์
์ด๋ฏ๋ก ๊ฐ์๋ ์๊ฐ ์๋ค.
findMember.getFavoriteFoods().remove("์นํจ");
findMember.getFavoriteFoods().add("ํ์");
// ์ด๋ฐ์์ผ๋ก ์์ ์์ ์คฌ๋ค๊ฐ ๋ํด์ฃผ์ด์ผํ๋ค.
// ์ฃผ์๋ฅผ ๋ฐ๊ฟ ๊ฒฝ์ฐ
findMember.getAddressHistory().remove(new Address("old1", "street", "10000"));
findMember.getAddressHistory().add(new Address("newCity", "street", "1000"));
}}}
- ๊ฐ ํ์ ์ ์ํฐํฐ์ ๋ค๋ฅด๊ฒ ์๋ณ์ ๊ฐ๋ ์ด ์๋ค.
- ๊ฐ์ ๋ณ๊ฒฝํ๋ฉด ์ถ์ ์ด ์ด๋ ต๋ค.
- ๊ฐ ํ์ ์ปฌ๋ ์ ์ ๋ณ๊ฒฝ ์ฌํญ์ด ๋ฐ์ํ๋ฉด, ์ฃผ์ธ ์ํฐํฐ์ ์ฐ๊ด๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๊ณ , ๊ฐ ํ์ ์ปฌ๋ ์ ์ ์๋ ํ์ฌ ๊ฐ์ ๋ชจ๋ ๋ค์ ์ ์ฅํ๋ค.
- ๊ฐ ํ์ ์ปฌ๋ ์ ์ ๋งคํํ๋ ํ ์ด๋ธ์ ๋ชจ๋ ์ปฌ๋ผ์ ๋ฌถ์ด์ ๊ธฐ๋ณธ ํค๋ฅผ ๊ตฌ์ฑํด์ผ ํจ : null ์ ๋ ฅX, ์ค๋ณต ์ ์ฅ X
=> ๋ฐ๋ผ์ ์ ์ฝ๋์ฒ๋ผ ๊ฐ ํ์ ์ ์์ ํ๋ฉด ์ฟผ๋ฆฌ๊ฐ ์์ฒญ ๋ง์ด ์ญ์ ๋์๋ค๊ฐ ๋ค์ ์์ฑ๋๋ ๋จ์ ์ด ์๋ค. ์ด๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์ถํ ๊ฐ์์ ๋์ด.
- ์ค๋ฌด์์๋ ์ํฉ์ ๋ฐ๋ผ ๊ฐ ํ์ ์ปฌ๋ ์ ๋์ ์ ์ผ๋๋ค ๊ด๊ณ๋ฅผ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ข๋ค
- ์ผ๋๋ค ๊ด๊ณ๋ฅผ ์ํ ์ํฐํฐ๋ฅผ ๋ง๋ค๊ณ , ์ฌ๊ธฐ์์ ๊ฐ ํ์ ์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
- ์์์ฑ ์ ์ด + ๊ณ ์ ๊ฐ์ฒด ์ ๊ฑฐ๋ฅผ ์ฌ์ฉํด์ ๊ฐ ํ์ ์ปฌ๋ ์ ์ฒ๋ผ ์ฌ์ฉํ๋ฉด ๋๋ค.
- EX)
@Entity
public class AddressEntity{
@Id @GeneratedValue
private Long id;
private Address address;
pulbic AddressEntity(String city, String street, String zipcode) {
this.address = new Address(city, street, zipcode);
}
public AddressEntity(Address address) {this.address = address;)
... // getter setter
}
@Entity
public class Member {
...
@Embedded
private Address homeAddress;
@ElementCollection
@CollectionTable(name = "FAVORIT_FOOD", joinColumns = @JoinColumn(name = "MEMBER_ID"))
private Set<String> favoriteFoods = new HashSet<>();
// @ElementCollection
// @CollectionTable(name = "ADDRESS" , joinColumns = @JoinColumn(name = "MEMBER_ID"))
// // address ๊ฐ ํ์
์ ์ฌ๋ฌ๊ฐ ์ ์ฅ
// private List<Address> addressHistory = new ArrayList<>();
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "MEMBER_ID")
private List<AddressEntity> addressHistory = new ArrayList<>();
...
public class JpaMain {
public static void main(String[] args) {
...
try{
Member member = new Member();
member.setUsername("member1");
member.setAddress(new Address("HomeCity", "street", "10000"));
member.getFavoritFoods().add("์นํจ");
member.getFavoritFoods().add("ํผ์");
member.getFavoritFoods().add("์กฑ๋ฐ");
member.getAddressHistory().add(new AddressEntity("old1", "street", "10000"));
member.getAddressHistory().add(new AddressEntity("old2", "street", "10000"));
}}}
JPA๋ ๋ค์ํ ์ฟผ๋ฆฌ ๋ฐฉ๋ฒ์ ์ง์ํ๋ค.
- JPQL, JPA Criteria, QueryDSL, ๋ค์ดํฐ๋ธ SQL, (JPQL์ด ์๋ ๋)JDBC API ์ง์ ์ฌ์ฉํ๊ฑฐ๋ MyBatis, SpringJdbcTemplate์ ์ฌ์ฉํ๋ฉด ๋๋ค.
-
ํ์ ์ด์ :
- ๊ฐ์ฅ ๋จ์ํ ์กฐํ ๋ฐฉ๋ฒ์ EntityManager.find() ํน์ ๊ฐ์ฒด ๊ทธ๋ํ ํ์(a.getB().getC())์ด๋ค.
- ํ์ง๋ง,,, ๋์ด๊ฐ 18์ด ์ด์์ธ ํ์์ ๋ชจ๋ ๊ฒ์ํ๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํ์ง? ๋ผ๋ ๊ฒ์ด ์ถ๋ฐ์ ์ด๋ค.
- JPQL์ sql๊ณผ ๋งค์ฐ ์ ์ฌํ ๋ฌธ๋ฒ์ด ์ ๊ณต์ด ๋๋ค.
- JPA๋ฅผ ์ฌ์ฉํ๊ฒ๋๋ฉด ์ฐ๋ฆฌ๋ ๋ชจ๋ ์ฝ๋๋ฅผ ์ํฐํฐ ๊ฐ์ฒด ์ค์ฌ์ผ๋ก ๊ฐ๋ฐ์ ํด์ผํ๋ค.
- ์ด๋ ๋ฐ์ํ๋ ๋ฌธ์ ๋ ๊ฒ์ ์ฟผ๋ฆฌ์ด๋ค. ์ฐ๋ฆฌ๋ ๊ฒ์์ ํ ๋๋ ํ ์ด๋ธ์ด ์๋ ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ๋์์ผ๋ก ๊ฒ์ํ ์ ์์ด์ผํ๋ค.
- ๋ชจ๋ DB ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ๋ณํํด์ ๊ฒ์ํ๋ ๊ฒ์ ํ์ค์ ์ผ๋ก ๋ถ๊ฐ๋ฅํ๋ค.
- ์ ํ๋ฆฌ์ผ์ด์ ์ด ํ์ํ ๋ฐ์ดํฐ๋ง DB์์ ๋ถ๋ฌ์ค๋ ค๋ฉด ๊ฒฐ๊ตญ ๊ฒ์ ์กฐ๊ฑด์ด ํฌํจ๋ SQL์ด ํ์ํ๋ค.
-
JPQL์ด๋?
- JPA๋ SQL์ ์ถ์ํํ JPQL์ด๋ผ๋ ๊ฐ์ฒด ์งํฅ ์ฟผ๋ฆฌ ์ธ์ด๋ฅผ ์ ๊ณตํ๋ค.
- ์ด๋ SQL ๋ฌธ๋ฒ SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN ๋ฑ์ ๊ธฐ๋ฅ์ ์ง์ํด์ค๋ค.
- JPQL์ ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ๋์์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฆฐ๋ค. ์ฆ, ๊ฐ์ ์งํฅ SQL์ด๋ค.
- SQL ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์ ๋์์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฆฐ๋ค๋ ์ฐจ์ด๊ฐ ์๋ค.
- ๋ฐ๋ผ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค Sql์ ์์กดํ์ง ์๋๋ค๋ ์ฅ์ ์ด ์๋ค.
try{ List<Member> result = em.createQuery( "select m From Member as m where m.username like "%kim%", Member.class).getResultList(); }
์ด๋ ๊ฒ ์ฌ์ฉํ Member์ ํ ์ด๋ธ์ด ์๋๋ผ ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋ค.
ํ์ง๋ง ์ด๋ ๊ฒ ์ฌ์ฉํ๊ฒ ๋๋ฉด ๋์ ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค๊ธฐ ๋งค์ฐ ์ด๋ ต๋ค๋ ๋จ์ ์ด ์๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ ์ด๋ป๊ฒ ํด๊ฒฐํ ์ ์์๊น? ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ Criteria๋ฅผ ์ฌ์ฉํ ์๋ ์๋ค.
- Criteria์ด๋?
- ๋ฌธ์๊ฐ ์๋ ์๋ฐ์ฝ๋๋ก jpql์ ์์ฑํ ์ ์๋ค.
- jpql ๋น๋ ์ญํ ์ ํ๋ค
- jpq ๊ณต์ ๊ธฐ๋ฅ์ด๋ค.
- ๋จ์ : ๋๋ฌด ๋ณต์กํ๊ณ ์ค์ฉ์ฑ์ด ์๋ค.
-
๋์ QueryDSL์ ์ฌ์ฉํ๊ธธ ๊ถ์ฅํ๋ค.
try{
// criteria ์ฌ์ฉ ์ค๋น
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Member> query = cb.createQuery(Member.class);
Root<Member> m = query.from(Member.class);
CriteriaQuery<Member> cq = query.select(m)
String username = "hyunbins";
if(username != null){
cq = cq.where(cb.equal(m.get("username"), "kim"));
}
List<Member> resultList = em.createQuery(cq).getresultLIst();
}
์ด๋ ๊ฒ ์ฝ๋๋ฅผ ์ง๋ฉด ์ค๋ฅ๋ฅผ ์ฝ๊ฒ ์ก๊ณ , ๋์ ์ปค๋ฆฌ๋ฅผ ์ง๊ธฐ๊ฐ ๋น๊ต์ ๋งค์ฐ ์ฝ๋ค๋ ์ฅ์ ์ด ์๋ค. ํ์ง๋ง ๋๋ฌด ๋ณต์กํ๋ค๊ณ ๋๋์๋ ์๋ค๋ ๋จ์ ๋ ์๋ค. ๊ทธ๋ฆฌ๊ณ sql์ค๋ฝ์ง๊ฐ ์๋ค. ์ํ ์์ ์จ๋ ์ ์ง ๋ณด์๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ์ค๋ฌด์์ ์ฌ์ฉํ์ง ์๋๋ค๊ณ ํ๋ค.
- ๋ฌธ์๊ฐ ์๋ ์๋ฐ์ฝ๋๋ก JPQL์ ์์ฑํ ์ ์๋ค.
- JPQL ๋น๋ ์ญํ ์ ํ๋ค
- ์ปดํ์ผ ์์ ์ ๋ฌธ๋ฒ ์ค๋ฅ๋ฅผ ์ฐพ์ ์ ์๋ค.
- ๋์ ์ฟผ๋ฆฌ ์์ฑ์ด ๋งค์ฐ ํธ๋ฆฌํ๋ค.
- ๋จ์ํ๊ณ ์ฝ๋ค.
- ์ค๋ฌด ์ฌ์ฉํ๊ธธ ๊ถ์ฅํ๋ค.
@Override
public List<Order> findAllByQuerydsl(OrderSearch orderSearch){
return queryFactory
.select(order)
.from(order)
.join(order.member, member)
.where(statusEq(orderSearch), memberNameEq(orderSearch))
.fetch();
}
### ๋ค์ดํฐ๋ธ SQL
- JPA๊ฐ ์ ๊ณตํ๋ SQL์ ์ง์ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ด๋ค.
- JPQL๋ก ํด๊ฒฐํ ์ ์๋ ํน์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์กด์ ์ธ ๊ธฐ๋ฅ์ด๋ค.
- ex) ์ค๋ผํด CONNECT BY, ํน์ db๋ง ์ฌ์ฉํ๋ SQL ํํธ
```java
try{
em.createNativeQuery("select MEMBER_ID, city, street, zipcode, USERNAME from MEMBER").getResultList();
}
- JPA๋ฅผ ์ฌ์ฉํ๋ฉด์ JDBC ์ปค๋ฅ์ ์ ์ง์ ์ฌ์ฉํ๊ฑฐ๋, ์คํ๋ง JdbcTemplate, ๋ง์ด๋ฐํฐ์ค ๋ฑ์ ํจ๊ป ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
- ํ์ง๋ง ์์์ฑ ์ปจํ ์คํธ๋ฅผ ์ ์ ํ ์์ ์ ๊ฐ์ ๋ก ํ๋ฌ์ ํด์ผํ๋ค.
- EX) JPA๋ฅผ ์ฐํํด์ SQL์ ์คํํ๊ธฐ ์ง์ ์ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ์๋์ผ๋ก ํ๋ฌ์ํด์ผํ๋ค.
- ์ํ ์์ ์จ๋ ์ฃผ๋ก ๋ค์ดํฐ๋ธ ์ฟผ๋ฆฌ๋ณด๋ค๋ ์ด๊ฑธ ๋ ๋ง์ด ์ฌ์ฉํ๋ค๊ณ ํ๋ค.
JPQL = Java Persistence Query Language
- JPQL์ SQL์ ์ถ์ํํด์ ํน์ ๋ฐ์ดํฐ๋ฒ ์ด์ค SQL์ ์์กดํ์ง ์๋๋ค.
- JPQL์ ๊ฒฐ๊ตญ SQL๋ก ๋ณํ๋๋ค.
- select m from Member as m where m.age> 18
- ์ํฐํฐ์ ์์ฑ์ ๋์๋ฌธ์ ๊ตฌ๋ถ O (Member, age)
- JPQL ํค์๋๋ ๋์๋ฌธ์ ๊ตฌ๋ถ X (SELECT, FROM, where)
- ์ํฐํฐ ์ด๋ฆ ์ฌ์ฉ, ํ ์ด๋ธ ์ด๋ฆ ์๋(Member)
- ๋ณ์นญ์ ํ์(m) (as๋ ์๋ต ๊ฐ๋ฅ)
- TypeQuery: ๋ฐํ ํ์ ์ด ๋ช ํํ ๋ ์ฌ์ฉ
- Query: ๋ฐํ ํ์ ์ด ๋ช ํํ์ง ์์ ๋ ์ฌ์ฉ
TypeQuery<Member> query = em.createQuery("SELECT m FROM Member m", Member.class);
Query query = em.createQuery("SELECT m.username, m.age from Member m");
# JPA ํ์ฉ1
### MemberRepository
@PsersistenceContext: entity ๋งค๋์ - spring boot๊ฐ ์ด ์ด๋
ธํ์ด์
์ด ์๋ค๋ฉด entity ๋งค๋์ ๋ฅผ ์ฃผ์
ํด์ค๋ค.
**return type ์ฃผ์ํ๊ธฐ**
```java
@PersistenceContext // entity ๋งค๋์ - spring boot๊ฐ ์ด ์ด๋
ธํ์ด์
์ด ์๋ค๋ฉด entity ๋งค๋์ ๋ฅผ ์ฃผ์
ํด์ค๋ค.
private EntityManager em;
public Long save(Member member){
em.persist(member);
return member.getId();
}
๋ก์ง ์ค๋ช : member๋ผ๋ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๊ณ ๋ฉค๋ฒ์ ์์ด๋๋ฅผ ๋ฆฌํดํ๋ค.
์ Member ์์ฒด๋ก ๋ฆฌํดํ์ง ์๊ณ ์์ด๋ ๊ฐ๋ง ๋ฆฌํด ํ์๊น?
์ปค๋ฉ๋์ ์ฟผ๋ฆฌ๋ฅผ ๋ถ๋ฆฌํ๋ผ๋ ์์น์ ์ํด์์ด๋ค. ์ ์ฅ ๋ก์ง์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ์ผ์ผํค๋ ์ปค๋ฉ๋ ์ฑ๊ฒฉ์ด ๋๊ธฐ ๋๋ฌธ์ ๊ฐ๊ธ์ ๋ฆฌํด ๊ฐ์ ์๋ง๋๋ ๊ฒ์ด ์ข๋ค. ํ์ง๋ง ์์ด๋๋ง ์๋ค๋ฉด ์กฐํ๊ฐ ๊ฐ๋ฅํ๋ ์์ด๋ ๊ฐ๋ง ์ ๋๋ค.
Entity manage๋ฅผ ํตํ ๋ชจ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ํธ๋ ์ ์ ์์ ์ด๋ฃจ์ด์ ธ์ผํ๋ค.
์๊ตฌ์ฌํญ ๋ถ์: ๋งค์ฐ ๊ฐ๋จํ ์ผํ๋ชฐ์ด๋ค.
-
ํ์ ๊ฐ์ , ๋ชฉ๋ก
ID ์์ฑ 1 ์ด๋ฆ 2 ๋์ 3 ๊ฑฐ๋ฆฌ 4 ์ฐํธ๋ฒํธ -
์ํ ๋ฑ๋ก, ๋ชฉ๋ก ์กฐํ, ์์ , ์ญ์
ID | ์์ฑ |
---|---|
1 | ์ํ๋ช |
2 | ๊ฐ๊ฒฉ |
3 | ์๋ |
4 | ์ ์ |
5 | ISBN |
- ์ํ ์ฃผ๋ฌธ, ๋ด์ญ ์กฐํ ์ญ์ (์ํ ์ฌ๊ณ ๋ ์กฐ์ ๊ธฐ๋ฅ ํ์), ๊ฒ์
ID | ์์ฑ |
---|---|
1 | ์ฃผ๋ฌธํ์ |
2 | ์ํ ์ ํ |
3 | ์ฃผ๋ฌธ ์๋ |
๊ธฐ๋ฅ ๋ชฉ๋ก:
- ํ์ ๊ธฐ๋ฅ
- ํ์ ๋ฑ๋ก
- ํ์ ์กฐํ
- ์ํ ๊ธฐ๋ฅ
- ์ํ ๋ฑ๋ก
- ์ํ ์์
- ์ํ ์กฐํ
- ์ฃผ๋ฌธ ๊ธฐ๋ฅ
- ์ํ ์ฃผ๋ฌธ
- ์ฃผ๋ฌธ ๋ด์ญ ์กฐํ
- ์ฃผ๋ฌธ ์ทจ์
- ๊ธฐํ ์๊ตฌ ์ฌํญ
- ์ํ์ ์ ๊ณ ๊ด๋ฆฌ๊ฐ ํ์ํ๋ค.
- ์ํ์ ์ข ๋ฃ๋ ๋์, ์๋ฐ, ์ํ๊ฐ ์๋ค.
- ์ํ์ ์นดํ ๊ณ ๋ฆฌ๋ก ๊ตฌ๋ถํ ์ ์๋ค.
- ์ํ ์ฃผ๋ฌธ์ ๋ฐฐ์ก ์ ๋ณด๋ฅผ ์ ๋ ฅํ ์ ์๋ค.