1. 검색기능 - SELECT
resources/templates/list.html의 검색하기 버튼을 누르면 /board/search로 GET method가 요청된다. 요청이 가면 controller에서는 boardService.searchPost(keyword) method를 이용해 해당하는 DTO만 SELECT하게 하고, 받아온 DTO list를 model에 addAttribute한 후 return하자.
1) Controller
/src/main/java/com/example/testcompose/controller/BoardController.java
package com.example.testcompose.controller; import com.example.testcompose.dto.BoardDto; import com.example.testcompose.service.BoardService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestParam; import lombok.AllArgsConstructor; import java.util.List; @Controller @AllArgsConstructor public class BoardController{ private BoardService boardService; ... @GetMapping("/board/search") public String search(@RequestParam(value = "keyword") String keyword, Model model){ List<BoardDto> boardDtoList = boardService.searchPost(keyword); model.addAttribute("boardList", boardDtoList); return "board/list.html"; } }
- annotation
@RequestParam
query에 parameter로 넘긴 값을 가져오는 것이다. 위 코드는 /board/search?keyword=asdf 이렇게 넘어왔을 때 keyword에 해당하는 값만 가져온다.
*** RequestParam vs PathVariable
RequestParam은 url query에 있는 값을, PathVariable은 url 변수에 있는 값을 처리할 때 사용한다.
즉, RequestParam은 /localhost/main?keyword=asdf 이런 형태를, PathVariable은 /localhost/main/post/2 이런 형태를 처리할 때 사용한다.
2) Service
keyword로 받은 값으로 boardRepository에서 검색한 후 BoardEntityList를 넘겨주는 boardRepository.findByTitleInclude() method를 호출하자. 그리고 이전 포스트처럼 boardEntityList를 boardDtoList로 바꾸어서 리턴하자.
/src/main/java/com/example/testcompose/service/BoardService.java
package com.example.testcompose.service; import com.example.testcompose.dto.BoardDto; import com.example.testcompose.domain.repository.BoardRepository; import com.example.testcompose.domain.entity.BoardEntity; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import javax.transaction.Transactional; import java.util.ArrayList; import java.util.List; import java.util.Optional; @AllArgsConstructor @Service public class BoardService { private BoardRepository boardRepository; ... @Transactional public List<BoardDto> searchPost(String keyword){ List<BoardEntity> boardEntityList = boardRepository.findByTitleContaining(keyword); List<BoardDto> boardDtoList = new ArrayList<>(); if(boardEntityList.isEmpty()) return boardDtoList; for(BoardEntity boardEntity : boardEntityList){ boardDtoList.add(this.convertEntity2Dto(boardEntity)); } return boardDtoList; } private BoardDto convertEntity2Dto(BoardEntity boardEntity){ return BoardDto.builder() .id(boardEntity.getId()) .title(boardEntity.getTitle()) .content(boardEntity.getContent()) .writer(boardEntity.getWriter()) .createdDate(boardEntity.getCreatedDate()) .build(); } }
3) repository
/src/main/java/com/example/testcompose/service/BoardService.java
package com.example.testcompose.domain.repository; import com.example.testcompose.domain.entity.BoardEntity; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; public interface BoardRepository extends JpaRepository<BoardEntity,Long>{ List<BoardEntity> findByTitleContaining(String keyword); }
- import
List를 사용하기 위해 java.util.List를 import하자.
- 내용
JpaRepository method 이름으로 내가 원하는 query를 만들 수 있다. findBy 이후의 부분은 SQL에서 WHERE절에 해당한다. 즉, findByTitle은 Title로 검색하는 것이고 Containing은 Like 검색이다. StartsWith, EndsWith, IgnoreCase, Not 등 여러 옵션이 있다.
https://www.baeldung.com/spring-jpa-like-queries
4) 테스트

test를 검색하면 test1, test2가 둘 다 나오고 test1만 검색하면 test1이 나오는 것을 볼 수 있다.
2. Paging
pageable interface를 이용해 구현 가능하다.
https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/PageRequest.html