[Spring] JPA์™€ Spring Data JPA ์ฐจ์ด

๐Ÿ“ ์ด ๊ธ€์€ CS ์Šคํ„ฐ๋””๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ ๊ฐœ์ธ์ ์œผ๋กœ ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.
ํ‹€๋ฆฐ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์„ธ์š”. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.๐Ÿ™‡‍โ™€๏ธ๐ŸŒŸ

 

๐ŸŽˆJPA (Java Persistence API)

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

ํ•ต์‹ฌ ์ธํ„ฐํŽ˜์ด์Šค์ธ EntityManager ๋“ฑ์„ ํฌํ•จํ•˜๋Š” javax.persistence ํŒจํ‚ค์ง€๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๋™์ด ์ด๋ฃจ์–ด์ง„๋‹ค. JPA์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์€ ORM ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐ„ ํ˜ธํ™˜์„ฑ๊ณผ ์ด์‹์„ฑ์„ ๋†’์—ฌ, ๊ตฌํ˜„์ฒด๋ฅผ ์‰ฝ๊ฒŒ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.

 

JPA๋Š” ์˜์†์„ฑ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด EntityManager์™€ EntityManagerFactory์— ์˜์กดํ•œ๋‹ค.

EntityManager๋Š” ์—”ํ‹ฐํ‹ฐ์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์ด๋ฅผ SQL ์ฟผ๋ฆฌ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” Persistence Context๋กœ ์ž‘๋™ํ•œ๋‹ค. 

 

EntityManager์˜ ์ฃผ์š” ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

/*
* Returns an entity by its primary key.
*/
public <T> T find(Class<T> entityClass, Object primaryKey);
 
/*
* Creates a new transient entity that will be inserted in the databse during
* the next flush()
*/
public void persist(Object entity);
 
/*
* Transforms a detached entity (an entity that was managed by a Persistence
* Context at some point) into a transient one 
*/
public <T> T merge(T entity);
 
/*
* Removes the entity from database at the next flush() operation
*/
public void remove(Object entity);
 
/*
* Synchronizes the Persistence Context with the underlying database
*/
public void flush();
  • ์กฐํšŒ : find(Member.class, memberId)
  • ์ €์žฅ : persist(member)
  • ์ˆ˜์ • : member.setName("๋ณ€๊ฒฝํ•  ์ด๋ฆ„")
  • ์‚ญ์ œ : remove(member)
  • ๋ณ‘ํ•ฉ(์ค€์˜์† → ์˜์†) : merge(detachedMember)
  • ์ฆ‰์‹œ DB ๋ฐ˜์˜ : flush()

 

๊ทธ๋Ÿฌ๋ฉด Hibernate๋Š” ๋ฌด์—‡์ผ๊นŒ ? ๐Ÿค”

 

๐ŸŽˆHibernate

Hibernate๋Š” JPA (Java Persistence API) ๋ช…์„ธ์˜ ๋Œ€ํ‘œ์ ์ธ ๊ตฌํ˜„์ฒด ์ค‘ ํ•˜๋‚˜์ด๋‹ค.
javax.persistence.EntityManager์™€ ๊ฐ™์€ JPA์˜ ํ•ต์‹ฌ ์ธํ„ฐํŽ˜์ด์Šค๋“ค์„ ์ง์ ‘ ๊ตฌํ˜„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, JPA๊ฐ€ ์ •์˜ํ•œ ํ‘œ์ค€ ๋ฐฉ์‹์— ๋”ฐ๋ผ ๋™์ž‘ํ•œ๋‹ค.

JPA์™€ Hibernate์˜ ๊ด€๊ณ„๋Š” ์ž๋ฐ”์˜ interface์™€ ์ด๋ฅผ ๊ตฌํ˜„ํ•œ class์˜ ๊ด€๊ณ„์™€ ์œ ์‚ฌํ•˜๋‹ค.

 

