Framework/Spring Framework

JPA ์™€ Spring data JPA ์ฐจ์ด์  (+ ํ•˜์ด๋ฒ„๋„ค์ดํŠธ)

ํ”„๋กœ๊ทธ๋ž˜๋จธ ์˜ค์›” 2023. 11. 8.

JPA, JPA, JPA ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๋งํ•˜์ง€๋งŒ, JPA ์™€ Spring data JPA๋ฅผ ํ˜ผ์šฉํ•ด์„œ, ์ฐฉ๊ฐํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์ด ๋งŽ์€ ๊ฒƒ ๊ฐ™๋‹ค.
๋ฌผ๋ก  ๋‚˜๋˜ํ•œ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค. JPA๋Š” EntityManager ๋ฅผ ์ด์šฉํ•˜์—ฌ, EntityManager ์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ CRUD ํ•˜๋Š” ๊ฑธ๋กœ ์•Œ๊ณ  ์žˆ์ง€๋งŒ, ์‹ค์ œ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•ด๋ณด๋ฉด EntityManager ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ   Repository ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์† ๋ฐ›์•„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค. ๋ฌด์Šจ ์ฐจ์ด ์ผ๊นŒ?

์ด์ฐธ์— JPA์™€ Spring data JPA ๊ฐœ๋…์„ ๋‹ค์žก์•„ ๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

 

JPA (Java Persistence API)

JPA๋Š” ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํ‘œ์ค€ API๋‹ค. JPA๋Š” ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์— ๋งคํ•‘ํ•˜๊ณ , CRUD(Create, Read, Update, Delete) ์ž‘์—…์„ ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

์ฃผ์š” ํŠน์ง•

  • ํ‘œ์ค€ ์ŠคํŽ™: JPA๋Š” ์ž๋ฐ” EE์˜ ์ผ๋ถ€๋กœ, ORM(Object-Relational Mapping) ํ‘œ์ค€์„ ์ •์˜ํ•œ๋‹ค.
  • POJO ๋ชจ๋ธ: ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค๋Š” ์ผ๋ฐ˜ ์ž๋ฐ” ๊ฐ์ฒด(POJO)๋กœ ์ž‘์„ฑ๋˜๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘๋œ๋‹ค.
  • ์ฟผ๋ฆฌ ์–ธ์–ด: JPA๋Š” JPQL(Java Persistence Query Language)์ด๋ผ๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ์ฟผ๋ฆฌ ์–ธ์–ด๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
  • ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ: JPA๋Š” ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค.

 

JPA ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ

  • EntityManager: ์—”ํ‹ฐํ‹ฐ์˜ ๋ผ์ดํ”„์‚ฌ์ดํด์„ ๊ด€๋ฆฌํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  • Entity: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘๋˜๋Š” ์ž๋ฐ” ํด๋ž˜์Šค๋‹ค.
  • JPQL: ๊ฐ์ฒด ์ง€ํ–ฅ ์ฟผ๋ฆฌ ์–ธ์–ด๋กœ, SQL๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

์˜ˆ์‹œ

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    // getters and setters
}

public class UserDAO {
	// ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ € ํŒฉํ† ๋ฆฌ ์ƒ์„ฑ ์ƒ๋žต
    EntityManager em = entityManagerFactory.createEntityManager();

	TypedQuery<User> query = em.createQuery("SELECT u FROM User u", User.class);
	List<User> users = query.getResultList();

	for (User user : users) {
    	System.out.println("User Name: " + user.getName());
	}

	em.close();
    //์บ์น˜๋ฌธ ๋ฐ ํŒŒ์ด๋„๋ฌธ ์ƒ๋žต
}

 

 

Spring Data JPA

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

์ฃผ์š” ํŠน์ง•

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

์˜ˆ์‹œ

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
    User findByName(String name);
}

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public User findUser(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    public User findUserByName(String name) {
        return userRepository.findByName(name);
    }
}

 

+ Hibernate (ํ•˜์ด๋ฒ„๋„ค์ดํŠธ)

Hibernate๋Š” JPA์˜ ๊ตฌํ˜„์ฒด ์ค‘ ํ•˜๋‚˜๋กœ, JPA ํ‘œ์ค€์„ ๋”ฐ๋ฅด๋ฉด์„œ ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ๊ณผ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์ œ๊ณตํ•œ๋‹ค. Hibernate๋Š” ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” JPA ๊ตฌํ˜„์ฒด๋‹ค. (์ด์™ธ ๊ตฌํ˜„์ฒด๋กœ EclipseLink , DataNucleus ๋“ฑ์ด ์žˆ๋‹ค.)

 

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

JPA์˜ ํ•ต์‹ฌ์ธ EntityManagerFactory , EntityManager , EntityTransaction์„Hibernate์—์„œ๋Š” ๊ฐ๊ฐSessionFactory , Session , Transaction ์œผ๋กœ ์ƒ์†๋ฐ›๊ณ  ๊ฐ๊ฐ Impl๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ฃผ์š” ํŠน์ง•

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

 

์ฐจ์ด์  ์š”์•ฝ

๊ฐœ๋… JPA Hibernate Spring Data JPA
์ •์˜ ์ž๋ฐ” ํ‘œ์ค€ ORM API JPA์˜ ๊ตฌํ˜„์ฒด ์ค‘ ํ•˜๋‚˜ Spring ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๋ชจ๋“ˆ
์ฃผ์š” ํŠน์ง• ์—”ํ‹ฐํ‹ฐ ๋งคํ•‘, JPQL, ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ JPA ํ‘œ์ค€ ๊ตฌํ˜„, ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ์ œ๊ณต ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ถ”์ƒํ™”, ์ž๋™ ๊ตฌํ˜„, ๋ฉ”์„œ๋“œ ์ฟผ๋ฆฌ
์‚ฌ์šฉ ๋ฐฉ์‹ ํ‘œ์ค€ API ์‚ฌ์šฉ JPA ํ‘œ์ค€ API + Hibernate ๊ธฐ๋Šฅ ์‚ฌ์šฉ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ
์ถ”๊ฐ€ ๊ธฐ๋Šฅ ์—†์Œ 2์ฐจ ์บ์‹œ, ๋„ค์ดํ‹ฐ๋ธŒ SQL, ๋ณต์žกํ•œ ๋งคํ•‘ ์ง€์› ํŽ˜์ด์ง•, ์ •๋ ฌ, ๋ฉ”์„œ๋“œ ์ฟผ๋ฆฌ, ์ปค์Šคํ…€ ์ฟผ๋ฆฌ ์ง€์›
๊ตฌํ˜„ ํ•„์š”์„ฑ ์ง์ ‘ ๊ตฌํ˜„ ํ•„์š” ์ง์ ‘ ๊ตฌํ˜„ ํ•„์š” ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜๋งŒ์œผ๋กœ ์ž๋™ ๊ตฌํ˜„

 

 

์ฐธ๊ณ 

์ธํ”„๋Ÿฐ - ์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ / ๊น€์˜ํ•œ

 

๋Œ“๊ธ€