Development/Spring

[Docker + Spring] Docker gradle Spring Boot with VS Code JPA MySQL 게시판 생성 - 3. 검색기능Search

hyelie 2022. 10. 4. 13:57

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