์ถœ์ฒ˜ : https://suhwan.dev/2019/02/24/jpa-vs-hibernate-vs-spring-data-jpa

์œ„ ๊ทธ๋ฆผ์€ JPA์™€ Hibernate ๊ฐ„์˜ ์ƒ์† ๋ฐ ๊ตฌํ˜„ ๊ด€๊ณ„๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

 

JPA์˜ ํ•ต์‹ฌ ์ธํ„ฐํŽ˜์ด์Šค์ธ EntityManagerFactory, EntityManager, EntityTransaction์€ Hibernate์—์„œ ๊ฐ๊ฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„๋œ๋‹ค.

  • EntityManagerFactory → SessionFactory
  • EntityManager → Session
  • EntityTransaction → Transaction

Hibernate๋Š” ์ด ํด๋ž˜์Šค๋“ค์„ ์ƒ์†ํ•˜๊ณ  ๋‚ด๋ถ€์ ์œผ๋กœ Impl ํด๋ž˜์Šค๋“ค๋กœ ๊ตฌํ˜„ํ•œ๋‹ค.

 

Hibernate๋Š” JPA์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋ฉฐ, ๊ฐ์ฒด์™€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ„์˜ ๋งคํ•‘์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์„œ ๊ฐœ๋ฐœ์ž๊ฐ€ SQL ์ฟผ๋ฆฌ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•˜์ง€ ์•Š๋„๋ก ๋„์™€์ค€๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด Hibernate๋Š” ํ•„์ˆ˜์ผ๊นŒ ? ๐Ÿค”

 

Hibernate๋Š” JPA์˜ ๊ตฌํ˜„์ฒด ์ค‘ ํ•˜๋‚˜์ผ ๋ฟ, JPA๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ˜๋“œ์‹œ Hibernate๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

๋งŒ์•ฝ Hibernate์˜ ์ž‘๋™ ๋ฐฉ์‹์ด ๋งˆ์Œ์— ๋“ค์ง€ ์•Š๋Š”๋‹ค๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ JPA๋กœ ๊ตฌํ˜„์ฒด๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • EclipseLink
  • DataNucleus
  • OpenJPA 
  • ๋˜๋Š” ์ง์ ‘ ๊ตฌํ˜„ํ•œ JPA๋„ ๊ฐ€๋Šฅ

 

๐Ÿ” Hibernate ์ž‘๋™ ๋ฐฉ์‹ ๊ฐ„๋žตํ•˜๊ฒŒ ๋ณด๊ธฐ

  1. Configuration ์„ค์ •
  2. Session ์ƒ์„ฑ
  3. ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘
  4. CRUD ์ž‘์—… ์ˆ˜ํ–‰
  5. DB ๋ฐ˜์˜
  6. ํŠธ๋žœ์žญ์…˜ ์ข…๋ฃŒ & ์„ธ์…˜ ์ข…๋ฃŒ

 

์™œ ๋Œ€๋ถ€๋ถ„ Hibernate๋ฅผ ์‚ฌ์šฉํ• ๊นŒ? ๐Ÿค”

 

Hibernate๋Š” ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๊ตฌํ˜„์ฒด๋กœ, ์˜ค๋žœ ์‹œ๊ฐ„ ๋™์•ˆ ์‚ฌ์šฉ๋˜๋ฉด์„œ ๊ฒ€์ฆ๋œ ์„ฑ์ˆ™ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

ํ’๋ถ€ํ•œ ๊ธฐ๋Šฅ, ์•ˆ์ •์„ฑ, ๋ฌธ์„œํ™”, ๊ทธ๋ฆฌ๊ณ  Spring Framework์™€์˜ ๋†’์€ ํ˜ธํ™˜์„ฑ ๋•๋ถ„์— ์‚ฌ์‹ค์ƒ JPA์˜ ํ‘œ์ค€ ๊ตฌํ˜„์ฒด์ฒ˜๋Ÿผ ๋„๋ฆฌ ์‚ฌ์šฉ๋œ๋‹ค.

 

