개발자 jin K

[Spring] Spring boot + JPA + MySQL 게시판 만들기 -3 검색, 페이징 본문

java/spring

[Spring] Spring boot + JPA + MySQL 게시판 만들기 -3 검색, 페이징

jin K 2021. 6. 12. 15:18

 

 

  • 검색 기능

 

메인인 list.html에서 검색과 관련된 소스는 다음과 같다.

 

<form action="/board/search" method="get">
        <div class="search">
            <input name="keyword" type="text" placeholder="검색어를 입력해주세요">
        </div>
        <button>검색하기</button>
    </form>

 

즉 검색하기를 누르면 GET 방식으로 /board/search에 input 값인 keyword를 넘겨준다.

 

 

//컨트롤러 단

@GetMapping("/board/search")
    public String search(@RequestParam(value = "keyword") String keyword, Model model) {
        List<BoardDto> boardDtoList = boardService.searchPosts(keyword);
        model.addAttribute("boardList", boardDtoList);

        return "board/list.html";
    }

 

@RequestParam으로 요청 들어온 값 중 'keyword'를 받아서 해당 키워드가 포함된 리스트를 넘겨받도록 한다. (searchPosts)

 

 

//서비스단

@Transactional
    public List<BoardDto> searchPosts(String keyword) {
        List<Board> boards = boardRepository.findByTitleContaining(keyword);
        List<BoardDto> boardDtoList = new ArrayList<>();
        
        if (boards.isEmpty()) {
            return boardDtoList;
        }

        for (Board board : boards) {
            boardDtoList.add(this.convertEntityToDto(board));
        }

        return boardDtoList;

    }

    private BoardDto convertEntityToDto(Board board) {
        return BoardDto.builder()
                .id(board.getId())
                .title(board.getTitle())
                .content(board.getContent())
                .writer(board.getWriter())
                .createdDate(board.getCreatedDate())
                .build();
    }

 

repository에서 keyword가 포함된 title을 가진 데이터를 가져온다. 이를 BoardDto에 매핑한다.

 

 

//리파지토리

 

public interface BoardRepository extends JpaRepository<Board, Long> {

    List<Board> findByTitleContaining(String keyword);

}

 

findByTitleContaining은 말 그래도 타이틀에 넘겨주는 인자값이 포함된 데이터를 찾는다. JPA에서 By는 SQL의 where 조건절과 같다. Containing은 like 검색과 같다.

 

 

 

검색을 위해 데이터를 여러개 넣었다.

 

검색 인풋창에 '검색'을 누르고 검색을 실행한다.

 

 

아니나 다를까..^^

404다 컴파일이 안된 모양이다.

 

 

잘 나온다 !

 

이때 url 주소를 보면 get방식으로 보낸 것이 보인다.

 

http://localhost:8080/board/search?keyword=검색

 


 

페이징은 참고한 자료의 페이지 네비게이터가 정상 작동 하지 않아 일단 get 방식으로 목록을 끄집어내는 데 까지 완료하였다. 

 

  • 페이징 

 

/?page= 라는 형태로 값을 넘겨주고 페이지 전환을 일으키는 것으로 보아 GET 방식 으로 값을 전달하는 것을 알 수 있다.

 

페이징은 메인 컨트롤러에서 해당 페이지의 글만 가져와서 뿌리게 해야한다.

 

//컨트롤러

    @GetMapping("/")
    public String list(@PageableDefault Pageable pageable, Model model) {
        Page<Board> boardList = boardService.getBoardList(pageable);
        
        model.addAttribute("boardList", boardList);

        return "board/list.html";
    }

 

@RequestParam으로 해당 페이지 값을 받는다.

요청받은 페이지의 게시글을 보여줘야 한다.

따라서 getBoardList의 인자에 pageNum이 들어간다.

pageList는 전체 페이지 목록인데 페이지 목록 수를 말한다.

 

//서비스

 

    @Transactional
    public Page<Board> getBoardList(Pageable pageable) {
        int page = (pageable.getPageNumber() == 0) ? 0 : (pageable.getPageNumber() - 1);
        pageable = PageRequest.of(page, 5);

        return boardRepository.findAll(pageable);
    }

 

Spring-data-JPA의 Pageable 객체를 사용한다

간단히 페이징을 만들 수 있다. 

PageRequest라는 이미 구현된 객체를 정적으로 받아서 (of) 사용한다.

int page는 몇페이지를 받아올 것인지를 말하고 5는 

페이지는 인덱스와 같이 0부터 시작하지만 사용자는 1페이지부터 사용하므로 이를 변환해준다.

 

이후 호출을 localhost:8080/?page={pageNum} 이 주소일때, pageNum에 페이지 넘버를 넣으면 해당 자료를 호출해준다.

 


예제소스의 페이지 네비게이터가 오류를 내고 생각보다 JPA 를 활용한 페이지 네비게이터 소스는 잘 보이지 않아서

이 부분은 좀더 공부하고 정리해 추후 보완해야겠다.