Loading...

Spring/Blog-V1 / / 2022. 3. 10. 11:42

스프링 30강. JPA 쿼리 기본 전략

반응형

 

터미널 창에 SQL 쿼리를 예쁘게 정렬해서 보여주는 설정이다.

application.yml 파일에 추가해주자.

spring:
  jpa:
  properties:
    hibernate.format_sql: true

 

터미널 창을 clear 하기 위해서는

Ctrl + Shift + A 커맨드 팔레트를 열어서

terminal:clear를 검색해줘야 한다.

 

과정이 귀찮으니까 오른쪽 설정 아이콘을 눌러 단축키를 설정해주자.

 

키 바인딩 빈칸을 더블클릭해

원하는 단축키를 설정해주면 된다.

Ctrl + Shift + C로 설정해주었다.

 


 

이제 서버를 시작시키고 메인 페이지에 들어가 보면

post를 findAll( ) 하는데

이때 터미널 창에서 쿼리를 확인해보자.

post만 SELECT 해오는 게 아니라

user까지 SELECT 하여 총 3번의 SELECT가 발생했다.

왜 user까지 찾아온 것일까?

 

post 테이블에 user 오브젝트가 연관되어 있기 때문이다.

 


 

(1)

 

지금 메인 페이지의 디폴트 전략은

post테이블의 글을 다 들고 오고

글을 쓴 1번, 2번 user 정보를 다 들고 왔다.

 

1. SELECT * FROM post

2. user SELECT

3. user SELECT

 

만약 1000명의 유저가 있으면

모든 글을 다 들고 오고,

1000명의 유저 select를 1000번 할 것이다.

 

성능이 좋지 않은 쿼리이다.

 

(2)

 

유저의 정보가 필요하다면

post와 user를 조인을 사용해 한번에 들고 올 수도 있겠다.

SELECT *
FROM post p left outer join user u
on p.userId = u.id;

 

(3)

 

하지만 우리가 만드는 블로그의 메인 페이지에는

뿌려줄 유저 정보가 없기 때문에

user을 SELECT 할 필요가 없다.

 

그냥 post만 SELECT 하면 되겠다.

SELECT * FROM post;

 


 

그렇다면 왜 디폴트가 첫 번째 쿼리일까?

 

일단 user 정보까지 가져와놓으면 사용하고 싶을 때 사용할 수 있기 때문이다.

 

메서드를 만들어주는 JPA 입장에서는 사용하는 사람이

user까지 사용할 수도 있다고 생각하면서 만들 수밖에 없다.

 

사용하지 않으면 그냥 안 쓰면 그만인데

필요할 수도 있기 때문에 가져와주는 것이다.

쿼리의 성능은 좋지 않아도 사용하는 사람에게 자유도를 주는 것이다.

 

JPA를 상속받아 사용한다고 하더라도

어떤 쿼리가 내 페이지에 제일 좋은지 알아야 뜯어고칠 수 있다.

 


 

제일 좋은 쿼리가 (3) post만 가져오는 거라고 생각했으면

바꿀 수도 있어야 한다.

 

post만 SELECT 하고 싶어서 findAll( ) 메서드를 사용하지 않고

mFindAll( ) 메서드를 만들어보았다.

package site.metacoding.dbproject.domain.post;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

@Repository
public interface PostRepository extends JpaRepository<Post, Integer> {
    @Query(value = "SELECT * FROM post", nativeQuery = true)
    Post mFindAll();
}

그리고 메인 페이지 메서드에서 findAll( )이 아닌

mFindAll( ) 메서드를 호출해보자.

 

그래도 결과는 같았다.

 

post에 user 오브젝트가 연관되어 있기 때문이다.

오브젝트가 연관되어 있으면

자동으로 SELECT 한다.

 


 

글 상세보기 페이지에서는 어떤 쿼리가 나올까?

 

자동으로 post와 user가 조인하여 실행되었다.

나는 post만 SELECT 했는데 JPA가 조인까지 해준 것이다.

 


 

하나씩 확인해보며 알 수 있는 쿼리 기본전략이 있다.

 

1. post 전체를 SELECT 하면 (SELECT * FROM post)

- post를 다 가져오고

- post를 다 가지러 갔더니 User 오브젝트도 필요하네?

각각의 User 오브젝트 SELECT

 

2. 하나의 post SELECT 하면

- post, user를 조인해서 가져온다.

 

 

∴ 하나의 값을 가져올 때는 조인해서 가져오고

전체를 가져올 때는 한방에 가져왔다가 필요한 만큼 다시 하나씩 쏙쏙 찾아준다.

 

이런 쿼리 전략을 바꾸기 위해서는 JPA Fetch 전략을 알아야 한다.

 

 

 

 

[출처]

 

https://cafe.naver.com/metacoding

 

메타코딩 : 네이버 카페

코린이들의 궁금증

cafe.naver.com

메타 코딩 유튜브

https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9

 

메타코딩

문의사항 : getinthere@naver.com 인스타그램 : https://www.instagram.com/meta4pm 깃헙 : https://github.com/codingspecialist 유료강좌 : https://www.easyupclass.com

www.youtube.com

반응형