๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
โ˜˜๏ธ ๋ฐฑ์—”๋“œ: Backend

[Spring] ํ˜ผ๋™๋˜๋Š” JPA ๊ฐœ๋… ์ •๋ฆฌ (Hibernate, Spring Data JPA)

by ๐Ÿค ์ค€์ฝฉ์ด 2023. 6. 27.

๐Ÿ˜ฑ ์ด ๊ธ€์„ ์“ฐ๋Š” ์ด์œ 

 

์ทจ์—… ์ค€๋น„๋ฅผ ํ•˜๋ฉฐ ๋ฉด์ ‘์„ ๋ณด๋‹ค๋ณด๋ฉด JPA ์˜ ๊ฐœ๋…์€ ๋งค๋ฒˆ ๋‚˜์˜ฌ๋งŒํผ ๋‹จ๊ณจ ์งˆ๋ฌธ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ๋งค๋ฒˆ Hibernate ๋Š” JPA ์˜ ๊ตฌํ˜„์ฒด์ž…๋‹ˆ๋‹ค! ๋ผ๋Š” ๋Œ€๋‹ต๋งŒ ํ•ด์™”๊ณ , ์†”์งํžˆ ์ฐจ์ด๋ฅผ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๊ณ  ์žˆ์ง€ ์•Š๋‹ค๊ณ  ๋А๊ผˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฒˆ ๊ธฐํšŒ์— JPA, Hibernate, Spring Data JPA ์˜ ์ฐจ์ด์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•˜๊ณ  ์ •๋ฆฌํ•ด๋ณด๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์ ธ๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ˜Ž

 

 

๐Ÿค” JPA ๋ž€?

 

JPA ๋Š” Java Persistence API ์˜ ์•ฝ์ž๋กœ, ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์ด์˜ ๋ฐ์ดํ„ฐ ์˜์†์„ฑ์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํ‘œ์ค€ํ™”๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. JPA ๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ„์˜ ๋ถˆ์ผ์น˜๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ์ฒด์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋งคํ•‘ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ์ˆ ์„ ORM ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ JPA ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ผ๋Š” ์ ์„ ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ธํ„ฐํŽ˜์ด์Šค๋Š” javax.persistence ํŒจํ‚ค์ง€์— ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ์œ„ํ•œ ๋ฉ”์„œ๋“œ๋“ค์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— JPA ์— ๋ช…์„ธ๋œ ๊ธฐ๋Šฅ๋“ค์„ ์‹ค์ œ๋กœ ๋™์ž‘ํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ด๋ฅผ ๊ตฌํ˜„ํ•œ ORM ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์ธ JPA ๊ตฌํ˜„์ฒด๋กœ Hibernate, EclipseLink, OpenJPA ๋“ฑ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

 

 

๐Ÿค” ORM ์ด๋ž€?

 

ORM ์€ Object-Relational Mapping ์˜ ์•ฝ์ž๋กœ, ๊ฐ์ฒด์™€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ„์˜ ๋งคํ•‘์„ ์ž๋™ํ™”ํ•˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ORM ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ SQL ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๊ณ  ์กฐํšŒํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. JPA ๋Š” ์ด๋Ÿฌํ•œ ORM ๊ธฐ์ˆ ์˜ ํ•œ ์ข…๋ฅ˜๋กœ, ๊ฐ์ฒด์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ„์˜ ๋งคํ•‘์„ ์œ„ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค.

 

 

๐Ÿค” Hibernate ๋ž€?

 

Hibernate ๋Š” ์œ„์—์„œ ์–ธ๊ธ‰ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ JPA ์˜ ๊ตฌํ˜„์ฒด ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

 

JPA ์ธํ„ฐํŽ˜์ด์Šค์™€ Hibernate ๊ตฌํ˜„์ฒด ๊ฐ„์˜ ์—ฐ๊ด€ ๊ด€๊ณ„

 

์œ„ ์‚ฌ์ง„์€ Hibernate ๊ณต์‹๋ฌธ์„œ์—์„œ ์ œ๊ณตํ•˜๋Š” JPA ์ธํ„ฐํŽ˜์ด์Šค์™€ Hibernate ๊ตฌํ˜„์ฒด ๊ฐ„์˜ ์ƒ์† ๋ฐ ๊ตฌํ˜„ ๊ด€๊ณ„๋ฅผ ๋‹ค์ด์–ด๊ทธ๋žจ์œผ๋กœ ๋‚˜ํƒ€๋‚ธ ๋ชจ์Šต์ž…๋‹ˆ๋‹ค. ๋‹ค์ด์–ด๊ทธ๋žจ์„ ์‚ดํŽด๋ณด๋ฉด JPA ์˜ ์ธํ„ฐํŽ˜์ด์Šค์ธ EntityManagerFactory, EntityManager, EntityTransaction ์„ Hibernate ๊ตฌํ˜„์ฒด์—์„œ ์ƒ์†๋ฐ›์•„ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Hibernate ๋Š” JPA ์˜ ๊ตฌํ˜„์ฒด ์ค‘ ํ•˜๋‚˜์ด๊ธฐ ๋•Œ๋ฌธ์—, JPA ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฐ˜๋“œ์‹œ Hibernate ๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ์˜ ์š”๊ตฌ์‚ฌํ•ญ๊ณผ ์ƒํ™ฉ์— ๋”ฐ๋ผ EclipseLink, OpenJPA ์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ณ , ์‹ฌ์ง€์–ด๋Š” ์ง์ ‘ JPA ์˜ ๊ตฌํ˜„์ฒด๋ฅผ ๊ตฌํ˜„ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, Hibernate ๊ฐ€ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ์ด์œ ๋Š” ์˜ค๋žœ ๊ธฐ๊ฐ„ ๋™์•ˆ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ์‚ฌ์šฉ๋˜๋ฉฐ ์„ฑ์ˆ™ํ•ด์ง„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๋Š” ๊ฒƒ์„ ์ดํ•ดํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

 

๐Ÿค” Spring Data JPA ๋ž€?

 

Spring Data JPA ๋Š” Hibernate ์™€ JPA ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœํ•œ ๋ฐ์ดํ„ฐ ์—‘์„ธ์Šค ๊ธฐ์ˆ ์„ ๋ณด๋‹ค ๊ฐ„ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•˜๋Š” Spring Framework ์˜ ํ”„๋กœ์ ํŠธ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

 

SimpleJpaRepository ์˜ ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ

 

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

 

package org.springframework.data.jpa.repository.support;

import ...

@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {

	...

	private final EntityManager em;

	...

	@Override
	public Optional<T> findById(ID id) {

		...

	}
	
	// Other methods
}