๐ŸŽˆJDBC (Java Database Connectivity)

JDBC๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์ž๋ฐ”์—์„œ ์ œ๊ณตํ•˜๋Š” API์ด๋‹ค.

Hibernate๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ JDBC๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ํ†ต์‹ ํ•œ๋‹ค.

JDBC๋Š” ์ง์ ‘์ ์ธ SQL ์ฝ”๋“œ ์ž‘์„ฑ๊ณผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ฆฌ์— ์ดˆ์ ์„ ๋งž์ถ”๊ณ  ์žˆ์ง€๋งŒ, Hibernate๋Š” ๊ฐ์ฒด์ง€ํ–ฅ์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ์ƒํ˜ธ์ž‘์šฉ์„ SQL์„ ์ง์ ‘ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ  ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

 

Spring์œผ๋กœ ๊ฐœ๋ฐœ์„ ํ•˜๋ฉด์„œ EntityManager๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋“œ๋ฌผ๋‹ค๋Š” ์ ์—์„œ ์˜๋ฌธ์ด ๋“ค ์ˆ˜ ์žˆ๋‹ค.

๊ทธ ์ด์œ ๋Š” ๋Œ€๋ถ€๋ถ„์˜ DB ์ ‘๊ทผ ์ž‘์—…์„ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ , Repository๋ฅผ ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด Repository ๊ฐœ๋…์ด ๋ฐ”๋กœ Spring Data JPA์˜ ํ•ต์‹ฌ์ด๋‹ค.

 

๐ŸŽˆSpring Data JPA

Spring Data JPA๋Š” Spring์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“ˆ ์ค‘ ํ•˜๋‚˜๋กœ, ๊ฐœ๋ฐœ์ž๊ฐ€ JPA๋ฅผ ๋” ์‰ฝ๊ณ  ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

๊ธฐ์กด JPA๋Š” EntityManager๋ฅผ ์ง์ ‘ ์ฃผ์ž…๋ฐ›์•„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜์ง€๋งŒ, Spring Data JPA๋Š” ์ด๋ฅผ ํ•œ ๋‹จ๊ณ„ ๋” ์ถ”์ƒํ™”ํ•œ Repository ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

 

Spring Data JPA๊ฐ€ JPA๋ฅผ ์ถ”์ƒํ™”ํ–ˆ๋‹ค๋Š” ๋ง์€, ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์—ฌ์ „ํžˆ EntityManager๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๊ฐœ๋ฐœ์ž๋Š” ์ด๋ฅผ ์ง์ ‘ ๋‹ค๋ฃจ์ง€ ์•Š๊ณ  Repository๋งŒ ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค๋Š” ๋œป์ด๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ Repository ์ธํ„ฐํŽ˜์ด์Šค์— ๊ทœ์น™์— ๋งž๊ฒŒ ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•˜๋ฉด, Spring์ด ํ•ด๋‹น ๋ฉ”์„œ๋“œ ์ด๋ฆ„์— ์•Œ๋งž์€ ์ฟผ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๊ณ , ๊ตฌํ˜„์ฒด๋ฅผ ๋งŒ๋“ค์–ด Bean์œผ๋กœ ๋“ฑ๋กํ•ด์ค€๋‹ค.

 

