Spring/Spring boot icia 75일차
Spring boot 게시판 검색기능, 검색기능 페이징처리
swkn
2023. 6. 9. 11:20
1. BoardRepsitory
1. 제목 q 로 검색
쿼리문으로 작성하지 않아도 JPA로 메서드 이름을 정의하면 자동으로 쿼리문을 완성해 준다.
// 제목으로 검색
// select * from board_table where board_title like concat('%','q','%')
// Containing = like
제목으로 q라는 값을 검색하면 쿼리문은
select * from board_table where board_title like concat('%','q','%')
으로 작성해 볼 수 있었다.
List<BoardEntity> findByBoardTitleContaining(String q);
Repository에서는 위와 같이 사용할 수 있다.
@Test
@DisplayName("검색 기능 테스트")
public void searchTest() {
List<BoardEntity> boardEntityList = boardRepository.findByBoardTitleContaining("2");
boardEntityList.forEach(boardEntity -> {
System.out.println(BoardDTO.toDTO(boardEntity));
});
}
테스트 코드로 테스트를 해보자면
q값에 2를 주고 테스트를 해보겠다.
boardTitle에 2가 들어간 값이 모두 조회되는 것을 볼 수 있었다.
findByBoardTitleContaining에 Containing은 SQL쿼리문의 "Like"와 같다고 볼 수 있다.
2. 작성자 q로 검색
마찬가지로 이번엔 제목이 아닌 작성자로 검색을 하고 싶다면
List<BoardEntity> findByBoardWriterContaining(String q);
@Test
@DisplayName("작성자 검색 기능 테스트")
public void searchWriterTest() {
List<BoardEntity> boardEntityList = boardRepository.findByBoardWriterContaining("2");
boardEntityList.forEach(boardEntity -> {
System.out.println(BoardDTO.toDTO(boardEntity));
});
}
테스트 코드는 이렇게 작성할 수 있을 것이다.
3. 작성자 q로 검색한 것을 id로 내림차순 정렬
List<BoardEntity> findByBoardWriterContainingOrderByIdDesc(String q);
@Test
@DisplayName("작성자 검색 기능 id 기준 내림차순 테스트")
public void searchWriterOrderByIdDescTest() {
List<BoardEntity> boardEntityList = boardRepository.findByBoardWriterContainingOrderByIdDesc("2");
boardEntityList.forEach(boardEntity -> {
System.out.println(BoardDTO.toDTO(boardEntity));
});
}
id 기준으로 내림차순 정렬까지 되는 것을 볼 수 있다.
4. 제목 또는 작성자에 q 가 들어간 값 id로 내림차순 조회
List<BoardEntity> findByBoardTitleContainingOrBoardWriterContainingOrderByIdDesc(String q1,String q2);
조건이 2개기 때문에 매개변수를 2개 주어야 한다.
@Test
@Transactional
@DisplayName("제목 또는 작성자 검색 테스트")
public void searchWriterOrsearchTitleTest() {
String q = "20";
List<BoardEntity> boardEntityList = boardRepository.findByBoardTitleContainingOrBoardWriterContainingOrderByIdDesc(q,q);
boardEntityList.forEach(boardEntity -> {
System.out.println(BoardDTO.toDTO(boardEntity));
});
}
매개변수를 2개준다고 각각 다른값을 주면 에러가 난다.
2. 검색결과 페이징 처리
Page<BoardEntity> findByBoardWriterContaining(String q, Pageable pageable);
리턴타입을 Page으로 바꿔주고 매개변수에 Pageable 변수를 담아준다.
@Test
@Transactional
@DisplayName("검색 결과 페이징처리")
public void searchPaging() {
String q = "2";
int page = 0;
int pageLimit = 3;
Page<BoardEntity> boardEntities = boardRepository.findByBoardWriterContaining(q, PageRequest.of(page, pageLimit, Sort.by(Sort.Direction.DESC, "id")));
Page<BoardDTO> boardEntityPage = boardEntities.map(boardEntity ->
BoardDTO.builder()
.id(boardEntity.getId())
.boardWriter(boardEntity.getBoardWriter())
.boardTitle(boardEntity.getBoardTitle())
.createdAt(UtilClass.dateFormat(boardEntity.getCreatedAt()))
.boardHits(boardEntity.getBoardHits())
.build()
);
System.out.println("boardEntities.getContent() = " + boardEntityPage.getContent()); // 요청페이지에 들어있는 데이터
System.out.println("boardEntities.getTotalElements() = " + boardEntityPage.getTotalElements()); // 전체 글갯수
System.out.println("boardEntities.getNumber() = " + boardEntityPage.getNumber()); // 요청페이지(jpa 기준)
System.out.println("boardEntities.getTotalPages() = " + boardEntityPage.getTotalPages()); // 전체 페이지 갯수
System.out.println("boardEntities.getSize() = " + boardEntityPage.getSize()); // 한페이지에 보여지는 글갯수
System.out.println("boardEntities.hasPrevious() = " + boardEntityPage.hasPrevious()); // 이전페이지 존재 여부
System.out.println("boardEntities.isFirst() = " + boardEntityPage.isFirst()); // 첫페이지인지 여부
System.out.println("boardEntities.isLast() = " + boardEntityPage.isLast()); // 마지막페이지인지 여부
}
테스트를 돌려보면
2로 검색된 갯수 = 15
페이지 번호 = 0
마지막 페이지 번호 = 5
한페이지에 보여지는 갯수 = 3
이전페이지 존재여부 = false
첫페이지 = true
마지막페이지 = false
즉 , 검색기능을 이용하려면 Repository에 쿼리문을 담은 메소드명을 제작후 , 페이징을 하고 싶다면 리턴과 매개변수를 Page로 바꾸어서 사용한다.
페이징처리하면서 Sort로 정렬기준을 보내기 때문에 OrderBy를 메소드에 적을 필요는 없다.