Skip to content

Commit bd9cfd3

Browse files
committed
keyword: 6주차 키워드 정리
1 parent 2614375 commit bd9cfd3

8 files changed

Lines changed: 240 additions & 1 deletion

File tree

keyword/chapter05/keyword.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
-피어리뷰(스프링A팀 빈)
1+
22
![img_1.png](img_1.png)
33
![img_2.png](img_2.png)
44
![img_3.png](img_3.png)

keyword/chapter06/img.png

114 KB
Loading

keyword/chapter06/keyword.md

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
- JPA란?
2+
3+
JPA(Java Persistence API)란,
4+
**자바 진영에서 ORM(Object-Relational Mapping) 기술의 표준으로 사용되는 인터페이스의 모음**
5+
6+
⇒ 즉, 실제로 동작하는 것이 아닌 인터페이스를 구현하여 사용해야 한다.
7+
8+
- 구현체 종류
9+
- JPA표준을 엄격하게 준수할수록 다른 구현체로의 전환성을 높이고,
10+
표준 기능을 적용하는데 도움이 된다.
11+
- Hibernate
12+
- EclipseLink
13+
- DataNucleus
14+
- OpenJPA
15+
- ![img.png](img.png)
16+
17+
JPA 어노테이션(워크북 기준)
18+
19+
- @Entity: DB 테이블과 일대일로 매칭되는 객체 단위, 클래스를 테이블과 매핑한다고 알려줌
20+
- @Table: 엔티티로 선언된 클래스에 매핑할 테이블이름,
21+
이 어노테이션이 없으면 클래스 이름을 테이블 이름으로 매핑한다.
22+
- @Column: DB 테이블에 있는 속성에 자바 필드를 매핑한다.
23+
- @Id: 클래스의 필드를 DB 테이블의 기본키로 매핑한다.
24+
- @GeneratedValue: 새로운 인스턴스 생성 시 마지막 값에서
25+
자동으로 +1 해줘야 하는 컬럼인 것을 알려준다. ex) PK
26+
- @Enumerated: Enum 형태로 되어있는 미리 정의되어 있는 코드 값이나 구분값을
27+
데이터 타입으로 사용할 때 작성한다.
28+
29+
- 장단점
30+
- 생산성 향상
31+
- JPA에 객체를 전달만 하면 되므로 SQL, JDBC 를 사용하는 반복적인 작업을 JPA가 대신 처리한다.
32+
- 유지보수
33+
- SQL을 직접 다루면 필드 하나 추가해도 전부 수정해야 했지만, JPA는 이를 대신 처리한다.
34+
- 벤더 독립성
35+
- RDB는 같은 기능이라도 벤더마다 사용법이 다른데 JPA는 추상화된(인터페이스) 데이터 접근을 제공하므로 종속되지 않도록 도와준다.
36+
- 학습 곡선이 높음
37+
- 영속성 컨텍스트를 이해하지 못하면 잘 활용하지 못할 수 있다.
38+
- 관계형 DB의 맵핑 방법도 학습해야 한다.
39+
- 속도 저하 가능성
40+
- 복잡하고 무거운 쿼리는 속도를 위해 SQL문을 작성하는 것이 나을 수도 있다.
41+
42+
- N+1 문제란?
43+
44+
연관 관계에서 발생하는 이슈로 연관 관계를 가지는 엔티티를 조회할 경우에
45+
데이터 개수(N)만큼 조회 쿼리가 추가로 발생하여 데이터를 읽어오는 문제를 말한다.
46+
47+
**⇒ 불필요한 쿼리 수행은 통신 비용과 지연을 증가시켜 성능을 저하시킬 수 있다!**
48+
49+
- 지연 로딩에서도 발생한다.
50+
- 사용되지 않는 엔티티를 프록시 객체로 두었다.
51+
- 데이터에 접근하는 순간, N+1 문제가 발생한다.
52+
53+
**발생이유**
54+
55+
JpaRepository에 정의한 인터페이스 메소드 실행
56+
57+
1. JPA가 메서드 이름을 분석해서 JPQL생성
58+
⇒ JPQL은 특정 SQL에 종속되지 않고 엔티티 객체와 필드 이름을 가지고 쿼리를 보낸다.
59+
2. findAll() 메소드를 수행하였을 때 해당 엔티티를 조회하는
60+
<select * from 테이블명> 쿼리만 실행한다.
61+
⇒JPQL 입장에서는 연관관계 데이터를 무시하고 해당 엔티티 기준으로 쿼리를 조회한다.
62+
3. **FetchType으로 지정한 시점**에 조회를 별도로 호출하게 된다.(EAGER이든 LAZY이든 발생!)
63+
64+
65+
- 지연로딩과 즉시로딩의 차이는?
66+
67+
FetchType이란, JPA가 하나의 Entity를 조회할 때 연관관계에 있는 객체들을 어떻게 가져올 지
68+
나타내는 설정값이다.
69+
70+
- **fetch = fetchType.EAGER 즉시로딩**
71+
- 데이터를 조회할 때, 연관된 모든 객체의 데이터까지 한 번에 불러오는 것이다.
72+
- ex) 게시물 10개, 게시물 1개에 달린 댓글 여러 개
73+
- 애플리케이션 단에서 게시물 10개를 요청하면 DB에서
74+
게시물 10개를 조회하는 쿼리(1)와 동시에 댓글(10개의 게시물)까지 다 준다고 생각
75+
76+
```sql
77+
SELECT * FROM post; //게시글 10개 조회 - 1번
78+
SELECT * FROM comment WHERE post_id = 1; //1번 게시글의 댓글 조회
79+
SELECT * FROM comment WHERE post_id = 2; //2번 게시글의 댓글 조회
80+
,,,
81+
,,
82+
,
83+
```
84+
- **fetch = fetchType.LAZY 지연로딩**
85+
- 필요한 시점에 연관된 객체의 데이터를 불러오는 것이다.
86+
- ex) 게시물 10개, 게시물 1개에 달린 댓글 여러 개
87+
- 게시글 10개 조회 쿼리(1) / 나중에 댓글 데이터 사용 시 쿼리가 **1번씩** 발생
88+
89+
90+
- JPQL란?
91+
92+
**Java Persistence Query Language**
93+
94+
SQL을 기반으로 한 객체 모델용 쿼리 언어
95+
96+
- SQL과 매우 유사한 형태지만, DB의 테이블과 컬럼이 아닌 자바 클래스와 객체에 작업을 수행한다.
97+
- 엔티티를 대상으로 쿼리를 수행한다고 생각하자
98+
99+
- 예시
100+
101+
```sql
102+
Query query = em.createQuery(
103+
"select u from UserEntity u where u.id = :id"
104+
);
105+
```
106+
107+
- 특징 & 장점
108+
- 기본적인 연산 지원
109+
- select, update, delete 등 기본적인 연산 지원, 키워드 제공
110+
- 객체지향 쿼리 언어
111+
- 쿼리 결과를 객체 또는 객체의 컬렉션으로 직접 반환받을 수 있다.
112+
- 타입 안정성 제공
113+
- **컴파일 오류**를 활용할 수 있다.
114+
115+
- Spring Data JPA와의 차이
116+
- Spring Data JPA에서 제공하는 인터페이스로 JPA를 아주 쉽게 사용할 수 있다.
117+
- 인터페이스 생성만으로 간단하게 CRUD를 사용할 수 있다.
118+
- 복잡한 쿼리는 JPQL이 더 효율적이다.
119+
120+
- JPQL쿼리 2가지 방식
121+
- TypedQuery: 반환하는 타입이 명확할 떄 사용하는 클래스
122+
- 미리 타입을 지정하므로 컴파일 오류 활용 가능
123+
124+
```sql
125+
TypedQuery<UserEntity> typedQuery = em.createQuery("~");
126+
127+
```
128+
129+
- Query: 반환하는 타입이 명확하지 않을 떄 사용하는 클래스
130+
- 다양한 타입 반환, 런타임 시점에 오류 체크
131+
132+
```sql
133+
Query query = em.createQuery("~");
134+
Object result = query.getSingleResult();
135+
```
136+
137+
-
138+
- 쿼리 결과 조회 방식
139+
- getSingleResult()
140+
- 쿼리의 결과로 단일 엔티티 객체 반환 → 없거나 2개 이상이면 예외 발생
141+
- getResultList()
142+
- 쿼리의 결과를 List 형태의 객체로 반환 → 없으면 빈 리스트 반환
143+
144+
- 단점
145+
- 동적 쿼리 사용 어려움
146+
- 실행 시점에 SQL문이 결정되는 쿼리
147+
- SQL의 모든 기능 사용 못함
148+
- 복잡한 JOIN 문제
149+
150+
- Fetch Join란?
151+
152+
JPQL에서 성능 최적화를 위해 제공하는 기능이다.
153+
154+
SQL의 조인 종류는 아님!
155+
156+
⇒연관된 엔티티나 컬렉션을 쿼리문 한 번으로 함께 조회하는 기능
157+
158+
- 사용
159+
- join fetch 명령어로 사용한다.
160+
161+
```sql
162+
String query "select b from Book b join fetch b.library";
163+
164+
List<Book>books = em.createQuery(query, Book.class).getResultList();
165+
166+
for(Book book: books){
167+
System.out.println(book.getLibrary());
168+
}
169+
```
170+
171+
- JOIN 쿼리문이 나가면서 데이터가 함께 조회된다.
172+
⇒ 추가적인 쿼리가 나가지 않는다.
173+
- 만약 컬렉션에서 사용한다면 DISTINCT 명령를 통해 중복 데이터를 거를 수 있다.
174+
175+
- 특징
176+
- fetchType은 엔티티에 직접 적용하는 로딩 전략으로 글로벌 로딩 전략이라고 부른다.
177+
- fetch join은 글로벌 로딩보다 우선시된다.
178+
⇒ LAZY로 설정해도 fetch join을 사용하면 데이터가 즉시 조회되는 결과를 가져오게 된다.
179+
- 글로벌 로딩 전=LAZY, 최적화 필요 시 = fetch join
180+
181+
- 장단점
182+
- fetch join 대상에 별칭을 줄 수 없다. (지원하는 곳도 있음)
183+
- 둘 이상의 컬렉션을 fetch할 수 없다. (컬렉션 * 컬렉션 의 cartesian product가 만들어짐)
184+
- 페이징 API를 사용할 수 없다. (하나의 쿼리문으로 데이터를 가져옴)
185+
- N+1 문제를 해결할 수 있다.
186+
- 단일 쿼리 조회를 이용 → 객체 그래프 일관성을 유지할 수 있다.
187+
188+
- @EntityGraph란?
189+
190+
Spring Data JPA에서 JPA가 제공하는 엔티티 그래프 기능을 편리하게 사용하도록 제공하는 기능이다.
191+
192+
⇒ JPQL로 fetch join을 직접 작성하지 않고 @EntityGraph 어노테이션을 붙임으로서 **fetch join을 사용**
193+
194+
ex)Member 조회할 때 Team도 같이 조회하는 경우
195+
196+
```sql
197+
@EntityGraph(attributePaths = {"team"})//연관된 엔티티 지정
198+
List<Member> findAll();
199+
```
200+
201+
- 주의점
202+
- @EntityGraph는 left outer join만을 지원한다.
203+
204+
- commit과 flush 차이점은?
205+
206+
영속성 컨텍스트 ⇒ Entity 객체를 영속성 상태로 관리하는 공간
207+
208+
**영속성**”: DB와 동기화하여 오래 지속 되도록 하는 것
209+
210+
JPA에서는 EntityManager를 통해 Persistence Context에 접근할 수 있다.
211+
212+
- persist()
213+
- 1차 캐시 저장소에 저장된다.
214+
- DB에 들어간 건 아니다.
215+
- SQL은 쓰기 지연 저장소에 저장된다.
216+
- flush()
217+
- persist()로 준비한 단계, 즉 영속성 컨텍스트의 변경 내용을 DB와 동기화
218+
- 아직 Context가 비워지지 않음 → 우리는 확인 가능하다.
219+
만약 옆에 있는 동료가 DB를 조회한다면? → 아직 변경 결과 나오지 않음
220+
- **SQL실행만 하고 트랜잭션 유지**
221+
- commit()
222+
- DB에 실제 반영!
223+
- 내 Context 에서 뿐만 아니라 다른 사람도 반영 결과를 볼 수 있다. → 영속성을 가지게 된다.
224+
- **flush() 실행 후 트랜잭션 종료**
225+
226+
- flush가 자동 실행되는 경우
227+
- commit()을 호출할 때 내부적으로 자동 flush() 호출된다.
228+
- JPQL실행 시 자동 실행된다.
229+
- flush() 모드 설정 → JPA 기본 설정은 AUTO모드이다.
230+
231+
```sql
232+
em.setFlushMode(FlushModeType.AUTO); // (기본값)
233+
234+
```

mission/chapter05/img.png

49.8 KB
Loading

mission/chapter05/img_1.png

44.8 KB
Loading

mission/chapter05/img_2.png

34.3 KB
Loading

mission/chapter05/mission.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-피어리뷰(스프링A팀 빈)
2+
![img.png](img.png)
3+
![img_1.png](img_1.png)
4+
![img_2.png](img_2.png)

mission/chapter06/mission.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-피어리뷰(스프링A팀 빈)

0 commit comments

Comments
 (0)