본문 바로가기

개발관련/TIL

내배캠 11주 2일 차

 오늘은 과제 진행과 강의 영상을 봤다. 뭔가 많은 것을 하진 않았는데 하루가 벌써 끝나간다. 뭔가 쓸 내용이 없는 거 같아서 과제는 뭘 했는지에 대한 것을 써보겠다.

 

 과제는 게시물의 좋아요 추가, 삭제 기능과 계정 생성 시 비밀번호 암호화 하기를 했다. 그리고 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