Search
Duplicate

JPA μ†Œκ°œ

JPA

λ°μ΄ν„°λ² μ΄μŠ€μ™€ 객체(Entity) κ°„ μžλ™ 맀핑을 톡해 데이터λ₯Ό κ΄€λ¦¬ν•˜λŠ” μžλ°” ORM ν”„λ ˆμž„μ›Œν¬
β€’
JPA
β€’
JPA μ£Όμš” ꡬ성 μš”μ†Œ
β€’
JPA μž₯점
β€’
JPA vs MyBatis
β€’
JPA μ£Όμš” κΈ°λŠ₯

JPAλž€?

JPA(Java Persistence API)λŠ” μžλ°” μ§„μ˜μ˜ ORM 기술 ν‘œμ€€μž…λ‹ˆλ‹€. JPAλ₯Ό μ‚¬μš©ν•˜λ©΄ κ°œλ°œμžκ°€ 직접 SQL을 μž‘μ„±ν•˜μ§€ μ•Šκ³ λ„ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό 객체지ν–₯적으둜 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.

JPA μ£Όμš” ꡬ성 μš”μ†Œ

ꡬ성 μš”μ†Œ
μ—­ν•  및 μ„€λͺ…
Persistence Unit
JPA μ„€μ • 정보λ₯Ό μ •μ˜ν•˜λŠ” 논리적 λ‹¨μœ„. DB μ—°κ²° 정보 및 μ—”ν‹°ν‹° λͺ©λ‘μ„ 포함. (persistence.xml λ˜λŠ” application.ymlμ—μ„œ μ„€μ •)
Entities (μ—”ν„°ν‹°)
λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”κ³Ό 1:1 λ§€ν•‘λ˜λŠ” 객체. @Entity μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ μ •μ˜ν•˜λ©°, @Id둜 κΈ°λ³Έ ν‚€ μ§€μ •.
EntityManagerFactory
EntityManagerλ₯Ό μƒμ„±ν•˜λŠ” νŒ©ν† λ¦¬ 객체. μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ ν•˜λ‚˜λ§Œ μƒμ„±ν•˜λ©° μ—¬λŸ¬ EntityManager 제곡.
EntityManager
μ—”ν‹°ν‹°μ˜ μ €μž₯, 쑰회, μˆ˜μ •, μ‚­μ œλ₯Ό λ‹΄λ‹Ήν•˜λŠ” 핡심 객체. persist(), find(), remove() λ“±μ˜ λ©”μ„œλ“œλ₯Ό 제곡.
PersistenceContext
μ—”ν‹°ν‹°μ˜ μƒνƒœλ₯Ό μΆ”μ ν•˜λŠ” JPA의 1μ°¨ μΊμ‹œ μ—­ν• . λ³€κ²½ 감지(Dirty Checking)λ₯Ό 톡해 μžλ™μœΌλ‘œ λ³€κ²½ 사항 반영.
TransactionManager
데이터 λ³€κ²½ μ‹œ νŠΈλžœμž­μ…˜μ„ κ΄€λ¦¬ν•˜μ—¬ 정합성을 보μž₯. Spring Bootμ—μ„œλŠ” @Transactional둜 νŠΈλžœμž­μ…˜ 적용 κ°€λŠ₯.
DB (Database)
JPAκ°€ μ—°λ™ν•˜λŠ” μ΅œμ’… μ €μž₯μ†Œ. Hibernate λ“± κ΅¬ν˜„μ²΄λ₯Ό μ‚¬μš©ν•˜μ—¬ SQL을 μžλ™ μƒμ„±ν•˜κ³  데이터 관리 μˆ˜ν–‰.

JPA ꡬ쑰 및 각 μš”μ†Œμ˜ μ—­ν• 

JPA(Java Persistence API)λŠ” 객체와 λ°μ΄ν„°λ² μ΄μŠ€ κ°„μ˜ 맀핑을 μžλ™ν™”ν•˜λŠ” ORM(Object-Relational Mapping) κΈ°μˆ μž…λ‹ˆλ‹€.

Persistence Unit (νΌμ‹œμŠ€ν„΄μŠ€ μœ λ‹›)

