일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- BFS
- 언리얼엔진
- 이분탐색
- Unity3d
- unityui
- 스택
- 프로그래머스
- 포톤
- 알고리즘
- 스파르타내일배움캠프TIL
- 유니티
- 해시
- UE4
- 유클리드호제법
- 워크플로
- 문자열
- 구현
- 순열
- Photon
- 내일배움캠프
- QueryDSL
- Unity2D
- Firebase
- FSM
- Unity
- Inventory
- c#
- C++
- UnrealEngine
- 스파르타내일배움캠프
Archives
- Today
- Total
개발 낙서장
[TIL] 내일배움캠프 53일차 - 불필요한 쿼리 개선 본문
오늘의 학습 키워드📚
QueryDSL 페이징 + 성능 개선
https://dachomi97.tistory.com/130
[Spring] QueryDSL 페이징
QueryDSL 페이징? 기존에 레포지토리에서 페이징 된 값을 받을 때처럼 Pageable 객체를 만들어 페이지 정보를 보내 QueryDSL로 작성된 쿼리문을 통해 받아오면 된다. List content = queryFactory.selectFrom(todo).wh
dachomi97.tistory.com
불필요한 조회 쿼리 개선
Todo에 관한 쿼리를 수행할 때 User 조회 쿼리도 항상 같이 날아가는 이슈가 있었다.
Hibernate:
/* select
todo
from
Todo todo
where
todo.user = ?1 */ select
t1_0.todo_id,
t1_0.content,
t1_0.created_at,
t1_0.finished,
t1_0.modified_at,
t1_0.todo_name,
t1_0.user_id
from
todo_tb t1_0
where
t1_0.user_id=?
limit
?, ?
Hibernate:
select
u1_0.user_id,
u1_0.created_at,
u1_0.email,
u1_0.modified_at,
u1_0.password,
u1_0.role,
u1_0.user_name
from
user_tb u1_0
where
u1_0.user_id=?
특정 유저의 Todo를 조회한 후 해당 User를 찾는 쿼리가 또 날아간다.
왜 이럴까 고민을 했는데 Dto에서 Entity를 다루려 했기 때문에 발생한 이슈였다.
@Getter
@ToString(exclude = {"createdAt", "modifiedAt"})
public class TodoResponseDto {
private String userName;
private String todoName;
private String content;
private boolean finished;
private LocalDateTime createdAt;
private LocalDateTime modifiedAt;
public TodoResponseDto(Todo todo) {
this.userName = todo.getUser().getUserName();
this.todoName = todo.getTodoName();
this.content = todo.getContent();
this.finished = todo.isFinished();
this.createdAt = todo.getCreatedAt();
this.modifiedAt = todo.getModifiedAt();
}
}
TodoResponseDto를 생성할 때 userName을 todo의 getUser를 통해 가져오고 있었다.
저 한 줄 때문에 todo에서 getUser를 하면서 해당 유저를 조회하는 쿼리가 실행되는 것이었다.
그냥 userName만 필요한 것이기 때문에 생성자를 바꿔주었다.
@Getter
@ToString(exclude = {"createdAt", "modifiedAt"})
public class TodoResponseDto {
private String userName;
private String todoName;
private String content;
private boolean finished;
private LocalDateTime createdAt;
private LocalDateTime modifiedAt;
public TodoResponseDto(Todo todo, User user) {
this.userName = user.getUserName();
this.todoName = todo.getTodoName();
this.content = todo.getContent();
this.finished = todo.isFinished();
this.createdAt = todo.getCreatedAt();
this.modifiedAt = todo.getModifiedAt();
}
}
Controller에서 받아온 인증된 User 객체를 Service에서 받아와 생성자에 넣어주어 불필요한 쿼리를 방지했다.
public Page<TodoResponseDto> getTodosByUser(Long userId, int page, int size, boolean isAsc,
String sortBy, User user) {
if (!userId.equals(user.getUserId())) {
throw new IllegalArgumentException("유저 정보가 일치하지 않습니다.");
}
// 페이징 처리
Sort.Direction direction = isAsc ? Direction.ASC : Direction.DESC;
Sort sort = Sort.by(direction, sortBy);
Pageable pageable = PageRequest.of(page, size, sort);
Page<Todo> todos = todoRepository.findAllByUser(user, pageable);
return todos.map(todo -> new TodoResponseDto(todo, user));
}
오늘의 회고💬
QueryDSL에서 페이징을 하는 방법, 성능을 개선하는 방법을 공부하면서 의문점이 많이 생겨 시간을 꽤 쏟았던 것 같다.
내일의 계획📜
내일은 예비군이다....
'Java > Sparta' 카테고리의 다른 글
[TIL] 내일배움캠프 55일차 - Git Commit 잔디 (0) | 2024.03.15 |
---|---|
[TIL] 내일배움캠프 54일차 - 설정 파일 분리 (0) | 2024.03.14 |
[TIL] 내일배움캠프 52일차 - 페이징 (0) | 2024.03.11 |
[TIL] 내일배움캠프 51일차 - 로그인 페이지 (0) | 2024.03.08 |
[TIL] 내일배움캠프 50일차 - Query DSL (0) | 2024.03.07 |
Comments