본문 바로가기

🌱JAVA/시나리오 개발

<SpringBoot> 게시판에 검색 기능 구현하기

# 예제 게시판에 검색기능을 구현해보자.

아래와 같이 생긴 녀석인데, 여기에 검색 기능을 넣어보자.

게시판의 기본틀은 아래와 같다.

여기서 구현을 해야할것은 위에 검색창에서 제목과 관련된 아무내용이나 입력하고 Search를 클릭했을때 화면에 검색 조건에 해당한 내용만 표시해 준다. 그리고 해당 페이지에 게시판 리스트로 이동? 이정도의 아이콘만 넣어주면 될거 같다.

쿼리는 LIKE 문으로 처리를 해주면 될거 같고, 컨트롤러는 새로 만들던지 아니면 기존에 있는 클래스에 구현을 해주던지 하면 될거 같고, 뭐 그렇다. 그럼 개발을 해볼까.

1. 검색 결과 페이지 만들기

일안 결과 후 리턴되는 검색 결과 페이지를 만든다.

뭐 SPA다 뭐다 하는 기능들이 있지만 나는 그런거는 모르므로 새로 페이지를 만들어서 값을 리턴해주는 방식으로 하자.

검색 결과가 어차피 게시판 리스트형태로 나올테니 index_result 정도의 이름으로 명명을 하면 되지 않을까 싶다.

위와 같이 생성 하였고, 변경한 부분은 "새로운 게시글" 을 "게시판 리스트로 가기" 정도의 텍스트와 URL만 변경 하였다.

2. DTO 추가하기

검색 하려는 값을 넘겨줘야 하므로 ResultForm 이라는 dto를 생성하고 아래와 같이 작성해준다.

@AllArgsConstructor
@ToString
public class ResultForm {
    private Long id;
    private String title;

    public SearchResult toEntity() {
        return new SearchResult(id, title);
    }
}

- 일단 삽질 로직부터 설명하면 아래와 같다.

1. 일단 id가 pk이어야 하니까 수동으로 pk값을 넣는 로직을 만들었다. (대망의 삽질의 시작임...)

- controller

int number = resultRepository.select_number() + 1; // pk값 생성 ㅡ.ㅡ 뭔 삽질이냐 이게...

- repositort

    @Query(value = "SELECT id FROM SEARCH_RESULT ORDER by id DESC limit 1", nativeQuery = true)
    int select_number();

2. form으로 넘어온 값을 뽑아내야 하니까... getId와 getTitle 메소드를 만들고 값을 리턴 받도록 했다.

(무려 id를 자동생성하도록 해놨는데, 수동으로 pk를 만들어서 구현을 했다.)

@Entity
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class SearchResult {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String title;

    public Long getId() {

        return id;
    }

    public String getTitle() {

        return title;
    }
}

- id는 수동 pk로직을 통해서 1개씩 늘어나도록 했고, 나머지는 타이틀인데, 타이틀도 위에서 생성한 getTitle()로 가져와서... 변수에 담아놓는다.

String title = result_value.getTitle(); //form에 담긴 title 값을 가져온다.

2. 검색값을 DB에 insert 한다. (여기서부터 말린 듯) search_result 라는 테이블에 컬럼은 달랑 2개이다. id(pk)와 title...

대망의 insert 작업... 왜 검색값을 DB에 넣냐... 그냥...검색 결과를 DB에 넣고 싶었다...

- DB insert

resultRepository.search_result(number, title); // 일단 search 값 insert...

- Repository

    @Transactional
    @Modifying
    @Query(value = "insert into search_result (id, title) values (:id, :title)", nativeQuery = true)
    int search_result(@Param("id") long id,
                      @Param("title") String title);

3. 자 그러면 검색을 할때마다 검색값을 DB에 넣는다... ㅋㅋㅋ

- 아래의 영상을 보면서 삽질의 흔적을 확인바람

3. Entity 생성

- SearchResult 이라는 Entity를 생성해준다.

@Entity
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class SearchResult {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String title;

    public Long getId() {

        return id;
    }

    public String getTitle() {

        return title;
    }
}

4. 컨트롤러 추가

    @PostMapping("/articles/result")
    public String search_result(Model model, ResultForm form) {
        SearchResult result_value = form.toEntity();
        System.out.println(result_value);
        result_value.getId();
        result_value.getTitle();
        int number = resultRepository.select_number() + 1; // pk값 생성 뭔 삽질이냐 이게...
        String title = result_value.getTitle(); //form에 담긴 title 값을 가져온다.
        resultRepository.search_result(number, title); // 일단 search 값 insert...
        String get_search_value = resultRepository.get_search_value();

//        1.위에서 search_form에서 전달받은 값을 기준으로 DB에서 LIKE 조회 수행
        List<Article> articleEntityList = articleRepository.search_result_like(get_search_value);
//        2. 가져온 Article 묶음을 뷰로 전달한다.
        model.addAttribute("articleList", articleEntityList);
//        3. 뷰페이지로 결과 값을 리턴한다.
        return "articles/index_result";
    }

5. Repository 내용은 아래와 같다.

(그냥 네이티브 쿼리가 젤 편함)

    @Transactional
    @Modifying
    @Query(value = "insert into search_result (id, title) values (:id, :title)", nativeQuery = true)
    int search_result(@Param("id") long id,
                      @Param("title") String title);

    @Query(value = "SELECT id FROM SEARCH_RESULT ORDER by id DESC limit 1", nativeQuery = true)
    int select_number();

    @Query(value = "SELECT title FROM SEARCH_RESULT ORDER by id DESC limit 1", nativeQuery = true)
    String get_search_value();
}

최종 결과 화면

MP4 버전

- 다음에는 로그인을 구현을 해볼까...