JPA μ„€μ • 정보λ₯Ό μ •μ˜ν•˜λŠ” 논리적 λ‹¨μœ„μž…λ‹ˆλ‹€.
β€’
JPAκ°€ μ–΄λ–€ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ‚¬μš©ν• μ§€, μ–΄λ–€ μ—”ν‹°ν‹°λ₯Ό 관리할지 λ“±μ˜ 섀정을 ν¬ν•¨ν•©λ‹ˆλ‹€.
β€’
Java SE ν™˜κ²½μ—μ„œλŠ” persistence.xml νŒŒμΌμ—μ„œ μ„€μ •ν•˜μ§€λ§Œ, Spring Bootμ—μ„œλŠ” application.properties λ˜λŠ” application.ymlμ—μ„œ μ„€μ •ν•©λ‹ˆλ‹€.
β€’
Persistence Unit이 μ •μ˜λ˜λ©΄, JPAκ°€ 이λ₯Ό 기반으둜 λ™μž‘ν•˜λ©° λ°μ΄ν„°λ² μ΄μŠ€ 연결을 κ΄€λ¦¬ν•©λ‹ˆλ‹€.
Spring Bootμ—μ„œμ˜ μ„€μ • μ˜ˆμ‹œ:
spring.datasource.url=jdbc:mysql://localhost:3306/mydb spring.datasource.username=root spring.datasource.password=1234 spring.jpa.hibernate.ddl-auto=update
Plain Text
볡사

Entities (μ—”ν„°ν‹°)

λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”κ³Ό 1:1 λ§€ν•‘λ˜λŠ” κ°μ²΄μž…λ‹ˆλ‹€.
β€’
@Entity μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜μ—¬ JPAκ°€ ν•΄λ‹Ή 클래슀λ₯Ό μ—”ν‹°ν‹°λ‘œ μΈμ‹ν•˜λ„λ‘ ν•©λ‹ˆλ‹€.
β€’
각 ν•„λ“œλŠ” λ°μ΄ν„°λ² μ΄μŠ€μ˜ 컬럼과 λ§€ν•‘λ˜λ©°, @IdλŠ” κΈ°λ³Έ ν‚€λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.
μ—”ν„°ν‹° 예제:
@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; }
Java
볡사

EntityManagerFactory (μ—”ν„°ν‹° λ§€λ‹ˆμ € νŒ©ν† λ¦¬)

EntityManagerλ₯Ό μƒμ„±ν•˜λŠ” νŒ©ν† λ¦¬(Factory) κ°μ²΄μž…λ‹ˆλ‹€.
β€’
JPAμ—μ„œλŠ” EntityManagerκ°€ λ°μ΄ν„°λ² μ΄μŠ€μ™€μ˜ 연결을 κ΄€λ¦¬ν•˜μ§€λ§Œ, EntityManagerFactoryλŠ” EntityManager의 생성을 λ‹΄λ‹Ήν•©λ‹ˆλ‹€.
β€’
일반적으둜 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ ν•˜λ‚˜λ§Œ μƒμ„±ν•˜λ©°, μ—¬λŸ¬ 개의 EntityManagerλ₯Ό μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
Spring Bootμ—μ„œλŠ” @PersistenceUnit 없이 μžλ™ 섀정됨
@Autowired private EntityManagerFactory entityManagerFactory;
Java
볡사

EntityManager (μ—”ν„°ν‹° λ§€λ‹ˆμ €)

μ—”ν‹°ν‹°λ₯Ό κ΄€λ¦¬ν•˜κ³  λ°μ΄ν„°λ² μ΄μŠ€μ™€ μƒν˜Έμž‘μš©ν•˜λŠ” 핡심 κ°μ²΄μž…λ‹ˆλ‹€.
β€’
μ—”ν‹°ν‹°μ˜ μ €μž₯, 쑰회, μˆ˜μ •, μ‚­μ œ λ“±μ˜ μž‘μ—…μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€.
β€’
persist(), find(), merge(), remove() λ“±μ˜ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ—”ν‹°ν‹°λ₯Ό μ‘°μž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
β€’
μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ(PersistenceContext)λ₯Ό 톡해 μ—”ν‹°ν‹°μ˜ μƒνƒœλ₯Ό κ΄€λ¦¬ν•©λ‹ˆλ‹€.
μ—”ν‹°ν‹° λ§€λ‹ˆμ € μ‚¬μš© 예제:
EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); User user = new User(); user.setName("John"); user.setEmail("john@example.com"); entityManager.persist(user); entityManager.getTransaction().commit(); entityManager.close();
Java
볡사
Spring Bootμ—μ„œλŠ” @PersistenceContextλ₯Ό μ‚¬μš©ν•˜μ—¬ μžλ™ μ£Όμž… κ°€λŠ₯
@PersistenceContext private EntityManager entityManager;
Java
볡사

