Spring Data JPA

0taetaeยท2025๋…„ 1์›” 19์ผ
post-thumbnail

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 ์ธํ„ฐํŽ˜์ด์Šค์— ์ฟผ๋ฆฌ ์ง์ ‘ ์ •์˜

โœ๏ธ๋ฉ”์†Œ๋“œ ์ด๋ฆ„์œผ๋กœ ์ฟผ๋ฆฌ ์ƒ์„ฑ

  • ์ธํ„ฐํŽ˜์ด์Šค์— ์ •์˜ํ•œ ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด Spring Data JPA๋Š” ๋ฉ”์†Œ๋“œ ์ด๋ฆ„์„ ๋ถ„์„ํ•ด์„œ JPQL์„ ์ƒ์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•œ๋‹ค.
    -> ์ •ํ•ด์ง„ ๊ทœ์น™์— ๋”ฐ๋ผ์„œ ๋ฉ”์†Œ๋“œ ์ด๋ฆ„์„ ์ง€์–ด์•ผ ํ•œ๋‹ค.

  • ๊ทœ์น™

    KeywordSampleJPQL snippet
    AndfindByLastnameAndFirstnameโ€ฆ where x.lastname = ?1 and x.firstname = ?2
    OrfindByLastnameOrFirstnameโ€ฆ where x.lastname = ?1 or x.firstname = ?2
    Is,EqualsfindByFirstname,findByFirstnameIs,findByFirstnameEqualsโ€ฆ where x.firstname = 1?
    BetweenfindByStartDateBetweenโ€ฆ where x.startDate between 1? and ?2
    LessThanfindByAgeLessThanโ€ฆ where x.age < ?1
    LessThanEqualfindByAgeLessThanEqualโ€ฆ where x.age โ‡ ?1
    GreaterThanfindByAgeGreaterThanโ€ฆ where x.age > ?1
    GreaterThanEqualfindByAgeGreaterThanEqualโ€ฆ where x.age >= ?1
    AfterfindByStartDateAfterโ€ฆ where x.startDate > ?1
    BeforefindByStartDateBeforeโ€ฆ where x.startDate < ?1
    IsNullfindByAgeIsNullโ€ฆ where x.age is null
    IsNotNull,NotNullfindByAge(Is)NotNullโ€ฆ where x.age not null
    LikefindByFirstnameLikeโ€ฆ where x.firstname like ?1
    NotLikefindByFirstnameNotLikeโ€ฆ where x.firstname not like ?1
    StartingWithfindByFirstnameStartingWithโ€ฆ where x.firstname like ?1 (parameter bound with appended %)
    EndingWithfindByFirstnameEndingWithโ€ฆ where x.firstname like ?1 (parameter bound with prepended %)
    ContainingfindByFirstnameContainingโ€ฆ where x.firstname like ?1 (parameter bound wrapped in %)
    OrderByfindByAgeOrderByLastnameDescโ€ฆ where x.age = ?1 order by x.lastname desc
    NotfindByLastnameNotโ€ฆ where x.lastname <> ?1
    InfindByAgeIn(Collection< Age > ages)โ€ฆ where x.age in ?1
    NotInfindByAgeNotIn(Collection< Age > age)โ€ฆ where x.age not in ?1
    TruefindByActiveTrue()โ€ฆ where x.active = true
    FalsefindByActiveFalse()โ€ฆ where x.active = false
    IgnoreCasefindByFirstnameIgnoreCaseโ€ฆ where UPPER(x.firstame) = UPPER(?1)

โœ๏ธ๋ฉ”์†Œ๋“œ ์ด๋ฆ„์œผ๋กœ 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๋Š” ์œ ์—ฐํ•œ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์ง€์›ํ•œ๋‹ค.

  • ๊ฒฐ๊ณผ๊ฐ€ ํ•œ ๊ฑด ์ด์ƒ์ด๋ฉด ์ปฌ๋ ‰์…˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
    List<Member> findByName(String name);
  • ๊ฒฐ๊ณผ๊ฐ€ ๋‹จ๊ฑด์ด๋ฉด ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์ง€์ •ํ•œ๋‹ค.
    Member findByEmail(String email);