Spring ํ”„๋กœ์ ํŠธ์—์„œ Spring Data JPA๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ Hibernate๊ฐ€ JPA์˜ ๊ตฌํ˜„์ฒด๋กœ ๋“ฑ๋ก๋˜์–ด ๋™์ž‘ํ•œ๋‹ค. ์ด ๋•๋ถ„์— ๊ฐœ๋ฐœ์ž๋Š” Hibernate๋‚˜ JPA์˜ ์„ธ๋ถ€ API๋ฅผ ์ง์ ‘ ๋‹ค๋ฃจ์ง€ ์•Š๊ณ ๋„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๋™์„ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ํ•œ, Repository ๋ฉ”์„œ๋“œ์˜ ๋„ค์ด๋ฐ ๊ทœ์น™์— ๋”ฐ๋ผ Spring์ด ์ฟผ๋ฆฌ๋ฅผ ์ž๋™ ์ƒ์„ฑํ•˜๋ฏ€๋กœ, ๋ฐ˜๋ณต์ ์€ SQL ์ž‘์„ฑ ์—†์ด๋„ ๋ฐ์ดํ„ฐ ์กฐํšŒ ๋ฐ ์กฐ์ž‘ ๊ธฐ๋Šฅ์„ ์†์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ‘‰ ์ •๋ฆฌํ•˜์ž๋ฉด Spring Data JPA → JPA → Hibernate → JDBC → DB ์ด๋ ‡๊ฒŒ ๊ณ„์ธต์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

 

๐Ÿงฉ Spring Data JPA ์˜ˆ์‹œ

1. ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ .findAll()

@Repository
public interface UserRepository extends JpaRepository<User, Long> {}

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public List<User> findAll() {
        return userRepository.findAll();
    }
}

2. ํŠน์ • id๋ฅผ ๊ฐ€์ง„ ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ .findById(Long id)

@Repository
public interface UserRepository extends JpaRepository<User, Long> {}

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public Optional<User> findById(Long id) {
        return userRepository.findById(id);
    }
}

3. ํŠน์ • ์ด๋ฆ„์œผ๋กœ ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ .findByName(String name)

@Repository
public interface UserRepository extends JpaRepository<User, Long> {}

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public List<User> findByName(String name) {
        return userRepository.findByName(name);
    }
}

4. ์—”ํ‹ฐํ‹ฐ ์ €์žฅ .save()

@Repository
public interface UserRepository extends JpaRepository<User, Long> {}

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public User save(User user) {
        return userRepository.save(user);
    }
}

5. ์—”ํ‹ฐํ‹ฐ ์—…๋ฐ์ดํŠธ .update()

@Repository
public interface UserRepository extends JpaRepository<User, Long> {}

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public User update(User user) {
        return userRepository.save(user);
    }
}

6. ์—”ํ‹ฐํ‹ฐ ์‚ญ์ œ .delete()

@Repository
public interface UserRepository extends JpaRepository<User, Long> {}

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public void delete(User user) {
        userRepository.delete(user);
    }
}

7. ํŽ˜์ด์ง€๋„ค์ด์…˜ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•œ ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ

@Repository
public interface UserRepository extends JpaRepository<User, Long> {}

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public Page<User> findAll(Pageable pageable) {
        return userRepository.findAll(pageable);
    }
}

8. ์ •๋ ฌ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•œ ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ

@Repository
public interface UserRepository extends JpaRepository<User, Long> {}

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public List<User> findAll(Sort sort) {
        return userRepository.findAll(sort);
    }
}

 

 


 

๐Ÿ’ญ Q&A

Q : JPA์™€ Spring Data JPA์˜ ์ฐจ์ด์ ์€ ?

A : JPA๋Š” ORM์„ ์œ„ํ•œ ํ‘œ์ค€ ๋ช…์„ธ๋กœ, EntityManager๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ง์ ‘ ๋‹ค๋ค„์•ผ ํ•˜๋ฉฐ Hibernate ๊ฐ™์€ ๊ตฌํ˜„์ฒด๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ๋ฐ˜๋ฉด Spring Data JPA๋Š” JPA ์œ„์— ๊ตฌ์ถ•๋œ Spring ๋ชจ๋“ˆ๋กœ, ๊ฐœ๋ฐœ์ž๊ฐ€ Repository ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ์ •์˜ํ•˜๋ฉด CRUD ์ฟผ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ค€๋‹ค. 

 

 

 

 

 

๐Ÿ“ƒ reference