Search

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๊ณผ ๊ฐ™์€ ์ฟผ๋ฆฌ๋ฅผ ์ž๋ฐ” ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