sm 기술 블로그

[스프링부트] 검색기능 (JPA) 본문

스프링부트

[스프링부트] 검색기능 (JPA)

sm_hope 2022. 8. 8. 21:27

JPA에서 검색기능을 구현하는 방법은 다양하다.

하지만 쿼리문을 직접 사용해서 구현하는 것이 직관적이기 때문에 쿼리문을 사용해보려고 한다.

 

1. 폼에 검색  추가

    <form th:action="@{/article/posts/search}" method="GET" role="search">
        <input type="text" name="keyword" placeholder="검색">
        <button> 검색 </button>
    </form>

margin, padding 등 어떠한 조건도 주지 않은 상태이다.

정말 기본 으로 테일윈드 적용시 노말라이즈로 인해 다음과 같이 나올 것이다.

GET방식을 사용하는 이유

GET이 아닌 POST 방식으로 전달할경우 검색과 페이징을 처리한다면 웹 브라우저에서 '새로고침' 또는 '뒤로가기'를 했을 때 '만료된 페이지 입니다'라는 오류가 종종 발생한다. 그 이유는 동일한 POST요청이 중복으로 요청하는 것을 방지하기 위해 '만료된 페이지입니다.'라는 오류를 발생시키는 것이다.

때문에 페이징에서 2페이지에서 3페이지를 갔다가 뒤로가기를 한다면? 오류가 발생할 것이다.

그냥 GET을 쓰자!

 

2. 리포지터리 추가

public interface ArticleRepository extends JpaRepository<Article, Long> {
    @Query("select a from Article a where a.title like %:kw%")
    List<Article> findByTitleKeyword(@Param("kw") String keyword);
}

Query또한 다양하게 사용이 가능하다.

다른 쿼리 사용법은 다음 사이트를 참고하자. https://sundries-in-myidea.tistory.com/91

 

Spring Data JPA에서 Query를 사용하는 방법

쿼리를 자동 생성해준다고? Spring boot를 통해서 개발을 하게 된다면, DB에 데이터를 삽입, 읽기 등 여러 가지 작동을 하기 위해서는 방식이 필요하다. 쿼리를 작동시키는 방식에는 여러 가지 방식

sundries-in-myidea.tistory.com

 

쿼리를 직접 사용할 때 중요한 규칙이 있다.

 

1. 소문자로 사용할것

2. 테이블 이름은 직접 사용하지 말고 치환해서 사용하자

3. 뭐가됐든 테이블 첫 이름은 대문자

4. parameter를 넣을 때는 ':'를 붙일 것

 

위 4가지 조건은 jpa에서 쿼리문을 사용할 때, 꼭 필요한 조건이다.

따라서 하나라도 어기지말고 사용해야 오류없이 제대로 작동할 것이다.

 

또한 쿼리문을 사용했기 때문에 메소드 명은 아무거나 상관 없다.

 

3. 서비스 추가

    @Transactional
    public List<Article> searchTitle(String keyword){
        List<Article> articles = articleRepository.findByTitleKeyword(keyword);
        return articles;
    }

@Transactional은 연산 도중 오류가 발생하더라도 에러를 발생시키지 않고 롤백 시킬때 사용하는 어노테이션이다.

 

우리는 Article에 대한 리스트를 나타낼 것이기 때문에 리스트 형태의 Articles를 만들었다.

 

4. 컨트롤러 추가

    @GetMapping("/posts/search")
    public String search(String keyword, Model model) {
        List<Article> articles= articleService.searchTitle(keyword);
        model.addAttribute("articles", articles);
        return "article/list.html";
    }

폼에서  get형식으로 보냈기 때문에 컨트롤러에서도 get형식으로 mapping 할 것이다.

keyword를 통해 찾은 article들을 articles에 저장하고 model 을 통해서 폼에게 전달할 것이다.

키워드를 검색하면 도메인은 다음과 같이 바뀔 것이다.

 

Comments