๐Spring JPA์ ๋์
Spring JPA
๋์ - ๊ธฐ์กด ๋ฐฉ์์ ๋ฌธ์ ์
- ๊ฐ์ฒด์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํจ๋ฌ๋ค์์ ๋ถ์ผ์น
- ๊ฐ์ฒด์งํฅ์ด ์๋ฌด๋ฆฌ ์ข์๋ ์๊ตฌ์ ์ผ๋ก ๋ณด๊ดํ๊ธฐ ์ํด์๋ ํ์ค์ ์ผ๋ก๋ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋ค.
- SQL์ ์์กด์ ์ธ ๊ฐ๋ฐ์ ํผํ๊ธฐ ์ด๋ ต๋ค.
- ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์๋ ์์๊ด๊ณ์ ์ ์ฌํ ๊ตฌ์กฐ๊ฐ ์์ง๋ง, ๋ชจ๋ ์ฟผ๋ฆฌ์ ์กฐ์ธ์ ๋ฃ์ด์ ๊ตฌํํ ๊ฒ์ธ๊ฐ?
- ๊ฐ์ฒด ๋ด๋ถ์ Has-A ๊ด๊ณ๋ฅผ ๊ณ์ธต์ ์ผ๋ก ํํํ ์๋ ์์๊น?
-
๊ฒฐ๋ก ์ ์ผ๋ก ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์๋ฐ ์ปฌ๋ ์ ์ฒ๋ผ ์ฌ์ฉํ ์๋ ์์๊น?
- ๊ทธ๋ฆฌ๊ณ ์ํฐํฐ๋ฅผ ์ ๋ขฐํ ์ ์์๊น?
```java
class MemberDAO {
public Member getMember(String memberId) {
String sql = โSELECT * FROM MEMBER WHERE MEMBER_ID = ?โ;
โฆ
//JDBC API, SQL ์คํ
return new Member(โฆ);
}
}
String memberId = โ100โ;
Member member1 = memberDAO.getMember(memberId);
Member member2 = memberDAO.getMember(memberId);
member1 == member2; //๋ค๋ฅด๋ค.
์์ฒ๋ผ ์ฟผ๋ฆฌ๋ฅผ ํตํด ์ป์ด์จ ์ํฐํฐ๋ ๊ฐ์ ๊ฐ์ฒด๊ฐ ์๋์ง๋ง, ์ฐ๋ฆฌ๊ฐ ์ฐ๋ ์๋ฐ ์ปฌ๋ ์
์ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์ป์ด์ฌ ์ ์๋ค.
```java
String memberId = "100";
Member member1 = list.get(memberId);
Member member2 = list.get(memberId);
member1 == member2; //๊ฐ๋ค.
์ด๋ฌํ ๋์ ๋ฐฐ๊ฒฝ์ผ๋ก ์ธํด JPA๋ผ๋ ๊ธฐ์ ์ด ๋๋๋๊ฒ ๋๋ค.
JPA
- Java Persistence API
- node.js์ TypeORM, django์ django ORM์ฒ๋ผ ์๋ฐ ์ง์์ ORM ๊ธฐ์ ํ์ค์ด๋ค.
- Object-relational mapping(๊ฐ์ฒด ๊ด๊ณ ๋งคํ)
- ์ข์ ํ๋ ์์ํฌ๋ค์ด ๊ทธ๋ ๋ฏ ๊ธฐ์กด์ JDBC๋ฅผ ์ wrappingํด์ ์ข์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ค.
History
- ์คํ๋ง์ ๋ชจํ์ด๊ธฐ๋ ํ EJB(์ํฐํ๋ผ์ด์ฆ ์๋ฐ ๋น)์์ ๋ถํธํจ์ ๋๋ ๊ฐ๋ฐ์๋ค์ด ํ์ด๋ฒ๋ค์ดํธ๋ผ๋ ์คํ์์ค๋ฅผ ๊ฐ๋ฐํ์๋ค.
- ๋์ค์ ์ผ๋ก ์์ฒญ๋๊ฒ ํฅํํ์ฌ ์ฌ์ค์์ ํ์ค์ด ๋์ ์๋ฐ ์ง์์์ ํ์ด๋ฒ๋ค์ดํธ๋ฅผ ์์ฉํ์ฌ JPA๋ผ๋ ํ์ค์ ์ ์ํ์๋ค.
- ์คํ๋ง๊ณผ๋ ๋ค๋ฅธ ์์์ผ๋ก ์คํ๋ง์ ์ฌ์ค์ ํ์ค์ด์ง๋ง ์์ง ์๋ฐ์ง์์์ ํ์ค์ ์๋๋ค.
- JPA๋ ์ธํฐํ์ด์ค์ ๋ชจ์์ผ๋ก ํ์ด๋ฒ๋ค์ดํธ๋ ๊ทธ ๊ตฌํ์ฒด์ด๋ค. ์ฌ์ค ๊ตฌํ์ฒด๊ฐ ๋ ๋จผ์ ๋์ค๊ธฐ๋ ํ์ง๋งโฆ
- Hibernate, EclipseLink, DataNucleus๊ฐ์ ๊ตฌํ์ฒด๋ค์ด ์๋ค.
ํจ๋ฌ๋ค์ ๋ถ์ผ์น ๋ฌธ์ ๋ฅผ ํด๊ฒฐ
- ์์์ ์ธ๊ธํ๋ ๋ชจ๋ ๋ฌธ์ ๋ฅผ JPA๊ฐ ํด๊ฒฐํ์๋ค.
- ํ ์ด๋ธ์ ์ํผํ์ , ์๋ธํ์ ๊ด๊ณ๋ฅผ ๊ฐ์ฒด์ ์์๊ด๊ณ์ ๋งคํํ์ฌ ๊น๋ํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ค. ๋ฌผ๋ก ๋ค์์๋ ๋ฐฑ์กฐ์ ๋ฐ์ฒ๋ผ ์์ฒญ๋ ๋ ธ๊ฐ๋ค๊ฐ ๋์ ์ด๋ฃจ์ด์ง๊ณ ์๋ค.
- Has-A ๊ด๊ณ๋ฅผ ํํํ ์ ์๊ฒ ๋์๋ค. ๊ฐ์ฒด ๋ด๋ถ์ ๊ฐ์ฒด๋ JPA๊ฐ ์ฒ๋ฆฌํด์ค ์ ์๊ฒ ๋์๋ค.
```java
member.setTeam(team);
jpa.persist(member);
Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();
- ์ํฐํฐ์ ์ ๋ขฐ์ฑ์ด ์๊ฒผ๋ค.
```java
String memberId = "100";
Member member1 = jpa.find(Member.class, memberId);
Member member2 = jpa.find(Member.class, memberId);
member1 == member2; //๊ฐ๋ค.
JPA์์ ์๊ธด ์ถ๊ฐ์ ์ธ ์ฅ์
- 1์ฐจ ์บ์์ ๋์ผ์ฑ(identity) ๋ณด์ฅ
- ํธ๋์ญ์ ์ ์ง์ํ๋ ์ฐ๊ธฐ ์ง์ฐ(transactional write-behind)
- ์ง์ฐ ๋ก๋ฉ(Lazy Loading)
JPA๋ฅผ ์ค์ ๋ก ์ฌ์ฉํด๋ณด์
Dialect(๋ฐฉ์ธ)
- ์ธํ (persistence.xml)์ ํ์ํ๋ค. ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ง๋ค ๋น์ทํ๋ฏ ๋ค๋ฅธ SQL ๋ฌธ๋ฒ์ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก ์ค์ ํด์ฃผ๊ฒ ๋๋ฉด ์์์ ํ์ด๋ฒ๋ค์ดํธ๊ฐ ๋ฒ์ญํด์ค๋ค.
- ํ์ด๋ฒ๋ค์ดํธ๋ ๋๋ถ๋ถ์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ชจ๋ ์ง์ํด์ค๋ค.
H2 : org.hibernate.dialect.H2Dialect Oracle 10g : org.hibernate.dialect.Oracle10gDialect MySQL : org.hibernate.dialect.MySQL5InnoDBDialect
๊ตฌ๋๋ฐฉ์
- ์ํฐํฐ ๋งค๋์ ํฉํ ๋ฆฌ๋ ํ๋๋ง ์์ฑํด์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด์ ์ ๊ณต์
- ์ํฐํฐ ๋งค๋์ ๋ ์ฐ๋ ๋๊ฐ์ ๊ณต์ X (์ฌ์ฉํ๊ณ ๋ฒ๋ ค์ผ ํ๋ค).
=> ์ ๋๊ฐ๋ Bean์ ํน์ฑ์ด๊ธฐ๋ ํ๋ค. - JPA์ ๋ชจ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ํธ๋์ญ์ ์์์ ์คํ
JPA๋ก ๋ชจ๋ ๋ค ํํํ ์ ์๋๊ฐ?
- ์๋ ๊ฑด ์์ง๋ง ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ํํํ๊ธฐ ์ํด์๋ ๋ค๋ฅธ ๊ธฐ์ ๋ค์ด ํ์ํ๋ค.
- JPQL : SQL๊ณผ ์ ์ฌํ์ง๋ง ํ ์ด๋ธ์ด ์๋ ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ๋์์ผ๋ก ์ฟผ๋ฆฌ๋ฌธ์ ์์ฑํ ์ ์๋ค. ๋ค์ ์์ฝ์ง๋ง ๊ทธ๋๋ ์ SQL๋ณด๋ค ๋ง์ ์ด์ ์ด ์๋ค.
- QueryDSL : ์์ฃผ ๋ณต์กํ ์ฟผ๋ฆฌ๋ ์๋ฐ ์ฝ๋๋ก ํํํ ์ ์๋ค.