โ ๊ณผ๊ฑฐ์๋ ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๋ ค๋ฉด ๋ณต์กํ JDBC API์ SQL์ ํ๋ํ๋ ์ ์ด์ผ ํ๋ค.
โ JdbcTemplate์ด๋ MyBatis ๊ฐ์ ๊ฒ์ ์ฌ์ฉํ๋ฉด์ ๊ฐ๋ฐ ์ฝ๋๊ฐ ๋ง์ด ์ค์์ง๋ง SQL์ ํ๋ํ๋ ์์ฑํด์ผ ํ๋ค.
โ JPA๋ฅผ ์ฌ์ฉํ๋ฉด SQL ์กฐ์ฐจ๋ ์์ฑํ ํ์๊ฐ ์๋ค. JPA๊ฐ ์ ์ ํ SQL์ ์์ฑํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์คํํด์ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๊ฑฐ๋ ๋ถ๋ฌ์ค๊ฒ ๋๋ค.
1. ๋ฌดํ ๋ฐ๋ณต, ์ง๋ฃจํ ์ฝ๋
โพ CRUD ์ฟผ๋ฆฌ ๋ฌดํ ๋ฐ๋ณตํด์ผ๋๋ค. ๊ฐ์ฒด์ ํ๋๊ฐ ์ถ๊ฐ๋๋ฉด ์ฟผ๋ฆฌ๋ค์ ํ๋์ฉ ์ผ์ผ์ด ๋ค ์ถ๊ฐํด์ค์ผ ํ๋ค.
โพ ๊ด๊ณํ DB(Oracle, MySQL)์์๋ SQL๋ง ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก SQL ์์กด์ ์ธ ๊ฐ๋ฐ์ ํ ์ ๋ฐ์ ์๋ค.
2. ํจ๋ฌ๋ค์์ ๋ถ์ผ์น (๊ฐ์ฒด vs ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค)
โพ ๊ด๊ณํ DB๋ ๋ฐ์ดํฐ๋ฅผ ์ ๊ตํํด์ ์ ์ฅํ๋๊ฒ ๋ชฉ์ ์ด๊ณ , ๊ฐ์ฒด๋ ํ๋๋ ๋ฉ์๋ ๊ฐ์๊ฒ ๋ฌถ์ฌ์ ์บก์ํํด์ ์ฐ๋๊ฒ ๋ชฉ์ ์ด๋ค.
โพ ๊ด๊ณํ DB์ ๋ชฉ์ ๊ณผ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ๋ชฉ์ ์ด ์ผ์นํ์ง ์๋๋ค. ๊ทธ๋ฌ๋, ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ์ ์๋ ๊ฐ์ฅ ํ์ค์ ์ธ ๋ฐฉ์์ ๊ด๊ณํ DB์ด๋ค.
โพ ๊ด๊ณํ DB๊ฐ ์ธ์ํ ์ ์๋ ๊ฒ์ SQL๋ฟ์ด๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ตญ Object๋ฅผ SQL๋ก ์ง์ผํ๋ค. ๊ฒฐ๋ก ์ ์ผ๋ก ๊ฐ์ฒด์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ด์ ํจ๋ฌ๋ค์ ๋ถ์ผ์น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋๋ฐ ๋๋ฌด ๋ง์ ์๊ฐ๊ณผ ์ฝ๋๋ฅผ ์๋นํ๋ค๋ ๊ฒ ๋ฌธ์ ๋ค.
โ ๊ฐ์ฒด์๋ ์์ ๊ด๊ณ๊ฐ ์์ง๋ง, ๊ด๊ณํ DB์๋ ์์ ๊ด๊ณ๊ฐ ์๋ค. ์ํผํ์ ์๋ธํ์ ๊ด๊ณ๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ์ฒด ์์๊ณผ ์ ์ฌํ ํํ๋ก ํ ์ด๋ธ์ ์ค๊ณํ ์ ์๋ค.
Album์ DB์ ์ ์ฅํ ๊ฒฝ์ฐ
โฝ ๊ฐ์ฒด๋ฅผ ๋ถํดํ์ฌ ITEM ํ
์ด๋ธ ์ฝ์
SQL๊ณผ ALBUM ํ
์ด๋ธ ์ฝ์
SQL, ์ด 2๊ฐ๋ฅผ ์์ฑํด์ผ ํ๋ค.
Album์ DB์์ ์กฐํํ ๊ฒฝ์ฐ
โฝ ๊ฐ ํ
์ด๋ธ์ ์กฐํํ๋ Join SQL์ ์์ฑํ๊ณ ๊ฐ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์์ฑ, ๋์จ ๊ฐ์ ์ผ์ผ์ด ๊ฐ์ฒด์ ๋ฃ๊ณ ๊ทธ๋ฐ ๋ณต์กํ ๊ณผ์ ์ ๊ฑฐ์ณ์ผ ํ๋ค. ๊ทธ๋์ DB์ ์ ์ฅํ ๊ฐ์ฒด์๋ ์์ ๊ด๊ณ๋ฅผ ์ฐ์ง ์๋๋ค.
Album์ ์๋ฐ ์ปฌ๋ ์ ์ ์ ์ฅํ ๊ฒฝ์ฐ
list.add(album);
Album์ ์๋ฐ ์ปฌ๋ ์ ์์ ์กฐํํ ๊ฒฝ์ฐ
Album album = list.get(albumId);
//๋ถ๋ชจ ํ์
์ผ๋ก ์กฐํ ํ ๋คํ์ฑ ํ์ฉ
Item item = list.get(albumId);
โ ๊ฐ์ฒด๋ ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํด์ ์ฐ๊ด๋ ๊ฐ์ฒด๋ฅผ ์กฐํํ๊ณ , ํ ์ด๋ธ์ PK, FK๋ฅผ ์ฌ์ฉํด์ join์ ํตํด ์ฐ๊ด๋ ํ ์ด๋ธ์ ์กฐํํ๋ค.
โฝ ๊ฐ์ฒด๋ ์ฐธ์กฐ๋ฅผ ์ฌ์ฉ : member.getTeam()
โฝ ํ
์ด๋ธ์ ์ธ๋ํค๋ฅผ ์ฌ์ฉ : JOIN ON M.TEAM_ID = T.TEAM_ID
๐ ๊ฐ์ฒด๋ฅผ ํ ์ด๋ธ์ ๋ง์ถ์ด ๋ชจ๋ธ๋ง
class Member {
String id; //MEMBER_ID ์ปฌ๋ผ ์ฌ์ฉ
Long teamId; //TEAM_ID FK ์ปฌ๋ผ ์ฌ์ฉ
String username; //USERNAME ์ปฌ๋ผ ์ฌ์ฉ
}
class Team {
Long id; //TEAM_ID PK ์ฌ์ฉ
String name; //NAME ์ปฌ๋ผ ์ฌ์ฉ
}
โฝ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ Join์ด๋ผ๋ ๊ธฐ๋ฅ์ด ์๊ธฐ ๋๋ฌธ์ ์ธ๋ํค์ ๊ฐ์ ๊ทธ๋๋ก ๋ณด๊ดํด๋ ๋๋ค.
โฝ ํ์ง๋ง ๊ฐ์ฒด๋ ์ฐ๊ด๋ ๊ฐ์ฒด์ ์ฐธ์กฐ๋ฅผ ๋ณด๊ดํด์ผ ํ๋ค.
๐ ๊ฐ์ฒด๋ค์ด ๋ชจ๋ธ๋ง
class Member {
String id; //MEMBER_ID ์ปฌ๋ผ ์ฌ์ฉ
Team team; //์ฐธ์กฐ๋ก ์ฐ๊ด๊ด๊ณ๋ฅผ ๋งบ๋๋ค
String username; //USERNAME ์ปฌ๋ผ ์ฌ์ฉ
Team getTeam() {
return team;
}
}
class Team {
Long id; //TEAM_ID PK ์ฌ์ฉ
String name; //NAME ์ปฌ๋ผ ์ฌ์ฉ
}
โฝ ์ธ๋ ํค์ ๊ฐ์ ๊ทธ๋๋ก ๋ณด๊ดํ๋ ๊ฒ์ด ์๋๋ผ ์ฐ๊ด๋ Team์ ์ฐธ์กฐ๋ฅผ ๋ณด๊ดํ๋ค.
๐ ๊ฐ์ฒด ๋ชจ๋ธ๋ง ์กฐํ
SELECT M.*, T.* FROM MEMBER M
JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
public Member find(String memberId) {
//SQL ์คํ ...
Member member = new Member();
//๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์กฐํํ ํ์ ๊ด๋ จ ์ ๋ณด ์
๋ ฅ
Team team = new Team();
//๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์กฐํํ ํ ๊ด๋ จ ์ ๋ณด ์
๋ ฅ
//ํ์๊ณผ ํ ๊ด๊ณ ์ค์
member.setTeam(team);
return member;
}
โฝ ๊ทธ๋ฐ๋ฐ ์ด๋ ๊ฒ ๊ฐ์ฒด๋ค์ด ๋ชจ๋ธ๋ง์ ์ฌ์ฉํ๋ฉด ๊ฐ์ฒด๋ฅผ ํ
์ด๋ธ์ ์ ์ฅํ๊ฑฐ๋ ์กฐํํ๊ธฐ๊ฐ ์ฝ์ง ์๋ค๋ ๋จ์ ์ด ์๋ค.
โฝ ์ด๋ฌํ ๊ณผ์ ๋ค์ ๋ชจ๋ ํจ๋ฌ๋ค์ ๋ถ์ผ์น๋ฅผ ํด๊ฒฐํ๋ ค๊ณ ์๋ชจํ๋ ๋น์ฉ์ด๋ค. ๋ง์ฝ ์๋ฐ ์ปฌ๋ ์
์ ํ์ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๋ค๋ฉด ์ด๋ฐ ๋น์ฉ์ด ์ ํ๋ค์ง ์๋๋ค.
๐ ๊ฐ์ฒด ๊ทธ๋ํ ํ์
โฝ ๊ฐ์ฒด๋ ์์ ๋กญ๊ฒ ๊ฐ์ฒด ๊ทธ๋ํ๋ฅผ ํ์ํ ์ ์์ด์ผ ํ๋ค. ํ์ง๋ง ์ฒ์ ์คํํ๋ SQL์ ๋ฐ๋ผ ํ์ ๋ฒ์๊ฐ ๊ฒฐ์ ๋๊ธฐ ๋๋ฌธ์ SQL ์ค์ฌ์ ์ธ ๊ฐ๋ฐ์์๋ ๊ทธ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ค.
๐ ์ํฐํฐ ์ ๋ขฐ ๋ฌธ์
class MemberService {
public void process() {
Member member = memberDAO.find(memberId);
member.getTeam(); //???
member.getOrder().getDelivery(); //???
}
}
โฝ getTeam()์ getOrder().getDelicery()๊ฐ null์ธ์ง ์๋์ง๋ฅผ ์ด ์ฝ๋๋ง ๋ณด๊ณ ๋ ํ์ธํ ์ ์๋ค.
โฝ SQL์์ ํ์๋ ๊ฐ์ฒด ์ด์ธ์๋ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก ์ํฐํฐ๋ฅผ ์ ๋ขฐํ ์ ์๋ค.
โฝ ๊ณ์ธต ์ํคํ
์ณ์์๋ ์ด์ ๊ณ์ธต์์ ๋์ด์จ ๋ด์ฉ์ ์ ๋ขฐํ ์ ์์ด์ผ ํ๋๋ฐ SQL ์ค์ฌ์ ์ธ ๊ฐ๋ฐ์์๋ ๊ทธ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ฏ๋ก ๊ฐ์ฒด๊ฐ SQL์ ์์กดํ๋ค.
memberDAO.getMember(); //Member๋ง ์กฐํ
memberDAO.getMemberWithTeam(); //Member์ Team ์กฐํ
//Member,Order,Delivery
memberDAO.getMemberWithOrderWithDelivery();
โฝ ๊ทธ๋ ๋ค๊ณ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ๋ฏธ๋ฆฌ ๋ก๋ฉํ ์๋ ์์ผ๋ฏ๋ก ์ํฉ์ ๋ฐ๋ผ ๋์ผํ ํ์ ์กฐํ ๋ฉ์๋๋ฅผ ์ฌ๋ฌ๋ฒ ์์ฑํด์ผ ํ๋ค.
โฝ ์ฆ, ์ง์ ํ ์๋ฏธ์ ๊ณ์ธต ๋ถํ ์ด ์ด๋ ต๋ค. ๋ํ, ๊ฐ์ฒด๋ต๊ฒ ๋ชจ๋ธ๋ง ํ ์๋ก ๋งคํ ์์
๋ง ๋์ด๋๋ค.
โ ๊ฐ์ฒด๋ฅผ ์๋ฐ ์ปฌ๋ ์ ์ ์ ์ฅํ๋ฏ์ด DB์ ์ ์ฅํ ์๋ ์์๊น? ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๊ฒ์ด ๋ฐ๋ก JPA(Java Persistence API)์ด๋ค.
โฝ Java Persistence API
โฝ ์๋ฐ ์ง์์ ORM ๊ธฐ์ ํ์ค
โฝ Object-relational mapping(๊ฐ์ฒด ๊ด๊ณ ๋งคํ)
โฝ ๊ฐ์ฒด๋ ๊ฐ์ฒด๋๋ก ์ค๊ณํ๊ณ , ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋๋ก ์ค๊ณํ๊ณ , ORM ํ๋ ์์ํฌ๊ฐ ์ค๊ฐ์์ ๋งคํ์ ํด์ค๋ค.
โฝ ๋์ค์ ์ธ ์ธ์ด์๋ ๋๋ถ๋ถ ORM ๊ธฐ์ ์ด ์กด์ฌ
โฝ ๊ฐ๋ฐ์๊ฐ ์ง์ JDBC API๋ฅผ ์ฌ์ฉํ๋๊ฒ ์๋ JPA๋ฅผ ์ฌ์ฉํ๋ฉด JPA๊ฐ JDBC API๋ฅผ ํธ์ถํ๋ ๋ฐฉ์์ด๋ค.
JPA ๋์ - ์ ์ฅ
โฝ JPA์๊ฒ MemberDAO์์ Member ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๊ณ ์ถ๋คํ๋ฉด JPA๊ฐ Entity๋ฅผ ๋ถ์ ํ Insert SQL ์์ฑํ๋ค. ๊ทธ๋ฆฌ๊ณ JDBC API๋ฅผ ์ฌ์ฉํ์ฌ DB์ SQL์ ๋ณด๋ธ๋ค.
โฝ ์ฟผ๋ฆฌ๋ฅผ ๊ฐ๋ฐ์๊ฐ ๋ง๋๋๊ฒ ์๋๊ณ JPA๊ฐ ๋ง๋ค์ด์ค๋ค.
โฝ ํจ๋ฌ๋ค์์ ๋ถ์ผ์น๋ฅผ ํด๊ฒฐํด์ค๋ค.
JPA ๋์ - ์กฐํ
โฝ JPA์๊ฒ MemberId 10๋ฒ์ ์ฐพ์๋ฌ๋ผ๊ณ ํ๋ฉด JPA๊ฐ Member ๊ฐ์ฒด๋ฅผ ๋ณด๊ณ ์ ์ ํ ์กฐํ ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ JDBC API๋ฅผ ํตํด DB๋ก๋ถํฐ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์์จ๋ค. ๊ทธ๋์ ResultSet ๋งคํ์ ์ํ ํ Entity Object๋ฅผ ๋ฐํํ๋ค.
โฝ ํจ๋ฌ๋ค์์ ๋ถ์ผ์น๋ฅผ ํด๊ฒฐํด์ค๋ค.
JPA๋ ํ์ค ๋ช
์ธ
โฝ JPA๋ ์ธํฐํ์ด์ค์ ๋ชจ์
โฝ JPA 2.1 ํ์ค ๋ช
์ธ๋ฅผ ๊ตฌํํ 3๊ฐ์ง ๊ตฌํ์ฒด : ํ์ด๋ฒ๋ค์ดํธ, EclipseLink, DataNucleus
โ ํ ์ค๋ง ์์ฑํ๋ฉด ๋๊ธฐ์ ์ข์ ์์ฐ์ฑ์ ๊ฐ์ง ์ ์๋ค. JPA์ ์์์ฑ ์ปจํ ์คํธ๋ก ์ธํด ์ปฌ๋ ์ ์์ ๋จ์ํ๊ฒ ์กฐํ ํ setName๋ง ํธ์ถํ์ฌ update ํ ์ ์๋ค.
์ ์ฅ: jpa.persist(member)
์กฐํ: Member member = jpa.find(memberId)
์์ : member.setName(โ๋ณ๊ฒฝํ ์ด๋ฆโ)
์ญ์ : jpa.remove(member)
โ ๊ธฐ์กด์๋ ํ๋ ๋ณ๊ฒฝ์ ๋ชจ๋ SQL ๋ฌธ์ ์์ ํด์ผ ํ์ง๋ง, JPA์์๋ ํ๋๋ง ์ถ๊ฐํ๋ฉด SQL์ JPA๊ฐ ์ฒ๋ฆฌํ๋ค.
โ JPA์ ์์ : ํน์ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ๊ฒฝ์ฐ ์์ ๊ด๊ณ๋ฅผ JPA๊ฐ ๋ถ์ํ์ฌ ํ์ํ ์ฟผ๋ฆฌ๋ฅผ JPA๊ฐ ์์ฑํ๋ค.
โ JPA์ ์ฐ๊ด๊ด๊ณ, JPA์ ๊ฐ์ฒด ๊ทธ๋ํ ํ์ : ์ง์ฐ ๋ก๋ฉ์ ์ฌ์ฉํ์ฌ ์ ๋ขฐํ ์ ์๋ ์ํฐํฐ, ๊ณ์ธต์ ์ ๊ณตํ๋ค.
โ JPA์ ๋น๊ตํ๊ธฐ : ๋์ผํ ํธ๋์ญ์
์์ ์กฐํํ ์ํฐํฐ๋ ๊ฐ์์ ๋ณด์ฅํ๋ค.
๐ 1์ฐจ ์บ์์ ๋์ผ์ฑ(identity) ๋ณด์ฅ
โฝ ๊ฐ์ ํธ๋์ญ์
์์์๋ ๊ฐ์ ์ํฐํฐ๋ฅผ ๋ฐํ -> ์ฝ๊ฐ์ ์กฐํ ์ฑ๋ฅ ํฅ์
โฝ DB Isolation Level์ด Read Commit์ด์ด๋ ์ ํ๋ฆฌ์ผ์ด์
์์ Repeatable Read ๋ณด์ฅ
๐ ํธ๋์ญ์
์ ์ง์ํ๋ ์ฐ๊ธฐ ์ง์ฐ(transactional write-behind)
โฝ ํธ๋์ญ์
์ ์ปค๋ฐํ ๋๊น์ง INSERT SQL์ ๋ชจ์
โฝ JDBC BATCH SQL ๊ธฐ๋ฅ์ ์ฌ์ฉํด์ ํ๋ฒ์ SQL ์ ์ก
โฝ UPDATE, DELETE๋ก ์ธํ ๋ก์ฐ(ROW)๋ฝ ์๊ฐ ์ต์ํ
โฝ ํธ๋์ญ์
์ปค๋ฐ ์ UPDATE, DELETE SQL ์คํํ๊ณ , ๋ฐ๋ก ์ปค๋ฐ
๐ ์ง์ฐ ๋ก๋ฉ(Lazy Loading)๊ณผ ์ฆ์ ๋ก๋ฉ(Eager Loading)
โฝ ์ง์ฐ ๋ก๋ฉ: ๊ฐ์ฒด๊ฐ ์ค์ ์ฌ์ฉ๋ ๋ ๋ก๋ฉ
-> ์ค์ Team ๊ฐ์ฒด์ ํ๋๋ฅผ ์ ๊ทผํ ๋ Team ํ
์ด๋ธ๋ก๋ถํฐ์ ์กฐํ ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ ค์ ๋ฐ์ดํฐ๋ฅผ ์ป์ด์ด
โฝ ์ฆ์ ๋ก๋ฉ: JOIN SQL๋ก ํ๋ฒ์ ์ฐ๊ด๋ ๊ฐ์ฒด๊น์ง ๋ฏธ๋ฆฌ ์กฐํ
-> ํ ๋ฒ์ join์ ํ์ฉํ์ฌ ์ฐ๊ด๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ป์ด์ด