โœ๏ธํŽ˜์ด์ง•๊ณผ ์ •๋ ฌ

  1. ์ •๋ ฌ ๊ธฐ๋Šฅ
    • org.springframework.data.domain.Sort
  2. ํŽ˜์ด์ง• ๊ธฐ๋Šฅ
    • 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 ๊ตฌํ˜„

  1. ์‚ฌ์šฉ์ž ์ •์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ž‘์„ฑ
  2. ์‚ฌ์šฉ์ž ์ •์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•  ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑ
    • ํด๋ž˜์Šค ์ด๋ฆ„
      • 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๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ฐพ๋Š”๋‹ค.

โœ๏ธํŽ˜์ด์ง•๊ณผ ์ •๋ ฌ ๊ธฐ๋Šฅ

  1. ํŽ˜์ด์ง• ๊ธฐ๋Šฅ
    • PageableHandlerMethodArgumentResolver
    • ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ
      • page : ํ˜„์žฌ ํŽ˜์ด์ง€, 0๋ถ€ํ„ฐ ์‹œ์ž‘
      • size : ํ•œ ํŽ˜์ด์ง€์— ๋…ธ์ถœํ•  ๋ฐ์ดํ„ฐ ๊ฑด์ˆ˜
      • sort : ์ •๋ ฌ ์กฐ๊ฑด์„ ์ •์˜ (ASC | DESC)
    • ์‚ฌ์šฉํ•ด์•ผ ํ•  ํŽ˜์ด์ง• ์ •๋ณด๊ฐ€ ๋‘˜ ์ด์ƒ์ด๋ฉด ์ ‘๋‘์‚ฌ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.
      • @Qualifier ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
      • " {์ ‘๋‘์‚ฌ๋ช…}_"๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.
    • Pageable์˜ ๊ธฐ๋ณธ๊ฐ’์€ page=0, size=20์ด๋‹ค.
      • @PageableDefault ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ๋ณธ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ์ •๋ ฌ ๊ธฐ๋Šฅ
    • 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

ํ•ญ๋ชฉJPASpring Data JPA
์—ญํ• ORM ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค ์ œ๊ณต.JPA๋ฅผ ์ถ”์ƒํ™”ํ•˜์—ฌ ๋” ํŽธ๋ฆฌํ•œ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๋ฐ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ ์ œ๊ณต.
์„ค์ •JPA ๊ตฌํ˜„์ฒด(Hibernate ๋“ฑ)๋ฅผ ์ง์ ‘ ์„ค์ •ํ•ด์•ผ ํ•จ.Spring Boot์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ ์‹œ, ์„ค์ •์ด ๊ฐ„๋‹จํ•˜๊ณ  ์ž๋™ํ™”๋จ.
์‚ฌ์šฉ ๋ฐฉ์‹EntityManager๋ฅผ ์ง์ ‘ ์‚ฌ์šฉ.JpaRepository ๋“ฑ์˜ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค.
์ปค์Šคํ…€ ์ฟผ๋ฆฌJPQL ๋˜๋Š” Native Query ์ž‘์„ฑ ํ•„์š”.๋ฉ”์„œ๋“œ ์ด๋ฆ„ ๊ธฐ๋ฐ˜ ์ฟผ๋ฆฌ ์ƒ์„ฑ, @Query๋กœ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ปค์Šคํ…€ ์ฟผ๋ฆฌ ์ž‘์„ฑ ๊ฐ€๋Šฅ.
ํ•™์Šต ๊ณก์„ ์ƒ๋Œ€์ ์œผ๋กœ ๋†’์Œ.์ดˆ๋ณด์ž๋„ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.
์ƒ์‚ฐ์„ฑ๊ธฐ๋ณธ์ ์ธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์ฝ”๋“œ ์ž‘์„ฑ์— ์‹œ๊ฐ„ ์†Œ์š”.๊ธฐ๋ณธ์ ์ธ CRUD ๊ธฐ๋Šฅ ์ž๋™ ์ œ๊ณต์œผ๋กœ ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ.

0๊ฐœ์˜ ๋Œ“๊ธ€