Query Parameter

2024. 1. 22. 11:54
728x90

Query Parameter 활용

: 기본 CRUD와 더불어 요구하는 자원은 동일하지만, 요구하는 자원에 특정한 동적인 조건을 덧붙이는 방법.

- URL 구성요소 중 ? 뒤의 요소.

ex) http://example.com/path?query=keyword&limit=20

- 페이지, 검색 등의 기능.

- key(인자이름) = value(값) 형식으로 활용

- 각 인자는 &로 구분.

 

 

1) @RequestParam

: @RequestParam을 이용해 Query의 인자를 받아올 수 있다! 

  • defaultValue : 기본값 설정 (문자열로만 줄 수 있다)
  • required : 필수 포함 여부
@RestController
@Slf4j
public class QueryController {
    @GetMapping("query-test")
    public String queryParams(@RequestParam(defaultValue = "name", required = false)
                                String name) {
        log.info(name);
        return name;
    }
}

default value

 

2) Pagination

: 조회할 데이터의 갯수가 많을 때, 조회되는 데이터의 갯수를 한정시켜 페이지 단위로 나누는 기법.

- 조회할 데이터의 갯수가 줄어드므로 성능 향상.

- 사용자가 데이터를 확인할 때 확인해야하는 데이터를 줄여 UX 향상.

 

- JpaRepository가 상속받는 PagingAndSortingRepository의 기능을 활용해 페이징을 할 수 있다!

 

~ ~ > 타고 타고 들어가면 형태가 Page<T> findAll(Pageable pageable); 이런 형태의 메서드가 있다

 

그러면 readAll 메서드에서 Pagination을 적용해보기로 한다.

  • 1) Pageable 객체를 만든다.
  • 2) findAll 호출 시 Pageable 전달 (Page- 페이지에 대한 정보를 포함한 객체이다)
  • 3) 마지막으로 꺼내온 엔티티 객체를 DTO로 바꿔준다. (Page.map()은 결과로 Page<U>의 형태로 응답을 준다.)
// ArticleService class
    public Page<ArticleDto> readAllPagination(Integer page, Integer limit) {
        // Jpa PagingAndSorting Repository
        // limit개 단위로 나누었을 때 page번째 페이지 (0페이지부터 시작이므로...-1해줌)
        Pageable pageable = PageRequest.of(page-1, limit);

		//id를 기준으로 내림차순 정렬 후 limit개 단위로 나누었을 때 page번째 페이지를
        //Pageable pageable = PageRequest.of(page - 1, limit, Sort.by(Sort.Direction.DESC, "id"));


	//findAll메서드를 위해 Pageable을 만들고, 얘를 꺼내온다.
        Page<Article> articleEntityPage = repository.findAll(pageable);
        // 꺼내온 엔티티 객체를 DTO로 바꿔주고 리턴
        return articleEntityPage.map(ArticleDto::fromEntity);
    }
    
// ArticleController class
    // 게시글 전체 조회 > 페이징처리 Jpa
    @GetMapping
    public Page<ArticleDto> readAllPaged(
            @RequestParam(value = "page", defaultValue = "1")
            Integer page,
            @RequestParam(value = "limit", defaultValue = "20")
            Integer limit
            ) {
        return service.readAllPagination(page, limit);
    }

>> 결과는 이렇게 나온다! (첫번째 정렬 안한 상황) > id가 1부터 10개 

 

>> Sort까지 적용했을 때의 결과 (내림차순 정렬한 경우) >> id가 50부터 10개

 

>> 결과 Page 객체를 지켜보면 페이지 내부 데이터와 함께 

- "totalPages" : 전체 페이지 수

- "totalElements" : 아이템 갯수

 

 

3) 검색 기능

: JpaRepository에 메서드를 추가하여 구현 가능. + Pageable을 사용중이면 인자로 넣어 추가가 가능하다.

 

List<Article> findAllByTitleContains(String title);
Page<Article> findAllByTitleContains(String title, Pageable pageable);

 

 

- Query By Example

: Example이라는 객체를 활용해 Example을 기준으로 유사한 Entity를 검색하는 기능. 

1) ExampleMatcher 객체를 만든다. 

  • matchingAny() : 주어지는 검색 기준의 각 필드 중 하나라도 일치하면 조회.
  • withIgnoreCase() : 대소문자를 구분하지 않는 옵션.
  • withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) : 검색 문자열이 데이터에 포함되어 있으면 조회.

2) 기준을 적용할 비교대상 Entity를 만든다.

3) 비교대상 Entity와 matcher를 활용해 Example을 만든다.

4) example 객체를 인자로 전달하여 findAll()

=> Article중 비교대상 엔티티의 필드를 포함한 Article 목록을 조회할 수 있다. 

(**다만 문자열을 제외한 조건에 대해서는 정의가 까다로으므로 많이 사용되지는 않는다.. 상세조건 검색은 JPQL/QueryDSL을 활용하는 경우가 더 많음)

ExampleMatcher matcher = ExampleMatcher.matchingAny()
							.withIgnoreCase()
                            .withStringMatcher(ExampleMatcher.stringMatcher.CONTAINING);
                            
// 기준을 적용할 비교 대상 Entity를 정한다.
Article article = new Article();
article.setTitle(query);
article.setContent(query);

// article과 matcher를 활용해 Example을 만든다.
Example<Article> example = Example.of(article, matcher);

// repository.findAll()시 example 객체를 인자로 전달.
Pageable pageable = PageRequest.of(page, limit);
repository.findAll(example, pageable);

 

 

728x90

'Programming > Spring, SpringBoot' 카테고리의 다른 글

Exception & Validation  (0) 2024.01.23
File Handling (정적파일과 Multipart/form-data)  (0) 2024.01.22
Spring Boot & REST  (0) 2024.01.18
연습문제(로깅)  (0) 2024.01.15
Profiles  (0) 2024.01.15

BELATED ARTICLES

more