Spring/게시판 만들기

검색 기능 만들기(동적쿼리) - Querydsl 사용

민철킹 2021. 6. 30. 23:30

현재 Spring Security를 사용하여 로그인, 로그아웃을 구현한 상태이고 인증(로그인)하지 않은 사용자는 게시판에 접속할 수 없도록 구현해놓았다.

 

Controller

파라미터로 page(페이징 변수), category(카테고리별 조회), myPost(내 게시물 보기), searchDto(검색창)를 받는다.

 

1. page

page는 defaultValue를 0으로 설정하였기 때문에 값을 설정하지 않으면 0페이지부터 보여준다.

만약 다음 페이지 버튼을 누르게 되면 현재 페이지에서+1을 한 값이 page 변수에 담기고, 이전 페이지 버튼을 누르면 현재 페이지에서 -1을 한 값이 담긴다.

 

 

 

2. category

required 속성을 false로 지정해놓았기 때문에 category 값을 주지 않으면 null이 되어 전체 카테고리를 조회한다.

카테고리 메뉴에서 원하는 분류를 선택하면 category에 해당 값이 담겨 그 category의 게시물만 조회가 된다.

 

 

3.  myPost

myPost는 내 게시물 보기를 클릭했는지를 판단하는 파라미터이다. defaultValue는 0이고 클릭하면 1이된다.

상단 nav바에서 내 게시물 보기를 클릭하면 myPost가 1이 되고 내가 작성한 게시물만 조회된다.

 

 

4. searchDto

searchDto에는 검색창에서 검색한 값들이 담기는데 필드 값으로는 searchKey(제목, 작성자, 내용 중 선택), searchValue(검색창에 입력)가 존재한다.

선택한 옵션과 검색어가 searchDto에 담겨 넘어간다.

 


Service

 

게시물을 조회하는 Service 계층의 postList 메서드이다. 현재는 Querydsl을 사용하여 동적쿼리로 바꾸었지만 이전에는 주석처리한 부분과 같이 파라미터로 넘어온 값들을 하나하나 체크한 다음에 각각 다른 메서드를 호출하는 식으로 구현했다. 이는 굉장히 비효율적인 방식

 

또한 Repository 계층에서는 엔티티 타입으로 조회를 하고 Service 계층에서 이를 DTO로 변환하는 과정을 수행했는데 이 또한 Querydsl을 사용하여 간편하게 바로 DTO 타입으로 조회할 수 있도록 바꾸었다.

 

페이징 처리

 

 


Repository

 

이제 검색기능의 핵심 부분인 Repository 계층의 실제 동적쿼리를 만드는 것을 살펴보자.

 

먼저 Querydsl을 사용하기 위해서는 JPAQueryFactory를 사용한다. @Configuration을 통해 JPAQueryFactory를 스프링 빈으로 등록하는 방식을 사용했다.

 

현재 대부분의 쿼리들이 Spring Data JPA를 사용한 BoardRepository 인터페이스에 있기 때문에 함께 사용하기 위해 Querydsl을 위한 커스텀 interface를 하나 생성한다.

인터페이스이기 때문에 위와 같이 메서드 선언만 해준 상태

 

이제 진짜 동적쿼리를 위한 구현체를 살펴보자.

스프링 빈으로 등록한 JPAQueryFactory를 사용한다.

먼저 우리가 인터페이스로 만든 메서드를 구현해보자. 페이징 처리를 해야하기 때문에 fetchResults()를 사용하여 QueryResults로 값을 받는다.(조회한 리스트 + 전체 개수를 포함한 QueryResults 반환. count 쿼리가 추가로 실행된다.)

타입을 DTO로 반환하기 위해 Projections의 생성자 방식을 사용하여 값을 Dto로 변환하여 반환하도록 하였다.

 

여기서 동적 쿼리의 핵심이 바로 where절의 메서드들이다. Querydsl의 where절에서는 null값이 파라미터로 들어오면 해당 조건을 무시한 채 실행된다. 이것이 바로 Querydsl 동적 쿼리의 원리

==> 만약 category가 null이면 category는 where절의 조건에서 제외된다는 의미이다.

 

BooleanExpression을 반환하는 메서드로 구현한다. category가 null이 아니면 조건으로 post.category가 파라미터로 넘어온 category와 일치하는 조건을 추가시키는 방식이다.

 

이렇게 각 조건에 대한 메서드를 따로 구현하게 된다면 컴포지션이 가능해지므로 재사용성이 높아지는 엄청난 이점이 존재한다.

제목과 내용으로 검색하는 방식은 contains를 사용하여 SQL의 LIKE 기능을 사용하였다.

 

 

 

반응형

'Spring > 게시판 만들기' 카테고리의 다른 글

로그인한 사용자 정보 받아오기  (0) 2021.06.23
조회수 기능, 페이징, 정렬  (0) 2021.06.22
프로젝트 시작과 설계  (0) 2021.06.22