#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
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SearchCondition {
//검색받을 글 제목
private String boardTitle;
//검색받을 글 내용
private String boardContent;
//검색받을 글 작성자
private String boardWriter;
}
#Service
//문의사항 검색 및 페이지 제네이션
public PageImpl<QuestionResponseDTO> getPageListWithSearch(SearchCondition searchCondition, Pageable pageable){
PageImpl<QuestionResponseDTO> result = questionsRepositorySupport.getQuestionListPageWithSearch(searchCondition, pageable);
return result;
}
#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));
}
이 조건절로 인해, 글 내용과 글 제목에 해당되는 값들을 요청합니다.