๐ŸŒฟSpring/Spring Data JPA

[Spring JPA] JPA๋ž€?

Boom's 2024. 1. 22. 12:20
๋ฐ˜์‘ํ˜•

 

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” JPA(Java Persistence API)์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

JPA๋Š” ์ž๋ฐ” ์ง„์˜์—์„œ ORM(Object-Relational Mapping) ๊ธฐ์ˆ  ํ‘œ์ค€์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค ๋ชจ์Œ์ด๋‹ค.

๊ทธ ๋ง์€ ์ฆ‰, ์‹ค์ œ์ ์œผ๋กœ ๊ตฌํ˜„ ๋œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ตฌํ˜„๋œ ํด๋ž˜์Šค์™€ ๋งคํ•‘์„ ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ

JPA๋ฅผ ๊ตฌํ˜„ํ•œ ๋Œ€ํ‘œ์ ์ธ ์˜คํ”ˆ์†Œ์Šค๋กœ๋Š” Hibernate๊ฐ€ ์žˆ๋‹ค.


 

JPA(Java Persistence API) ๋ž€?

  • Java ์ง„์˜์—์„œ ORM(Object-Relational Mapping) ๊ธฐ์ˆ  ํ‘œ์ค€์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค ๋ชจ์Œ
  • ์ž๋ฐ” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์„ ์ •์˜ํ•œ ์ธํ„ฐํŽ˜์ด์Šค
  • ์ธํ„ฐํŽ˜์ด์Šค ์ด๊ธฐ ๋•Œ๋ฌธ์— Hibernate, OpenJPA ๋“ฑ์ด JPA๋ฅผ ๊ตฌํ˜„ํ•จ

์žฅ์ 

  1. ๊ฐ„ํŽธํ•œ CRUD ์ž‘์—…
    • Spring Data JPA๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ CRUD ์ž‘์—…์„ ์ •์˜ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค. Repository ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ๊ฐ„๋‹จํ•œ ๋ฉ”์„œ๋“œ ์„ ์–ธ๋งŒ์œผ๋กœ๋„ ๊ธฐ๋ณธ์ ์ธ CRUD ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ์ฟผ๋ฆฌ ๋ฉ”์„œ๋“œ
    • Spring Data JPA๋Š” ๋ฉ”์„œ๋“œ ์ด๋ฆ„์„ ํ†ตํ•œ ์ฟผ๋ฆฌ ์ƒ์„ฑ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ ์ด๋ฆ„๋งŒ์œผ๋กœ๋„ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์–ด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ SQL์„ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
  3. ์ž๋™ํ™”๋œ JPA ๊ตฌํ˜„
    • Spring Data JPA๋Š” Repository ์ธํ„ฐํŽ˜์ด์Šค์— ๋Œ€ํ•œ ๊ตฌํ˜„์ฒด๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž๋Š” ๋ณ„๋„์˜ ๊ตฌํ˜„ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
  4. ํŽ˜์ด์ง€๋„ค์ด์…˜ ๋ฐ ์ •๋ ฌ
    • Spring Data JPA๋Š” ํŽ˜์ด์ง•๊ณผ ์ •๋ ฌ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜์—ฌ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  5. ์œ ์—ฐ์„ฑ
    • JPA ๊ธฐ๋ฐ˜์˜ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ง€์›ํ•˜๋ฉฐ, ๊ฐœ๋ฐœ์ž๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹จ์ 

  1. ๋ณต์žกํ•œ ์ฟผ๋ฆฌ ์ฒ˜๋ฆฌ
    • ๊ฐ„๋‹จํ•œ ์ฟผ๋ฆฌ๋Š” ๋ฉ”์„œ๋“œ ์ด๋ฆ„๋งŒ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋‚˜ ํŠน์ • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ข…์†์ ์ธ ์ฟผ๋ฆฌ์˜ ๊ฒฝ์šฐ JPA Query Language (JPQL)์ด๋‚˜ Native Query๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.
  2. ์„ฑ๋Šฅ ์˜ค๋ฒ„ํ—ค๋“œ
    • ์ผ๋ถ€ ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋‚˜ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ๋Š” ์„ฑ๋Šฅ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํŠœ๋‹ํ•˜์ง€ ์•Š์œผ๋ฉด N+1 ๋ฌธ์ œ ๋“ฑ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
  3. ํ•™์Šต ๊ณก์„ 
    • JPA ๋ฐ Spring Data JPA๋Š” ์ฒ˜์Œ์—๋Š” ํ•™์Šต ๊ณก์„ ์ด ์กด์žฌ
    • ํŠนํžˆ, ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์ด๋‚˜ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์ถ”๊ฐ€์ ์ธ ํ•™์Šต์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ๋‹ค.
  4. ๋™์  ์ฟผ๋ฆฌ ์ž‘์„ฑ์˜ ์–ด๋ ค์›€
    • ๋™์ ์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” JPQL์ด๋‚˜ Criteria API๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ, ์ด๋Š” ํ•™์Šต์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„

 

