오늘은 과제 진행과 강의 영상을 봤다. 뭔가 많은 것을 하진 않았는데 하루가 벌써 끝나간다. 뭔가 쓸 내용이 없는 거 같아서 과제는 뭘 했는지에 대한 것을 써보겠다.
과제는 게시물의 좋아요 추가, 삭제 기능과 계정 생성 시 비밀번호 암호화 하기를 했다. 그리고 QueryDsl을 사용해서 게시물 조회시 키워드 검색과 정렬하기를 구현했다. 그리고 게시물 조회할 때 사용자의 정보를 가지고 사용자가 좋아요를 누른 게시물인지에 대한 정보를 DTO(Data Transfer Object)에 담아서 반환했다. 이 과정에서 어려웠던 것은 좋아요를 눌렀는지 확인 후 반환하는 것이었다. 이 과정에 대해서 좀 써보겠다.
처음에는 게시물 조회한 목록을 반환할 때 사용자의 정보와 게시물의 정보를 갖고 좋아요 테이블에서 좋아요를 눌렀는지를 하나씩 확인 하는 방식을 택했다. 그러나 이렇게 하니 게시물을 DTO로 만들 때 마다 좋아요 테이블로 쿼리가 발생했다.
게시물 전체 조회 함수
@Transactional(readOnly = true)
fun getTodos(
topic: String,
keyword: String,
orderBy: String,
ascend: Boolean,
memberId: Long?
): List<TodoResponse> {
val todos: List<Todo> = todoRepository.todoList(topic, keyword, orderBy, ascend)
if (memberId == null) {
return todos.map { it.toResponse(false) }
}
return todos.map { it.toResponse(likeRepository.existsByTodoIdAndMemberId(it.getId()!!,memberId)) }
}
그래서 저런 문제를 해결하기 위해서 좋아요 테이블에서 memberId로 존재하는 값을 한번에 가져온 후 게시물의 id와 좋아요 테이블에 존재하는 게시물 id를 확인해서 있는지로 바꿨더니 쿼리 수가 줄어들었다. 내가 작성한 코드는 다음과 같다.
게시물 전체 조회 함수
@Transactional(readOnly = true)
fun getTodos(
topic: String,
keyword: String,
orderBy: String,
ascend: Boolean,
memberId: Long?
): List<TodoResponse> {
val likeTodoIds : List<Long> = likeRepository.findAllByMemberId(memberId).map {it.getTodoId()}
val todos: List<Todo> = todoRepository.todoList(topic, keyword, orderBy, ascend)
if (memberId == null) {
return todos.map { it.toResponse(false) }
}
return todos.map { it.toResponse(likeTodoIds.find{ item->item==it.getId()!!} != null) }
}
문제는 게시물 정보를 DTO로 바꿀 때 매번 좋아요 테이블에 쿼리를 날려서였기 때문이다. 처음에는 N+1문제인 줄 알았으나 조금 달랐던 거 같다.
'개발관련 > TIL' 카테고리의 다른 글
내배캠 11주 4일 차 (0) | 2024.06.27 |
---|---|
내배캠 11주 3일 차 (0) | 2024.06.27 |
내배캠 11주 1일 차 (0) | 2024.06.24 |
내배캠 10주 5일 차 (0) | 2024.06.21 |
내배캠 10주 4일차 (0) | 2024.06.20 |