https://github.com/venh312/jpashop
๐ป ORM ํ์ค JPA ํ๋ก๊ทธ๋๋ฐ (ํ์, ์ํ, ์ฃผ๋ฌธ)
https://github.com/venh312/jpashop
java17 jpa springboot3
Last synced: over 1 year ago
JSON representation
๐ป ORM ํ์ค JPA ํ๋ก๊ทธ๋๋ฐ (ํ์, ์ํ, ์ฃผ๋ฌธ)
- Host: GitHub
- URL: https://github.com/venh312/jpashop
- Owner: venh312
- Created: 2024-03-08T11:34:19.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2024-06-06T12:41:04.000Z (about 2 years ago)
- Last Synced: 2025-01-24T10:13:18.728Z (over 1 year ago)
- Topics: java17, jpa, springboot3
- Language: Java
- Homepage:
- Size: 103 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: Readme.md
Awesome Lists containing this project
README
## ์์์ฑ ์ปจํ
์คํธ

### ๋น์์
์์์ฑ ์ปจํ
์คํธ์ ์ ํ ๊ด๊ณ๊ฐ ์๋ ์๋ก์ด ์ํ
```java
Member member = new Member("kim");
```
### ์์
์์์ฑ ์ปจํ
์คํธ์ ๊ด๋ฆฌ๋๋ ์ํ
```java
Member member = new Member("kim");
EntityMangager em = entityManagerFactory.createEntityManager();
em.persist(member); // ์ด์ ์์์ฑ ์ปจํ
์คํธ์์ ๊ด๋ฆฌํ๋ค.
```
em.persist(member); ๋ฅผ ํ๋ค๊ณ DB์ ์ ์ฅ๋๋ ๊ฒ์ ์๋๋ค. `์ปค๋ฐ` ํน์ `flush()` ์ดํ์ DB์ ์ ์ฅ๋๋ค. ๊ทธ์ ๊น์ง๋ ์์์ฑ ์ปจํ
์คํธ์๋ง ์กด์ฌ.
### ์ค์์
์์์ฑ ์ปจํ
์คํธ์ ์ ์ฅ๋์๋ค๊ฐ ๋ถ๋ฆฌ๋ ์ํ
```java
Member member = new Member("kim");
EntityMangager em = entityManagerFactory.createEntityManager();
em.detach(member);
```
๊ฐ๋ฐ์๊ฐ ์ง์ ์ค์์์ ๋ง๋ค ์ผ์ ๊ฑฐ์ ์์
## ํธ๋์ญ์
- em.persist() ํธ๋์ญ์
์ด ์ปค๋ฐ๋๋ฉด์ ์์์ฑ ์ปจํ
์คํธ๊ฐ ํ๋ฌ์ ๋๋ค. ์ด๋ ํธ๋์ญ์
๊ณผ ์์์ฑ ์ปจํ
์คํธ๊ฐ ์ข
๋ฃ๋๋ค.
- em.findById() ์ ์ฅํ ์ํฐํฐ๋ฅผ ์กฐํํ๋ฉด ์๋ก์ด ์์์ฑ ์ปจํ
์คํธ๊ฐ ์์ฑ๋๋ค.
## ์ฐ๊ด ๊ด๊ณ ์ฐธ์กฐ ๋ฐ ์กฐ์ธ
์ค๋ฌด JPA์์๋ @OneToMany, @ManyToMany ์กฐ์ธ ์ฌ์ฉ์ ์ง์ํ๋ค. (@ManyToOne ๋ ๋๋๋ก์ด๋ฉด ์ฌ์ฉํ์ง ์๋๋ค๊ณ ํ๋ค.)
DB์ ๊ด๊ณ๋ฅผ ๋งบ๋ ์๊ฐ ๊ท๋ชจ๊ฐ ์ปค์ง ์๋ก ์์ ์ ์ ์ฝ์ด ๋ฐ๋ฅด๊ณ , ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ์์๋ ๋ฌดํ๋ฃจํ ๋ฑ, ํนํ JPA์์๋ ์์์ฑ ์ ์ด๋ ๊ณ ์๊ฐ์ฒด์ ๋ํ ์ง์์ด ๋ถ์กฑํ๋ฉด ๋ฏธ๊ถ์ ๋น ์ง๊ธฐ ์ฝ์์ด๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ง๋ง, ์๊ณ ์ฌ์ฉํ์ง ์๋๊ฑฐ์ ์ฌ์ฉํด๋ณด์ง ์๊ณ ์ฌ์ฉํ์ง ๋ง๋ผํ์ฌ ์ฌ์ฉํ์ง ์๋๊ฒ์ ์ฒ์ง์ฐจ์ด ์ด๊ธฐ ๋๋ฌธ์ ์ด ํ๋ก์ ํธ์์๋ ๋ค์ํ ์ฐ๊ด ๊ด๊ณ ์กฐ์ธ ๋ฐฉ์์ ์ฌ์ฉํด๋ณด๋ฉฐ ํ์ตํ๋ค.
## ์ํฐํฐ ๊ทธ๋ํ
์ํฐํฐ ์กฐํ์์ ์ ์ฐ๊ด๋ ์ํฐํฐ๋ค์ ํจ๊ป ์กฐํํ๋ ๊ธฐ๋ฅ์ด๋ค.
### 1. Named ์ํฐํฐ ๊ทธ๋ํ
### @NamedEntityGraph๋ก ์ ์ํ๋ค.
```java
@NamedEntityGraph(name = "Order.withMember", attributeNodes = {@NamedAttributeNode("member"})
@Entity
public class Order {
...
}
```
### ์ํฐํฐ ๊ทธ๋ํ ์ฌ์ฉ
```java
EntityGraph graph = em.getEntityGraph("Order.withMember");
Map hints = new HashMap();
hints.put("javax.persistence.fetchgraph", graph);
Order order = em.find(Order.class, orderId, hinst);
```
### 2. JPQL์์ ์ํฐํฐ ๊ทธ๋ํ
```java
List resultList =
em.createQuery("select o from Order o where o.id = :orderId", Order.class
.setParameter("orderId", orderId)
.setHint("javax.persistence.fetchgraph", e.getEntityGraph("Order.withAll"))
.getResultList();
```
## ์ด๋
ธํ
์ด์
### @Transactional(readonly = true)
๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ์ง ์๋ ํธ๋์ญ์
์์ ํ๋ฌ์๋ฅผ ์๋ตํ์ฌ ์ฝ๊ฐ์ ์ฑ๋ฅ ํฅ์์ ์ป์ ์ ์๋ค.
### @DiscriminatorColumn
Item ํด๋์ค์ ํ์ ํด๋์ค๋ฅผ ์๋ณํ๋ ๋ฐ ์ฌ์ฉ๋ ์ปฌ๋ผ์ ์ง์ ํ๊ณ , `@DiscriminatorValue`๋ ๊ฐ ํ์ ํด๋์ค๊ฐ ํด๋น ์ปฌ๋ผ์ ์ ์ฅ๋ ๊ฐ์ ๋ช
์ํฉ๋๋ค.
๋ฐ๋ผ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ
์ด๋ธ์์ `DTYPE` ์ปฌ๋ผ์ 'A'๊ฐ์ ๊ฐ์ง ๋ ์ฝ๋๋ Album ์ธ์คํด์ค์ ํด๋นํ๊ณ , 'B'๊ฐ์ ๊ฐ์ง ๋ ์ฝ๋๋ Book์ ์ธ์คํด์ค์ ํด๋นํฉ๋๋ค.
## N+1
์ง์ฐ๋ก๋ฉ์ ์ฌ์ฉํ๋, JPQL ํ์น ์กฐ์ธ์ ์ฌ์ฉํ์.
- @OneToOne, @ManyToOne: ๊ธฐ๋ณธ ํ์น ์ ๋ต์ ์ฆ์๋ก๋ฉ
- @OneToMany, @ManyToMany: ๊ธฐ๋ณธ ํ์น ์ ๋ต์ ์ง์ฐ๋ก๋ฉ
๋ฐ๋ผ์ ๊ธฐ๋ณธ๊ฐ์ด ์ฆ์ ๋ก๋ฉ์ธ @OnetoOne, @ManyToOne์ `fetch = FetchType.LAZY`๋ก ์ค์ ํด์ ์ง์ฐ ๋ก๋ฉ ์ ๋ต์ ์ฌ์ฉํ๋๋ก ํ์.
## ์ฝ๊ธฐ ์ ์ฉ ์ฟผ๋ฆฌ ์ฑ๋ฅ ์ต์ ํ
์ํฐํฐ๊ฐ ์์์ฑ ์ปจํ
์คํธ์ ๊ด๋ฆฌ๋๋ฉด 1์ฐจ ์บ์๋ถํฐ ๋ณ๊ฒฝ ๊ฐ์ง๊น์ง ์ป์ ์ ์๋ ํํ์ด ๋ ๋ง๋ค. ํ์ง๋ง ์์์ฑ ์ปจํ
์คํธ๋ ๋ณ๊ฒฝ๊ฐ์ง๋ฅผ ์ํด ์ค๋
์ท ์ธ์คํด์ค๋ฅผ ๋ณด๊ดํ๋ฏ๋ก ๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๋จ์ ์ด ์๋ค. ์๋ฅผ ๋ค์ด 100๊ฑด์ ๊ตฌ๋งค ๋ด์ฉ์ ์ถ๋ ฅํ๋ ๋จ์ํ ์กฐํ๊ฐ ์๋ค๊ณ ๊ฐ์ ํด๋ณด์. ๊ทธ๋ฆฌ๊ณ ์กฐํํ ์ํฐํฐ๋ฅผ ๋ค์ ์กฐํํ ์ผ๋ ์๊ณ ์์ ํ ์ผ๋ ์์ด ๋ฑ ํ๋ฒ๋ง ํ๋ฉด์ ์ถ๋ ฅํ๋ฉด ๋๋ค. ์ด๋๋ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ํฐํฐ๋ฅผ ์กฐํํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ต์ ํ ํ ์ ์๋ค.
### @Transactional(readOnlny = true)
์คํ๋ง ํ๋ ์์ํฌ๊ฐ ํ์ด๋ฒ๋ค์ดํธ ์ธ์
์ ํ๋ฌ์ ๋ชจ๋๋ฅผ MANUAL๋ก ์ค์ ํ๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๊ฐ์ ๋ก ํ๋ฌ์๋ฅผ ํธ์ถํ์ง ์๋ ํ ํ๋ฌ์๊ฐ ์ผ์ด๋์ง ์๋๋ค. ๋ฐ๋ผ์ ํธ๋์ญ์
์ ์ปค๋ฐํด๋ ์์์ฑ ์ปจํ
์คํธ๋ฅผ ํ๋ฌ์ ํ์ง์๋๋ค. ์์์ฑ ์ปจํ
์คํธ๋ฅผ ํ๋ฌ์ ํ์ง ์์ผ๋ ๋ฑ๋ก, ์์ , ์ญ์ ๋ ๋น์ฐํ ๋์ํ์ง ์๋๋ค. ํ์ง๋ง ํ๋ฌ์ํ ๋ ์ผ์ด๋๋ ์ค๋
์ท ๋น๊ต์ ๊ฐ์ ๋ฌด๊ฑฐ์ด ๋ก์ง๋ค์ ์ํํ์ง ์์ผ๋ฏ๋ก ์ฑ๋ฅ์ด ํฅ์๋๋ค. ํธ๋์ญ์
๊ณผ์ ์ ์ด๋ฃจ์ด์ง๋ ๋จ์ง ์์์ฑ ์ปจํ
์คํธ๋ฅผ ํ๋ฌ์ํ์ง ์์ ๋ฟ์ด๋ค.
## @PersistenceContext ๋?
- EntityManager๋ฅผ ๋น์ผ๋ก ์ฃผ์
ํ ๋ ์ฌ์ฉํ๋ ์ด๋
ธํ
์ด์
- ์คํ๋ง์์๋ ์์์ฑ ๊ด๋ฆฌ๋ฅผ ์ํด EntityManager๊ฐ ์กด์ฌ
- ์คํ๋ง ์ปจํ
์ด๋๊ฐ ์์๋ ๋ EntityManager๋ฅผ ๋ง๋ค์ด์ ๋น์ผ๋ก ๋ฑ๋ก
- ์ด ๋ ์คํ๋ง์ด ๋ง๋ค์ด๋ EntityManager๋ฅผ ์ฃผ์
๋ฐ์ ๋ ์ฌ์ฉ
- @PersistenceContext๋ก ์ง์ ๋ ํ๋กํผํฐ์ ์๋ ๋ ๊ฐ์ง ์ค ํ ๊ฐ์ง๋ก EntityManager๋ฅผ ์ฃผ์
- EntityManagerFactory์์ ์๋ก์ด EntityManager๋ฅผ ์์ฑํ๊ฑฐ๋ Transaction์ ์ํด ๊ธฐ์กด์ ์์ฑ๋ EntityManager๋ฅผ ๋ฐํ
### @PersistenceContext๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ์ด์
#### EntityManager๋ฅผ ์ฌ์ฉํ ๋ ์ฃผ์ํด์ผ ํ ์
์ฌ๋ฌ ์ฐ๋ ๋๊ฐ ๋์์ ์ ๊ทผํ๋ฉด ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ฌ ์ฐ๋ ๋ ๊ฐ์๋ EntityManager๋ฅผ ๊ณต์ ํด์๋ ์๋ฉ๋๋ค. ํ์ง๋ง ์คํ๋ง์ ์ฑ๊ธํค ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๊ธฐ์ ๋น์ ๋ชจ๋ ์ฐ๋ ๋๊ฐ ๊ณต์ ๋ฉ๋๋ค.
**๊ทธ๋ฌ๋ @PersistenceContext์ผ๋ก EntityManager๋ฅผ ์ฃผ์
๋ฐ์๋ ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋ ์ด์ ๋**
- ์คํ๋ง ์ปจํ
์ด๋๊ฐ ์ด๊ธฐํ๋๋ฉด์ @PersistenceContext์ผ๋ก ์ฃผ์
๋ฐ์ EntityManager๋ฅผ Proxy๋ก ๊ฐ์๋๋ค.
- ๊ทธ๋ฆฌ๊ณ EntityManager ํธ์ถ ์ ๋ง๋ค Proxy๋ฅผ ํตํด EntityManager๋ฅผ ์์ฑํ์ฌ Thread-Safe๋ฅผ ๋ณด์ฅํฉ๋๋ค.