Spring Data JPA์˜ ํ•ต์‹ฌ ๊ฐœ๋…

Repository

  • Spring Data ์ €์žฅ์†Œ ์ถ”์ƒํ™”์˜ ์ค‘์•™ ์ธํ„ฐํŽ˜์ด์Šค
  • ๊ด€๋ฆฌํ•  ๋„๋ฉ”์ธ ํด๋ž˜์Šค์™€ ๋„๋ฉ”์ธ ํด๋ž˜์Šค์˜ ์‹๋ณ„์ž ์œ ํ˜•์„ ์œ ํ˜• ์ธ์ˆ˜๋กœ ์‚ฌ์šฉ
  • ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ฃผ๋กœ ์ž‘์—…ํ•  ์œ ํ˜•์„ ์บก์ฒ˜ํ•˜๊ณ  ์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™•์žฅํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ๋งˆ์ปค ์ธํ„ฐํŽ˜์ด์Šค ์—ญํ• 
  • ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ด€๋ฆฌ๋˜๋Š” ์—”ํ„ฐํ‹ฐ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์ •๊ตํ•œ CRUD ๊ธฐ๋Šฅ์„ ์ œ๊ณต

CrudRepository ์ƒํ˜ธ์ž‘์šฉ

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
    <S extends T> S save(S entity);

    <S extends T> Iterable<S> saveAll(Iterable<S> entities);

    Optional<T> findById(ID id);

    boolean existsById(ID id);

    Iterable<T> findAll();

    Iterable<T> findAllById(Iterable<ID> ids);

    long count();

    void deleteById(ID id);

    void delete(T entity);

    void deleteAllById(Iterable<? extends ID> ids);

    void deleteAll(Iterable<? extends T> entities);

    void deleteAll();
}
  • JpaRepository Interface๋ฅผ ์ƒ์† ๋ฐ›์œผ๋ฉด ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋Š” ์ฃผ์š” ๋ฉ”์†Œ๋“œ
    • save() : ์ง€์ •๋œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ €์žฅ
    • findById() : ์ง€์ •๋œ ID๋กœ ์‹๋ณ„๋˜๋Š” ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฐ˜ํ™˜
    • findAll() : ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฐ˜ํ™˜
    • count() : ์—”ํ‹ฐํ‹ฐ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜
    • delete() : ์ง€์ •๋œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์‚ญ์ œ
    • existsById() : ์ง€์ •๋œ ID๋ฅผ ๊ฐ€์ง„ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

PagingAndSortingRepository ์ƒํ˜ธ์ž‘์šฉ

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
    Iterable<T> findAll(Sort sort);

    Page<T> findAll(Pageable pageable);
}
  • Spring Data JPA์˜ ์žฅ์ • ์ค‘ ํ•˜๋‚˜์ธ ํŽ˜์ด์ง€๋„ค์ด์…˜์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.
PagingAndSortingRepository<User, Long> repository = // … get access to a bean
Page<User> users = repository.findAll(PageRequest.of(1, 20));

 

ํŒŒ์ƒ๋œ ์ฟผ๋ฆฌ Repository 

interface UserRepository extends CrudRepository<User, Long> {

  long countByLastname(String lastname);
}

 

- Reference

https://docs.spring.io/spring-data/jpa/reference/index.html

 

Spring Data JPA :: Spring Data JPA

Oliver Gierke, Thomas Darimont, Christoph Strobl, Mark Paluch, Jay Bryant, Greg Turnquist Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that

docs.spring.io

 

๋ฐ˜์‘ํ˜•