[Spring/Database] Spring JPA์ Spring Data JPA
โ ๐๏ธ Fairy-Tale Island ๐๏ธ ๋ฆฌํฉํ ๋ง!
Spring Database ์ ๊ทผ ๋ฐฉ์
Spring์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ๋ ๋ฐฉ์๋ค์ ์์๋ณธ๋ค. ORM ์ด์ ์ ์ ๊ทผ ๋ฐฉ๋ฒ๋ค๊ณผ ๋จ์ ์ ์์๋ณด๊ณ , ์ด๋ฅผ ๋ณด์ํ๊ธฐ ์ํด ๋ฑ์ฅํ ORM์ ๊ฐ๋ ๊ณผ Spring์์ ์ฌ์ฉํ๋ Java ORM ๊ธฐ์ ์ ์์๋ณธ๋ค.
#1 [Database] ORM ์ ์, ๋ฑ์ฅ ๋ฐฐ๊ฒฝ, ์ฅ๋จ์
#2 [Spring/Database] JDBC์ JDBCTemplate
#3 [NOW] [Spring/Database] Spring JPA์ Spring Data JPA
#4 ์ ์ฒด ์ฝ๋ ์ ์ฅ์ : Various way of Spring Database Access
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ทผ : Spring JPA
JPA(Java Persistence API)๋ Java ORM ๊ธฐ์ ์ ๋ํ API ํ์ค ๋ช ์ธ ์ธํฐํ์ด์ค์ด๋ค. ์ ์์์ ์ ์ ์๋ฏ์ด, ํน์ ๊ธฐ๋ฅ์ ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋๋ผ, ์ธํฐํ์ด์ค์ด๋ค. ๋จ์ํ Java ์ ํ๋ฆฌ์ผ์ด์ ์์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ๋ ๋ฐฉ๋ฒ์ ์ ์ํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, ๊ตฌํ์ด ์๋๋ค. Hibernate์ ๊ฐ์ ORM ํ๋ ์์ํฌ์์ ์ด์ฉ ๊ฐ๋ฅํ ๊ณตํต API๋ฅผ ์ ๊ณตํ๋ค.
Java์์ ์ธํฐํ์ด์ค : ๊ตฌํ์ฒด ๊ด๊ณ์ฒ๋ผ, JPA : Hibernate๋ ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด ๊ด๊ณ๋ผ๊ณ ํ ์ ์๋ค. Java ORM ๊ธฐ์ ์ ๋ํ ๋ช ์ธ๋ฅผ ํ์ผ๋ฏ๋ก, ORM์ ์ฅ์ ์ ๊ฐ์ง๊ณ ์๋ค. ์ฆ, Hibernate๊ฐ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด Java์์ Entity์ attribute๋ฅผ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค Table์ Column๊ณผ ๋งคํ์ ์ง์ํ๊ธฐ ๋๋ฌธ์, ๊ฐ๋ฐ์๊ฐ ์ผ์ผ์ด ๋งคํ์ ์ํด SQL๋ฌธ์ ์์ฑํ ํ์๊ฐ ์๋ค.
Spring JPA ์ฌ์ฉ ๋ฐฉ๋ฒ
build.gradle์ ์์กด์ฑ์ ์ถ๊ฐํ๋ค.
1
2
3
4
5
6
7
dependencies {
...
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
...
}
Spring JPA๋ EntityManager ๊ฐ์ฒด๋ฅผ ์ด์ฉํ๋ค. EntityManger๋ JPA์์ ์ ์๋ ์ธํฐํ์ด์ค์ ์ผ๋ถ์ด๊ณ , ๋ช
์์ ์ผ๋ก Java์ ๋ฑ๋ก๋ ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ ๋ฐ์ดํฐ์ ๋งคํํ๋ค. JpaMemberRepository์์ EntityManager ๊ฐ์ฒด๋ฅผ ์์ฑ์์ ์ฃผ์
๋ฐ์ ์ฌ์ฉํ ์ ์๋ค.
๋ช
์์ ์ผ๋ก ๊ฐ์ฒด๋ฅผ ๋ฑ๋กํ๋ ค๋ฉด, ๋๋ฉ์ธ์ @Entity ์ด๋
ธํ
์ด์
์ ๋ฌ์์ค๋ค. EntityManager๋ @Entity ์ด๋
ธํ
์ด์
์ ๊ฐ์ง๊ณ ์๋ ๊ฐ์ฒด๋ค์ ๊ด๋ฆฌํ๊ณ , ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ
์ด๋ธ๊ณผ ๋งคํํ์ฌ ๋ฐ์ดํฐ๋ฅผ Create / Update / Save ํ๋ ๊ธฐ๋ฅ๋ค์ ์ํํ๋ค.
(์ฌ๊ธฐ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ๋ ๋ค์ํ ๋ฐฉ๋ฒ๋ค์ ์๊ฐํ๋๋ฐ ์ค์ ์ ๋๋ฏ๋ก, Spring JPA์ EntityManager์ ๋ํด์๋ ๋ค๋ฅธ ๊ธ์์ ์์ธํ ๋ค๋ฃจ๊ฒ ๋ค.)
1
2
3
4
5
6
7
8
9
10
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
...
}
์์ ์์ JDBC, JDBCTemplate์์๋ ์ฝ๋๊ฐ ๋๋ฌด ๊ธธ์ด ๋ฉ์๋ ํ๋, ๋ ๊ฐ๋ง ์ฒจ๋ถํ์๋ค. ํ์ง๋ง Spring JPA ์ฌ์ฉํ๋ฉด, ๋ค ๊ฐ ๋ฉ์๋ ์ฝ๋๋ฅผ ์ ๋ถ ์ฒจ๋ถํ ์ ์์ ์ ๋๋ก ์ฝ๋๊ฐ ๊ฐ๊ฒฐํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class JpaMemberRepository implements MemberRepository {
private final EntityManager em;
public JpaMemberRepository(EntityManager em) {
this.em = em;
}
public Member save(Member member) {
em.persist(member);
return member;
}
public Optional<Member> findById(Long id) {
Member member = em.find(Member.class, id);
return Optional.ofNullable(member);
}
public List<Member> findAll() {
return em.createQuery("select m from Member m", Member.class).getResultList();
}
public Optional<Member> findByName(String name) {
List<Member> result = em.createQuery("select m from Member m where m.name = :name", Member.class)
.setParameter("name", name)
.getResultList();
return result.stream().findAny();
}
}
์ด์ JDBCTemplate์์๋ ๋ฐ๋ณต์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์ฝ๋๋ฅผ ์์ฑํ์ง ์์๋ ๋์์ง๋ง, SQL๋ฌธ์ ์ง์ ์์ฑํด์ผ ํ๋ค. Spring JPA์์๋ SQL๋ฌธ๋ ์๋์ผ๋ก ์์ฑํ๋ค. ํ์ง๋ง findAll, findByName์ ๋ณด๋ฉด ์ ์ ์๋ฏ์ด, ๋ชจ๋ ๊ฒ์ JPA๋ก ์ฒ๋ฆฌํ ์ ์๋ ๊ฒ์ ์๋๋ค.
๊ฐ๋ฐ์ ํ๋ค๋ณด๋ฉด JPA์ Query Method ๋ง์ผ๋ก๋ ์กฐํ๊ฐ ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ๊ฐ ์กด์ฌํ๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ JPQL(Java Persistence Query Language)๋ฅผ ์ด์ฉํ ์ ์๋ค.
(EntityManager์ createQuery๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ ์ธ ๋ค์ํ ๋ฐฉ๋ฒ์ด ์กด์ฌํ๋๋ฐ, ์ด๋ ๋ค๋ฅธ ๊ธ์์ ์์ธํ ์๊ฐํ๋๋ก ํ๊ฒ ๋ค.)
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ทผ : Spring Data JPA
Spring Data JPA ์ฌ์ฉ ๋ฐฉ๋ฒ
Spring JPA์ ๊ฐ์ ํ๊ฒฝ์ค์ ์ด๋ค. build.gradle์ ๊ทธ๋๋ก ์ฌ์ฉํ๋ค.
์์ Spring JPA๋ง ์ฌ์ฉํด๋ SQL๋ฌธ์ ์ง์ ์์ฑํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋งค์ฐ ์ค์ด๋ค๊ณ , ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ๋ ์๋์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋น์ฆ๋์ค ๋ก์ง ๊ฐ๋ฐ์ ์ง์คํ ์ ์์๋ค. ์ฌ๊ธฐ์ ์ถ๊ฐ์ ์ผ๋ก Spring Data JPA๋ฅผ ์ฌ์ฉํ๋ฉด, ๊ตฌํ์ฒด ์์ด ์ธํฐํ์ด์ค๋ง์ผ๋ก ๊ฐ๋ฐ์ ์๋ฃํ ์ ์๋ค!
์๋ ์ฝ๋๊ฐ ์ ๋ง ๊ตฌํ์ ์ ๋ถ์ด๋ค!!
1
2
3
4
5
public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository {
Optional<Member> findByName(String name);
}
Spring Data JPA๋ ์ด๋ป๊ฒ ์ธํฐํ์ด์ค๋ง์ผ๋ก ๊ฐ๋ฐ์ ์๋ฃํ ์ ์๋ ๊ฒ์ผ๊น? ์๋ ๊ทธ๋ฆผ์ 4๊ฐ์ง ์์๋ ๋ชจ๋ ์ธํฐํ์ด์ค์ด๋ค. JpaRepository ์ธํฐํ์ด์ค๋ ์คํ๋ง ๋ฐ์ดํฐ JPA์์, PagingAndSortingReposiroty / CrudRepository / Repository ์ธํฐํ์ด์ค๋ ์คํ๋ง ๋ฐ์ดํฐ์์ ์ ๊ณตํ๋ค. ๊ฐ์ฅ ์๋์ JpaRepository์์ ์ ๊ณตํ๋ ์ธํฐํ์ด์ค๊ฐ ์กด์ฌํ๋ฏ๋ก, ์ด๋ฅผ ์ด์ฉํด ์ง์ผ ํ ์ฝ๋๋ฅผ ํ ์ค์ผ ์ ์๋ค.
Spring์ผ๋ก ๊ฐ๋ฐํ๋ฉด์ ์์ Spring JPA์์ ๋ฑ์ฅํ EntityManager๋ฅผ ์ง์ ๋ค๋ฃจ์ง ์์์๋ค. ๋ถ๋ช
ORM์ผ๋ก JPA๋ฅผ ์ฌ์ฉํ๊ณ ์์๋๋ฐ, ์ง์ ๋ค๋ฃฐ ์ผ์ด ์ ์์๊น ์๊ฐํด๋ณด๋, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ๋ ์ํฉ์์ Repository๋ฅผ ์ ์ํด์ ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ด๋ค!
Spring Data JPA๋ JPA์ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํด ๊ฐ๋ฐ์ ๊ฐํธํ๊ฒ ๋ง๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ/ํ๋ ์์ํฌ์ด๋ค. ์ด๋ Repository ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํจ์ผ๋ก์จ ์ด๋ฃจ์ด์ง๋ค! Spring Data Jpa๊ฐ ๊ถ๊ทน์ ์ผ๋ก ์ ๊ณตํ๋, ๊ฐ์ฅ ์ ๋จ์ Repository ์ธํฐํ์ด์ค๋ฅผ ์ด์ฉํจ์ผ๋ก์จ JPA ๊ธฐ๋ฐ ์ ํ๋ฆฌ์ผ์ด์
๊ฐ๋ฐ์ ๊ฐํธํ๊ฒ ํ ์ ์์๋ ๊ฒ์ด๋ค.
๊ฐ๋ฐํ๋ฉด์ Repository ์ธํฐํ์ด์ค์ ์ ์๋ ๋๋ก ์ฝ๋๋ฅผ ์ง๋ฉด, Spring์ด ์์์ ๋ฉ์๋ ์ด๋ฆ์ ์ ํฉํ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋ด๋ ๊ตฌํ์ฒด๋ฅผ ๋ง๋ค์ด์ Bean์ผ๋ก ๋ฑ๋กํ๋ค. ๊ทธ๋ฆผ์์ Repository ์ธํฐํ์ด์ค์ JpaRepository ์ธํฐํ์ด์ค ์ฌ์ด์ ์๋ ์ธํฐํ์ด์ค๋ค์ ํตํด์ CRUD ์ฐ์ฐ, ํ์ด์ง, ์ ๋ ฌ์ ์ฝ๊ฒ ํ ์ ์๊ณ , ์ฝ๋์ ์์ ํ๊ธฐ์ ์ผ๋ก ์ค์ผ ์ ์๋ค.
