Query Parameter
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;
}
}
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);
'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 |