Spring Data JPA๋ Spring ํ๋ ์์ํฌ์์ JPA๋ฅผ ํธ๋ฆฌํ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ์ง์ํ๋ ๋ชจ๋์ด๋ค.
- CRUD๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๊ณตํต ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ค.
- Repository๋ฅผ ๊ฐ๋ฐํ ๋ ์ธํฐํ์ด์ค๋ง ์์ฑํ๋ฉด ์คํ ์์ ์ Spring Data JPA๊ฐ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ๋์ ์ผ๋ก ์์ฑํด์ ์ฃผ์
ํด์ค๋ค.
-> ๋ฐ์ดํฐ ์ ๊ทผ ๊ณ์ธต์ ๊ฐ๋ฐํ ๋ ๊ตฌํ ํด๋์ค ์์ด ์ธํฐํ์ด์ค๋ง ์์ฑํด๋ ๊ฐ๋ฐ์ ์๋ฃํ ์ ์๋ค.
๐Spring Data JPA ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์ ๋ฐ ํ๊ฒฝ์ค์
-
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa></artifactId>
<version>1.8.0.RELEASE</version>
</dependency>
-
XML ์ค์
<beans>
...
<jpa:repositories base-package="..."/>
</beans>
-
JavaConfig ์ค์
@Configuration
@EnableJpaRepositories(basePackages ="...")
public class AppConfig{
}
โ๏ธ๊ณตํต ์ธํฐํ์ด์ค ๊ธฐ๋ฅ
Spring Data JPA๋ ๊ฐ๋จํ CRUD ๊ธฐ๋ฅ์ ๊ณตํต์ผ๋ก ์ฒ๋ฆฌํ๋ JpaRepository ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ค.
์ด ์ธํฐํ์ด์ค๋ฅผ ์์ ๋ฐ๊ณ , ์ ๋ค๋ฆญ์ ์ํฐํฐ ํด๋์ค์ ์ํฐํฐ ํด๋์ค๊ฐ ์ฌ์ฉํ๋ ์๋ณ์ ํ์
์ ์ง์ ํ๋ฉด ๋๋ค.
JpaRepository ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ผ๋ฉด ์ฌ์ฉํ ์ ์๋ ์ฃผ์ ๋ฉ์๋๋ฅผ ์์๋ณด์.
- save(S) : ์๋ก์ด ์ํฐํฐ๋ ์ ์ฅํ๊ณ ์ด๋ฏธ ์๋ ์ํฐํฐ๋ ์์ ํ๋ค.
- ์ํฐํฐ์ ์๋ณ์ ๊ฐ์ด ์์ผ๋ฉด ์๋ก์ด ์ํฐํฐ๋ก ๋ฐ๋จํด์ EntityManager.persist()๋ฅผ ํธ์ถํ๋ค.
- ์๋ณ์ ๊ฐ์ด ์์ผ๋ฉด ์ด๋ฏธ ์๋ ์ํฐํฐ๋ก ํ๋จํด์ EntityManager.merge()๋ฅผ ํธ์ถํ๋ค.
- delete(T) : ์ํฐํฐ ํ๋๋ฅผ ์ญ์ ํ๋ค.
- ๋ด๋ถ์์ EntityManager.remove()๋ฅผ ํธ์ถํ๋ค.
- findOne(ID) : ์ํฐํฐ ํ๋๋ฅผ ์กฐํํ๋ค.
- ๋ด๋ถ์์ EntityManager.find()๋ฅผ ํธ์ถํ๋ค.
- getOne(ID) : ์ํฐํฐ๋ฅผ ํ๋ก์๋ก ์กฐํํ๋ค.
- ๋ด๋ถ์์ EntityManager.getReference()๋ฅผ ํธ์ถํ๋ค.
- findAll(..) : ๋ชจ๋ ์ํฐํฐ๋ฅผ ์กฐํํ๋ค.
- ์ ๋ ฌ์ด๋ ํ์ด์ง ์กฐ๊ฑด์ ํ๋ผ๋ฏธํฐ๋ก ์ ๊ณตํ ์ ์๋ค.
๐์ฟผ๋ฆฌ ๋ฉ์๋ ๊ธฐ๋ฅ
Spring Data JPA๊ฐ ์ ๊ณตํ๋ ์ฟผ๋ฆฌ ๋ฉ์๋ ๊ธฐ๋ฅ์ ํฌ๊ฒ 3๊ฐ์ง๊ฐ ์๋ค.
1. ๋ฉ์๋ ์ด๋ฆ์ผ๋ก ์ฟผ๋ฆฌ ์์ฑ
2. ๋ฉ์๋ ์ด๋ฆ์ผ๋ก JPA NamedQuery ํธ์ถ
3. @Query ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํด์ Repository ์ธํฐํ์ด์ค์ ์ฟผ๋ฆฌ ์ง์ ์ ์
โ๏ธ๋ฉ์๋ ์ด๋ฆ์ผ๋ก ์ฟผ๋ฆฌ ์์ฑ
โ๏ธ๋ฉ์๋ ์ด๋ฆ์ผ๋ก JPA NamedQuery ํธ์ถ
- ์ฟผ๋ฆฌ์ ์ด๋ฆ์ ๋ถ์ฌํด์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
- ์ ์ธํ "๋๋ฉ์ธ ํด๋์ค + .(dot) + ๋ฉ์๋ ์ด๋ฆ"์ผ๋ก Named ์ฟผ๋ฆฌ๋ฅผ ์ฐพ์์ ์คํํ๋ค.
โ๏ธ@Query ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํด์ Repository ์ธํฐํ์ด์ค์ ์ฟผ๋ฆฌ ์ง์ ์ ์
- ์คํํ ๋ฉ์๋์ ์ ์ ์ฟผ๋ฆฌ๋ฅผ ์ง์ ์์ฑํ๋ฏ๋ก ์ด๋ฆ ์๋ Named ์ฟผ๋ฆฌ๋ผ ํ ์ ์๋ค.
- JPA Named ์ฟผ๋ฆฌ์ฒ๋ผ ์ ํ๋ฆฌ์ผ์ด์
์คํ ์์ ์ ๋ฌธ๋ฒ ์๋ฅ๋ฅผ ๋ฐ๊ฒฌํ ์ ์๋ค.
public interface MemberRepository extends JpaRepository<Member, Long> {
@Query("select m from Member m where m.username = ?1")
Member findByUsername(String username);
}
โ๏ธ ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉ
- ์์น ๊ธฐ๋ฐ ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉ๊ณผ ์ด๋ฆ ๊ธฐ๋ฐ ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉ์ ๋ชจ๋ ์ง์ํ๋ค.
- ๊ธฐ๋ณธ๊ฐ์ ์์น ๊ธฐ๋ฐ์ธ๋ฐ ํ๋ผ๋ฏธํฐ ์์๋ก ๋ฐ์ธ๋ฉํ๋ค.
- ์ด๋ฆ ๊ธฐ๋ฐ ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉ์ ์ฌ์ฉํ๋ ค๋ฉด org.springframework.data.repository.query.Param(ํ๋ผ๋ฏธํฐ ์ด๋ฆ) ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๋ฉด ๋๋ค.
โ๏ธ ๋ฒํฌ์ฑ ์์ ์ฟผ๋ฆฌ
- ๋ฒํฌ์ฑ ์์ , ์ญ์ ์ฟผ๋ฆฌ๋ org.springframework.data.jpa.repository.Modifying ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๋ฉด ๋๋ค.
- ๋ฒํฌ์ฑ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ ๋์ ์์์ฑ ์ปจํ
์คํธ๋ฅผ ์ด๊ธฐํํ๊ณ ์ถ์ผ๋ฉด @Modifying(clearAutoMatically = true)์ฒ๋ผ clearAutomatically ์ต์
์ true๋ก ์ค์ ํ๋ฉด ๋๋ค. (๊ธฐ๋ณธ๊ฐ = false)
โ๏ธ๋ฐํ ํ์
Spring Data JPS๋ ์ ์ฐํ ๋ฐํ ํ์
์ ์ง์ํ๋ค.
โ๏ธํ์ด์ง๊ณผ ์ ๋ ฌ
- ์ ๋ ฌ ๊ธฐ๋ฅ
- org.springframework.data.domain.Sort
- ํ์ด์ง ๊ธฐ๋ฅ
- org.springframework.data.domain.Pageable (๋ด๋ถ์ Sort ํฌํจ)
- ๋ฐํ ํ์
์ผ๋ก List๋ org.springframework.data.domain.Page๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
- ๋ฐํ ํ์
์ผ๋ก Page๋ฅผ ์ฌ์ฉํ๋ฉด Spring Data JPA๋ ํ์ด์ง ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ธฐ ์ํด ๊ฒ์๋ ์ ์ฒด ๋ฐ์ดํฐ ๊ฑด์๋ฅผ ์กฐํํ๋ count ์ฟผ๋ฆฌ๋ฅผ ์ถ๊ฐ๋ก ํธ์ถํ๋ค.
โ๏ธJPA ์ฟผ๋ฆฌ ํํธ
- org.springframework.data.jpa.repository.QueryHints ์ด๋
ธํ
์ด์
์ ์ฌ์ฉ
- JPA ๊ตฌํ์ฒด์๊ฒ ์ ๊ณตํ๋ ํํธ์ด๋ค.
- forCounting ์์ฑ : ๋ฐํ ํ์
์ผ๋ก Page ์ธํฐํ์ด์ค๋ฅผ ์ ์ฉํ๋ฉด ์ถ๊ฐ๋ก ํธ์ถํ๋ ํ์ด์ง์ ์ํ count ์ฟผ๋ฆฌ์๋ ์ฟผ๋ฆฌ ํํธ๋ฅผ ์ ์ฉํ ์ง๋ฅผ ์ค์ ํ๋ ์ต์
(๊ธฐ๋ณธ๊ฐ = true)
โ๏ธLock
- org.springframework.data.jpa.repository.Lock ์ด๋
ธํ
์ด์
์ ์ฌ์ฉ
๐๋ช
์ธ
- org.springframework.data.jpa.domain.Specification
- Specification
- composite ํจ์ปจ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ด์ ์ฌ๋ฌ Specification์ ์กฐํฉํ ์ ์๋ค.
-> ๋ค์ํ ๊ฒ์ ์กฐ๊ฑด์ ์กฐ๋ฆฝํด์ ์๋ก์ด ๊ฒ์์กฐ๊ฑด์ ์ฝ๊ฒ ๋ง๋ค ์ ์๋ค.
- Specifications
- ๋ช
์ธ๋ค์ ์กฐ๋ฆฝํ ์ ์๋๋ก ๋์์ฃผ๋ ํด๋์ค
- where(), and(), or(), not() ๋ฉ์๋๋ฅผ ์ ๊ณต
๐์ฌ์ฉ์ ์ ์ repository ๊ตฌํ
- ์ฌ์ฉ์ ์ ์ ์ธํฐํ์ด์ค๋ฅผ ์์ฑ
- ์ฌ์ฉ์ ์ ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ํด๋์ค๋ฅผ ์์ฑ
- ํด๋์ค ์ด๋ฆ
- repository ์ธํฐํ์ด์ค ์ด๋ฆ + Impl (default)
-> Spring Data JPA๊ฐ ์ฌ์ฉ์ ์ ์ ๊ตฌํ ํด๋์ค๋ก ์ธ์
- Impl ๋์ ๋ค๋ฅธ ์ด๋ฆ์ ๋ถ์ด๊ณ ์ถ์ ๊ฒฝ์ฐ
- repository-impl-postfix ์์ฑ์ ๋ณ๊ฒฝ
๐Web ํ์ฅ ๊ธฐ๋ฅ
Spring MVC์์ ์ฌ์ฉํ ์ ์๋ ํธ๋ฆฌํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
โ๏ธ์ค์
- Web ํ์ฅ ๊ธฐ๋ฅ์ ํ์ฑํํ๋ ค๋ฉด org.springframework.data.web.config.SpringDataWebConfiguration์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ฉด ๋๋ค.
- JavaConfig๋ฅผ ์ฌ์ฉํ๋ฉด, org.springframework.data.web.config.EnableSpringDataWebSupport ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๋ฉด ๋๋ค.
โ๏ธ๋๋ฉ์ธ ํด๋์ค ์ปจ๋ฒํฐ ๊ธฐ๋ฅ
- ๋๋ฉ์ธ ํด๋์ค ์ปจ๋ฒํฐ๋ HTTP ํ๋ผ๋ฏธํฐ๋ก ๋์ด์จ ์ํฐํฐ์ ์์ด๋๋ก ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ์ฐพ์์ ๋ฐ์ธ๋ฉํด์ค๋ค.
- ๋๋ฉ์ธ ํด๋์ค ์ปจ๋ฒํฐ๋ ํด๋น ์ํฐํฐ์ ๊ด๋ จ๋ repository๋ฅผ ์ฌ์ฉํด์ ์ํฐํฐ๋ฅผ ์ฐพ๋๋ค.
โ๏ธํ์ด์ง๊ณผ ์ ๋ ฌ ๊ธฐ๋ฅ
- ํ์ด์ง ๊ธฐ๋ฅ
- PageableHandlerMethodArgumentResolver
- ์์ฒญ ํ๋ผ๋ฏธํฐ
- page : ํ์ฌ ํ์ด์ง, 0๋ถํฐ ์์
- size : ํ ํ์ด์ง์ ๋
ธ์ถํ ๋ฐ์ดํฐ ๊ฑด์
- sort : ์ ๋ ฌ ์กฐ๊ฑด์ ์ ์ (ASC | DESC)
- ์ฌ์ฉํด์ผ ํ ํ์ด์ง ์ ๋ณด๊ฐ ๋ ์ด์์ด๋ฉด ์ ๋์ฌ๋ฅผ ์ฌ์ฉํด์ ๊ตฌ๋ถํ ์ ์๋ค.
- @Qualifier ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๋ฉด ๋๋ค.
- " {์ ๋์ฌ๋ช
}_"๋ก ๊ตฌ๋ถํ๋ค.
- Pageable์ ๊ธฐ๋ณธ๊ฐ์ page=0, size=20์ด๋ค.
- @PageableDefault ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๋ฉด ๊ธฐ๋ณธ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค.
- ์ ๋ ฌ ๊ธฐ๋ฅ
- SortHandlerMethodArgumentResolver
๐Spring Data JPA๊ฐ ์ฌ์ฉํ๋ ๊ตฌํ์ฒด
- @Repository ์ ์ฉ: JPA ์์ธ๋ฅผ Spring์ด ์ถ์ํํ ์์ธ๋ก ๋ณํํ๋ค.
- @Transactional ํธ๋์ญ์
์ฌ์ฉ
- JPA์ ๋ชจ๋ ๋ณ๊ฒฝ์ ํธ๋์ญ์
์์์ ์ด๋ฃจ์ด์ ธ์ผ ํ๋ค.
- Spring Data JPA๊ฐ ์ ๊ณตํ๋ ๊ณตํต ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๋ฉ์๋์ @Transactional๋ก ํธ๋์ญ์
์ฒ๋ฆฌ๊ฐ ๋์ด ์๋ค.
- ์๋น์ค ๊ณ์ธต์์ ํธ๋์ญ์
์ ์์ํ์ง ์์ผ๋ฉด repository์์ ํธ๋์ญ์
์ ์์ํ๋ค.
- ์๋น์ค ๊ณ์ธต์์ ํธ๋์ญ์
์ ์์ํ์ผ๋ฉด repository๋ ํด๋น ํธ๋์ญ์
์ ์ ํ๋ฐ์์ ๊ทธ๋๋ก ์ฌ์ฉํ๋ค.
- @Transactional(readOnly = true)
- ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ ๋ฉ์๋์๋ readOnly = true ์ต์
์ด ์ ์ฉ๋์ด ์๋ค.
- ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ์ง ์๋ ํธ๋์ญ์
์์ readOnly = true ์ต์
์ ์ฌ์ฉํ๋ฉด ํ๋ฌ์๋ฅผ ์๋ตํด์ ์ฝ๊ฐ์ ์ฑ๋ฅ ํฅ์์ ์ป์ ์ ์๋ค.
- save() ๋ฉ์๋
- ์ ์ฅํ ์ํฐํฐ๊ฐ ์๋ก์ด ์ํฐํฐ๋ฉด ์ ์ฅ(persist)ํ๊ณ ์ด๋ฏธ ์๋ ์ํฐํฐ๋ฉด ๋ณํฉ(merge)ํ๋ค.
๐JPA vs Spring Data JPA
| ํญ๋ชฉ | JPA | Spring Data JPA |
|---|
| ์ญํ | ORM ํ์ค ์ธํฐํ์ด์ค ์ ๊ณต. | JPA๋ฅผ ์ถ์ํํ์ฌ ๋ ํธ๋ฆฌํ ๋ฐ์ดํฐ ์ ๊ทผ ๋ฐ ๊ด๋ฆฌ ๊ธฐ๋ฅ ์ ๊ณต. |
| ์ค์ | JPA ๊ตฌํ์ฒด(Hibernate ๋ฑ)๋ฅผ ์ง์ ์ค์ ํด์ผ ํจ. | Spring Boot์ ํจ๊ป ์ฌ์ฉ ์, ์ค์ ์ด ๊ฐ๋จํ๊ณ ์๋ํ๋จ. |
| ์ฌ์ฉ ๋ฐฉ์ | EntityManager๋ฅผ ์ง์ ์ฌ์ฉ. | JpaRepository ๋ฑ์ ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ํตํด ๋ฐ์ดํฐ ์ก์ธ์ค. |
| ์ปค์คํ
์ฟผ๋ฆฌ | JPQL ๋๋ Native Query ์์ฑ ํ์. | ๋ฉ์๋ ์ด๋ฆ ๊ธฐ๋ฐ ์ฟผ๋ฆฌ ์์ฑ, @Query๋ก ๊ฐํธํ๊ฒ ์ปค์คํ
์ฟผ๋ฆฌ ์์ฑ ๊ฐ๋ฅ. |
| ํ์ต ๊ณก์ | ์๋์ ์ผ๋ก ๋์. | ์ด๋ณด์๋ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์. |
| ์์ฐ์ฑ | ๊ธฐ๋ณธ์ ์ธ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ฝ๋ ์์ฑ์ ์๊ฐ ์์. | ๊ธฐ๋ณธ์ ์ธ CRUD ๊ธฐ๋ฅ ์๋ ์ ๊ณต์ผ๋ก ๊ฐ๋ฐ ์์ฐ์ฑ ํฅ์. |