QueryDsl 이용한 제목, 내용, 제목+내용 검색

행행·2023년 2월 17일
0
  • QueryDsl 을 어느정도 활용할 줄 안다고 가정한 후 설명하겠습니다.

Controller

#Controller

//문의사항 검색
    @PostMapping("/search")
    public ResponseEntity<?> getPageListNotice(@RequestBody SearchCondition searchCondition, Pageable pageable) {
        PageImpl<QuestionResponseDTO> responseDTO;
        
        //검색조건중 모든 내용을 입력하지 않고 요청을 보냈을 때 일반 목록 페이지 출력
        if (searchCondition.getBoardWriter().isEmpty() && searchCondition.getBoardContent().isEmpty() && searchCondition.getBoardTitle().isEmpty() ){
            responseDTO = questionService.getPageList(pageable);
        }
        
        else {
            responseDTO = questionService.getPageListWithSearch(searchCondition, pageable);

        }
        return ResponseEntity.ok()
                .body(responseDTO);
    }



  • SearchCondition 를 통해서 검색 내용을 받습니다.
  • 글 제목, 글 내용, 글 제목 + 내용, 글 작성자를 요청받고 검색할 것 입니다.

SearchCondition (RequestDTO)

#SearchCondition 

@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SearchCondition {
	
    //검색받을 글 제목
    private String boardTitle;
	
    //검색받을 글 내용
    private String boardContent;
	
    //검색받을 글 작성자
    private String boardWriter;
    
}

Service

#Service

//문의사항 검색 및 페이지 제네이션
    public PageImpl<QuestionResponseDTO> getPageListWithSearch(SearchCondition searchCondition, Pageable pageable){
        PageImpl<QuestionResponseDTO> result = questionsRepositorySupport.getQuestionListPageWithSearch(searchCondition, pageable);
        return result;
    }

Repository

#Repository

public PageImpl<QuestionResponseDTO> getQuestionListPageWithSearch(SearchCondition searchCondition, Pageable pageable){
        JPQLQuery<BoardEntity> query = jpaQueryFactory
                .select(qBoardEntity)
                .from(qBoardEntity)
                .where(qBoardEntity.boardType.eq(BoardType.QUESTION)
                
                //제목 + 내용 검색 
                        ,ContentMessageTitleEq(searchCondition.getBoardContent(),searchCondition.getBoardTitle())
                        ,boardWriterEq(searchCondition.getBoardWriter()))
                		.orderBy(qBoardEntity.createDate.desc());
                
                
                
                //페이지 제네이션에 필요한 정보들
        		long totalCount = query.fetchCount();
        		List<BoardEntity> results = 		getQuerydsl().applyPagination(pageable,query).fetch();
        		List<QuestionResponseDTO> dtoList = results.stream()
        
                // response DTO로 변환
                .map(QuestionResponseDTO::new)
                .collect(Collectors.toList());
                
               
        Pageable pageRequest = new FixedPageRequest(pageable, totalCount);
        return new PageImpl<>(dtoList, pageRequest, totalCount);

    }


//제목 + 내용에 필요한 동적 쿼리문

private BooleanExpression ContentMessageTitleEq(String boardContent,String boardTitle){
		
        
        //검색시, 글 내용이 있고, 글 제목이 있는경우 or로 검색 요청을 보내는 쿼리
        if(!boardContent.isEmpty() && !boardTitle.isEmpty()){
            return qBoardEntity.boardTitle.contains(boardTitle).or(qBoardEntity.boardContent.contains(boardContent));
        }
        
        //검색시, 글 내용만 있는 경우, 글 내용을 검색 요청하는 쿼리
        if(!boardContent.isEmpty() && boardTitle.isEmpty()){
            return qBoardEntity.boardContent.contains(boardContent);
        }
        
        //검색시, 글 제목만 있는 경우, 글 제목을 검색 요청하는 쿼리
        if(boardContent.isEmpty() && !boardTitle.isEmpty()){
            return qBoardEntity.boardTitle.contains(boardTitle);
        }
        return null;
    }
    
    
 // 글 작성자 검색을 위한 동적 쿼리문
    
private BooleanExpression boardWriterEq(String boardWriter){
        if(boardWriter.isEmpty()){
            return null;
        }
        return qBoardEntity.boardWriter.contains(boardWriter);
    }


글 작성자로 검색했을때,

ContentMessageTitleEq의 리턴값이 null이고,

JPQL Query 절에서 where null, 조건1 식으로 요청을 보낸다. 그러면 조건 1에 해당하는 내용을 요청합니다.

글 내용으로 검색했을 때, 즉

requestBody가


{
	"boardTitle" : "",
    "boardContent" : "검색내용",
    "boardWriter : "",
   
}

ContentMessageTitleEq의


if(!boardContent.isEmpty() && boardTitle.isEmpty()){
            return qBoardEntity.boardContent.contains(boardContent);
        }
        

이 조건절로 인해, 글 내용에 해당되는 값만 요청합니다.

내용 + 제목 검색시,


{
	"boardTitle" : "검색내용",
   "boardContent" : "검색내용",
   "boardWriter : "",
}
if(!boardContent.isEmpty() && !boardTitle.isEmpty()){

           return qBoardEntity.boardTitle.contains(boardTitle)
           .or(qBoardEntity.boardContent.contains(boardContent));
           
       }
       

이 조건절로 인해, 글 내용과 글 제목에 해당되는 값들을 요청합니다.

profile
성장하려고 분투 중인 개발자

0개의 댓글