BoardRepository에서 JPQL로 만들면 쿼리가 어떻게 발생하는지 알아보자!
필기
유효성 검사 - onsubmit
JPA
게시글 목록에서 User 테이블 필요
board를 조회할때 jpa를 사용하면 board 조회 시 user도 join한다.
eager = object relation mapping 해 -> join 안하고 select 3번 -> 게시글 쓴 사람이 1번이므로
-> PC에서 캐싱했기 때문에 원래는 user_id를 select로 4번 해야하지만 1번 게시글을 select 하면
lazy =orm 하지마
board 데이터 4건 -> findAll
Board 클래스에 Object Mapping
근데 전략이 eager이면 board에 user_id를 넣는 곳이 없음 -> 객체를 넣어야함
user tb를 조회해서 relation mapping -> 이게 4번 일어나야 하는데 3번뿐 = eager
(근데 쿼리 한번에 i/o이므로 데이터 건수가 많으면 곤란
(n+1 : 연관된 애들 전부 select?)
join해서 넣는 경우 - 이것도 relation mapping에 eager 전략
근데 둘중 어떤 방법 선택했는지는 확인해봐야 알 수 있음
Board에서 User객체는 join해서 바로 넣어주기/ select해서 4번
relation된 객체에 값을 넣어주면 eager이다 -> User
값을 안넣어주면 lazy
lazy일때 - Board의 User에는 조회하는게 아니라 fk인 id=1만 존재 (tb에서 가져온 user_id)
=> boardList.get(0).getUser()까지는 안터짐
// Lazy ->
// Eager ->
// Eager ->
=> 근데 게시글 목록에 당장 user 정보 필요 없으므로
relation mapping을 안하는 lazy 전략을 쓴다!
-> eager로 하면 쓸데없는 정보를 조회하게 될 수 있으므로 lazy로 하고 relation mapping이
필요하면 직접 join하는게 낫다.
-> 무조건 lazy 전략을 쓴다.
서버 사이드 렌더링 서버에서 html화면에 데이터를 붙여서 오는 기술
CSR - 클라이언트 측 언어로 57:00
서버사이드렌더링 모델(request 객체)에 pw같은 보안에 민감한 데이터 줘도 괜찮다
-> 서버에서 request에 담아뒀다가 html화면에 안뿌리면 되기 때문
-> DTO로 데이터를 전달하게 될 경우에는 안된다!
1. Board 조회시 User도 같이 조회될까?
0. Board 클래스
- User는 FetchType을 EAGER으로 설정한다.

1. BoardRepository
public List<Board> findAll() {
Query query = em.createQuery("select b from Board b order by b.id desc", Board.class);
return query.getResultList();
}2. BoardRepositoryTest
- findAll 메서드를 실행하면 어떤 쿼리가 발생하는지 테스트해보자.
- 메서드의 매개변수가 없으므로 given 데이터는 없다.
package shop.mtcoding.blog.board;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import java.util.List;
@Import(BoardRepository.class) // BoardRepository가 메모리(IoC)에 뜬다.
@DataJpaTest // EntityManager, PC가 메모리(IoC)에 뜬다.
public class BoardRepositoryTest {
@Autowired // DI : JUnit에서는 생성자 주입이 불가능하다.
private BoardRepository boardRepository;
@Test
public void findAll_test() {
// given -> 함수의 매개변수(e.g. findById에서는 id)
// when -> 테스트할 함수 호출 -> 쿼리 확인
List<Board> boardList = boardRepository.findAll();
// eye
}
}
3. 쿼리
- Board는 한 번, User는 세 번 조회되는 것을 알 수 있다.
Hibernate:
select
b1_0.id,
b1_0.content,
b1_0.created_at,
b1_0.is_public,
b1_0.title,
b1_0.user_id
from
board_tb b1_0
order by
b1_0.id desc
Hibernate:
select
u1_0.id,
u1_0.created_at,
u1_0.email,
u1_0.password,
u1_0.username
from
user_tb u1_0
where
u1_0.id=?
Hibernate:
select
u1_0.id,
u1_0.created_at,
u1_0.email,
u1_0.password,
u1_0.username
from
user_tb u1_0
where
u1_0.id=?
Hibernate:
select
u1_0.id,
u1_0.created_at,
u1_0.email,
u1_0.password,
u1_0.username
from
user_tb u1_0
where
u1_0.id=?4. 더미데이터 - 게시글

5. EAGER
연관관계가 있는 것까지 같이 조회
6. LAZY
연관된 object mapping 안해줌
user의 getter로 조회하면
2. Board 조회시 User는 몇 번 조회될까? (Test2)
eager = object relation mapping 해 -> join 안하고 select 3번 -> 게시글 쓴 사람이 1번이므로
-> PC에서 캐싱했기 때문에 원래는 user_id를 select로 4번 해야하지만 1번 게시글을 select 하면
lazy =orm 하지마
1. 더미데이터에서 게시글을 쓴 user_id가 전부 1이라면
- 게시글을 조회할 때

n = 연관된 애들의 (relation) 개수 ⇒ n+1??????

3. LAZY 전략
1.
- 무조건 LAZY 전략으로 간다.
- 연관된 객체 조회가 필요하면, 조인쿼리는 직접 작성한다.

getter를 호출할때 user가 조회가 된다.

package shop.mtcoding.blog.board;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import java.util.List;
@Import(BoardRepository.class) // BoardRepository가 메모리(IoC)에 뜬다.
@DataJpaTest // EntityManager, PC가 메모리(IoC)에 뜬다.
public class BoardRepositoryTest {
@Autowired // DI : JUnit에서는 생성자 주입이 불가능하다.
private BoardRepository boardRepository;
@Test
public void findAll_test() {
// given -> 함수의 매개변수(e.g. findById에서는 id)
// when -> 테스트할 함수 호출 -> 쿼리 확인
List<Board> boardList = boardRepository.findAll();
// Lazy -> Board -> User(id=1)
// Eager -> N+1 -> Board조회 -> 연관된 User 유저 수 만큼 주회
// Eager -> Join -> 한방쿼리
System.out.println("--------------------");
boardList.get(0).getUser().getUsername();
System.out.println("--------------------");
// eye
}
}
board 데이터 4건 -> findAll
Board 클래스에 Object Mapping
근데 전략이 eager이면 board에 user_id를 넣는 곳이 없음 -> 객체를 넣어야함
user tb를 조회해서 relation mapping -> 이게 4번 일어나야 하는데 3번뿐 = eager
(근데 쿼리 한번에 i/o이므로 데이터 건수가 많으면 곤란
(n+1 : 연관된 애들 전부 select?)
join해서 넣는 경우 - 이것도 relation mapping에 eager 전략
근데 둘중 어떤 방법 선택했는지는 확인해봐야 알 수 있음
Board에서 User객체는 join해서 바로 넣어주기/ select해서 4번
relation된 객체에 값을 넣어주면 eager이다 -> User
값을 안넣어주면 lazy
lazy일때 - Board의 User에는 조회하는게 아니라 fk인 id=1만 존재 (tb에서 가져온 user_id)
=> boardList.get(0).getUser()까지는 안터짐
// Lazy ->
// Eager ->
// Eager ->
=> 근데 게시글 목록에 당장 user 정보 필요 없으므로
relation mapping을 안하는 lazy 전략을 쓴다!
-> eager로 하면 쓸데없는 정보를 조회하게 될 수 있으므로 lazy로 하고 relation mapping이
필요하면 직접 join하는게 낫다.
-> 무조건 lazy 전략을 쓴다. 
Share article