PersistenceContext (μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ)

EntityManagerκ°€ κ΄€λ¦¬ν•˜λŠ” μ—”ν‹°ν‹° μ €μž₯μ†Œλ‘œ, 1μ°¨ μΊμ‹œ 역할을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.
β€’
μ—”ν‹°ν‹°κ°€ EntityManager에 μ˜ν•΄ κ΄€λ¦¬λ˜λ©΄, λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ 쑰회된 μ—”ν‹°ν‹°κ°€ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ €μž₯λ©λ‹ˆλ‹€.
β€’
λ™μΌν•œ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ 같은 μ—”ν‹°ν‹°λ₯Ό λ‹€μ‹œ μ‘°νšŒν•˜λ©΄ λ°μ΄ν„°λ² μ΄μŠ€μ— μ ‘κ·Όν•˜μ§€ μ•Šκ³  1μ°¨ μΊμ‹œμ—μ„œ κ°€μ Έμ˜΅λ‹ˆλ‹€.
β€’
λ³€κ²½ 감지(Dirty Checking) κΈ°λŠ₯을 μ œκ³΅ν•˜μ—¬, μ—”ν‹°ν‹°μ˜ 값을 λ³€κ²½ν•˜λ©΄ μžλ™μœΌλ‘œ UPDATE 쿼리λ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€.
λ³€κ²½ 감지 예제:
User user = entityManager.find(User.class, 1L); // DBμ—μ„œ 쑰회 user.setName("Updated Name"); // κ°’ λ³€κ²½ // λ³„λ„μ˜ update 쿼리λ₯Ό μ‹€ν–‰ν•˜μ§€ μ•Šμ•„λ„ 변경이 κ°μ§€λ˜μ–΄ μžλ™ 반영됨 entityManager.getTransaction().commit();
Java
볡사

TransactionManager (νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €)

데이터 변경이 λ°œμƒν•  λ•Œ νŠΈλžœμž­μ…˜μ„ κ΄€λ¦¬ν•˜λŠ” 역할을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.
β€’
λ°μ΄ν„°λ² μ΄μŠ€μ˜ ACID(μ›μžμ„±, 일관성, 격리성, 지속성) νŠΉμ„±μ„ 보μž₯ν•©λ‹ˆλ‹€.
β€’
데이터 μ €μž₯, μˆ˜μ •, μ‚­μ œ λ“±μ˜ μž‘μ—…μ€ λ°˜λ“œμ‹œ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ μ‹€ν–‰ν•΄μ•Ό ν•©λ‹ˆλ‹€.
β€’
Spring Bootμ—μ„œλŠ” @Transactional μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜μ—¬ κ°„λ‹¨νžˆ νŠΈλžœμž­μ…˜μ„ 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.
νŠΈλžœμž­μ…˜ 관리 예제:
@Service public class UserService { @Autowired private EntityManager entityManager; @Transactional public void updateUser(Long id, String newName) { User user = entityManager.find(User.class, id); user.setName(newName); } // νŠΈλžœμž­μ…˜ μ’…λ£Œ μ‹œ μžλ™μœΌλ‘œ λ³€κ²½ 사항 반영 }
Java
볡사

DB (Database, λ°μ΄ν„°λ² μ΄μŠ€)

JPA의 μ΅œμ’… μ €μž₯μ†Œλ‘œ, μ—”ν‹°ν‹°μ˜ 데이터λ₯Ό μ €μž₯ν•˜λŠ” κ³΅κ°„μž…λ‹ˆλ‹€.
β€’
JPAκ°€ SQL을 μžλ™ μƒμ„±ν•˜μ—¬ λ°μ΄ν„°λ² μ΄μŠ€μ™€ μƒν˜Έμž‘μš©ν•©λ‹ˆλ‹€.
β€’
DDL(ν…Œμ΄λΈ” 생성) 및 DML(데이터 μ‘°μž‘) μž‘μ—…μ΄ μˆ˜ν–‰λ©λ‹ˆλ‹€.
β€’
JPA 섀정에 따라 Hibernate λ˜λŠ” EclipseLink 같은 κ΅¬ν˜„μ²΄κ°€ μ‚¬μš©λ©λ‹ˆλ‹€.
SQL μžλ™ 생성 μ˜ˆμ‹œ (spring.jpa.show-sql=true μ„€μ • μ‹œ 확인 κ°€λŠ₯)
INSERT INTO user (name, email) VALUES ('John', 'john@example.com'); UPDATE user SET name = 'Updated Name' WHERE id = 1;
SQL
볡사

μ΅œμ’… μš”μ•½

JPAλŠ” 객체(Entity)와 λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”μ„ μžλ™μœΌλ‘œ λ§€ν•‘ν•˜λŠ” ORM κΈ°μˆ μž…λ‹ˆλ‹€.
JPAλŠ” EntityManagerλ₯Ό 톡해 μ—”ν‹°ν‹°λ₯Ό κ΄€λ¦¬ν•˜κ³ , νŠΈλžœμž­μ…˜μ„ μ²˜λ¦¬ν•˜λ©°, SQL을 μžλ™ μƒμ„±ν•˜μ—¬ DB와 μ—°λ™ν•˜λŠ” ORM ν”„λ ˆμž„μ›Œν¬μž…λ‹ˆλ‹€.
β€’
Persistence Unit은 섀정을 μ •μ˜ν•˜κ³ ,
β€’
EntityManagerFactoryλŠ” EntityManagerλ₯Ό μƒμ„±ν•˜μ—¬ μ—”ν‹°ν‹°λ₯Ό κ΄€λ¦¬ν•©λ‹ˆλ‹€.
β€’
PersistenceContextλŠ” μ—”ν‹°ν‹°μ˜ μƒνƒœλ₯Ό μΆ”μ ν•˜κ³ , 1μ°¨ μΊμ‹œλ₯Ό 톡해 μ„±λŠ₯을 μ΅œμ ν™”ν•©λ‹ˆλ‹€.
β€’
TransactionManagerλŠ” 데이터 λ³€κ²½ μ‹œ νŠΈλžœμž­μ…˜μ„ κ΄€λ¦¬ν•˜μ—¬ 정합성을 보μž₯ν•©λ‹ˆλ‹€.
β€’
μ΅œμ’…μ μœΌλ‘œ JPAλŠ” λ°μ΄ν„°λ² μ΄μŠ€μ™€ μ—°λ™λ˜μ–΄ SQL을 μ‹€ν–‰ν•˜κ³  데이터λ₯Ό κ΄€λ¦¬ν•©λ‹ˆλ‹€.

JPA의 μž₯점

β€’
객체지ν–₯적인 μ½”λ“œ μž‘μ„± κ°€λŠ₯
β€’
생산성 ν–₯상
β€’
μœ μ§€λ³΄μˆ˜ 용이
β€’
λ°μ΄ν„°λ² μ΄μŠ€μ— 독립적인 개발 κ°€λŠ₯

JPA vs MyBatis

비ꡐ ν•­λͺ©
JPA (Java Persistence API)
MyBatis
κ°œλ…
객체와 κ΄€κ³„ν˜• λ°μ΄ν„°λ² μ΄μŠ€ κ°„μ˜ 맀핑을 μžλ™ν™”ν•˜λŠ” ORM 기술
SQL λ§€ν•‘ 기반의 λ°μ΄ν„°λ² μ΄μŠ€ μ ‘κ·Ό ν”„λ ˆμž„μ›Œν¬
쿼리 방식
SQL을 μžλ™ 생성 (JPQL, Criteria API, QueryDSL 지원)
SQL을 직접 μž‘μ„±ν•˜μ—¬ μ‚¬μš© (XML λ˜λŠ” μ–΄λ…Έν…Œμ΄μ…˜ ν™œμš©)
개발 생산성
CRUD μžλ™ν™”, 객체 쀑심 개발둜 μ½”λ“œ κ°„κ²°
SQL을 직접 μž‘μ„±ν•΄μ•Ό ν•˜λ―€λ‘œ 반볡 μ½”λ“œ 증가 κ°€λŠ₯
μœ μ§€λ³΄μˆ˜μ„±
μ—”ν‹°ν‹° 쀑심 개발, λΉ„μ¦ˆλ‹ˆμŠ€ 둜직과 데이터 μ ‘κ·Ό μ½”λ“œ 뢄리
SQL이 μ½”λ“œμ— ν¬ν•¨λ˜λ―€λ‘œ λ³€κ²½ μ‹œ μœ μ§€λ³΄μˆ˜ λΆ€λ‹΄ 증가
퍼포먼슀
1μ°¨ μΊμ‹œ, λ³€κ²½ 감지, μ§€μ—° λ‘œλ”© λ“± μ΅œμ ν™” κΈ°λŠ₯ 제곡
쿼리λ₯Ό 직접 μ΅œμ ν™”ν•  수 μžˆμ–΄ μ„±λŠ₯ 쑰정이 용이
νŠΈλžœμž­μ…˜ 관리
JPA λ‚΄λΆ€μ—μ„œ νŠΈλžœμž­μ…˜ μžλ™ 관리 (@Transactional)
MyBatis 자체 νŠΈλžœμž­μ…˜ 관리 κΈ°λŠ₯은 μ—†μœΌλ©°, Spring νŠΈλžœμž­μ…˜ ν™œμš©
동적 쿼리
Criteria API, QueryDSL μ‚¬μš© κ°€λŠ₯
if, choose, foreach λ“±μ˜ XML νƒœκ·Έλ‘œ μœ μ—°ν•œ 동적 쿼리 μž‘μ„± κ°€λŠ₯
캐싱 κΈ°λŠ₯
1μ°¨ μΊμ‹œ(μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ) 및 2μ°¨ μΊμ‹œ 지원
기본적으둜 캐싱 κΈ°λŠ₯이 μ—†μœΌλ©°, 별도 μ„€μ • ν•„μš”
μ‚¬μš© λͺ©μ 
도메인 쀑심 섀계(DDD), λŒ€κ·œλͺ¨ ν”„λ‘œμ νŠΈμ— 적합
λ³΅μž‘ν•œ SQL이 λ§Žμ€ μ‹œμŠ€ν…œ, νŠΉμ • DB μ΅œμ ν™”κ°€ ν•„μš”ν•œ 경우
ν•™μŠ΅ λ‚œμ΄λ„
ORM κ°œλ… ν•™μŠ΅ ν•„μš”, 초기 μ§„μž… μž₯벽이 있음
SQL 쀑심 개발 λ°©μ‹μœΌλ‘œ 비ꡐ적 쉽고 μ΅μˆ™ν•¨

JPA의 μ£Όμš” κΈ°λŠ₯

κΈ°λŠ₯
μ„€λͺ…
엔티티와 ν…Œμ΄λΈ” λ§€ν•‘
μžλ°” 객체와 λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”μ„ μžλ™μœΌλ‘œ λ§€ν•‘
μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ
μ—”ν‹°ν‹°λ₯Ό 영ꡬ μ €μž₯ν•˜λŠ” ν™˜κ²½μ„ 제곡
JPQL
SQL을 μΆ”μƒν™”ν•œ 객체지ν–₯ 쿼리 μ–Έμ–΄ 제곡
Criteria API
μžλ°” μ½”λ“œλ‘œ JPQL을 μž‘μ„±ν•  수 있게 λ„μ™€μ£ΌλŠ” λΉŒλ” 클래슀 API
QueryDSL
νƒ€μž… μ•ˆμ „ν•œ SQLκ³Ό 같은 쿼리λ₯Ό μžλ°” μ½”λ“œλ‘œ μž‘μ„±ν•  수 있게 ν•΄μ£ΌλŠ” ν”„λ ˆμž„μ›Œν¬