개요
이 튜토리얼에서는 MongoDB 에 연결된 Quarkus 애플리케이션 에서 페이지 매김 기술을 구현 방법을 보여줍니다. 자카르타 데이터 리포지토리 사용하여 오프셋 기반 및 커서 기반 페이지 매김 메서드를 모두 지원 REST API 엔드포인트를 생성하는 방법을 학습 .
페이지 매김
페이지 매김은 대규모 데이터 세트를 작고 관리하기 쉬운 청크로 나누는 데 사용되는 기술입니다. 이 튜토리얼에서는 오프셋 기반 및 커서 기반 페이지 매김 메서드를 구현합니다. 오프셋 기반 페이지 매김은 페이지 번호를 사용하여 데이터의 특정 하위 집합을 조회 하는 반면 커서 기반 페이지 매김은 점 또는 커서 사용하여 데이터 세트를 탐색합니다.
튜토리얼
이 튜토리얼에서는 다음 조치를 수행하는 방법을 보여줍니다.
전제 조건 확인
필요한 종속성이 있는 Quarkus 프로젝트 생성
MongoDB 연결 구성
데이터 엔터티 및 리포지토리 정의
페이지 매김을 위한 REST API 엔드포인트 구현
페이지 매김 엔드포인트 테스트
전제 조건을 확인합니다.
시작하기 전에 다음 전제 조건 작업을 완료하세요.
MongoDB Atlas 또는 로컬 Docker 인스턴스 에서 MongoDB 클러스터 구성합니다.
Docker 사용하여 로컬 MongoDB 인스턴스 시작하려면 다음 명령을 실행 .
docker run --rm -d --name mongodb-instance -p 27017:27017 mongo
또는 MongoDB Atlas 사용하여 무료 M0 클러스터 배포 수 있습니다. Atlas 계정 및 클러스터를 만드는 방법을 학습 보려면 MongoDB 시작하기 가이드를 참조하세요.
Quarkus 프로젝트 생성합니다.
Quarkus 코드 생성기 로 이동하여 다음 설정으로 프로젝트 구성합니다.
원하는 그룹 과 아티팩트 ID 선택합니다.
다음 종속성을 추가합니다.
JNoSQL 문서 MongoDB (
quarkus-jnosql-document-mongodb)RESTEasy 반응형(
quarkus-resteasy-reactive)RESTEasy Reactive 잭슨(
quarkus-resteasy-reactive-jackson)OpenAPI(
quarkus-smallrye-openapi)
프로젝트 생성하고 ZIP 파일 다운로드 압축을 풉니다.
참고
생성기에서 종속성을 찾을 수 없는 경우 pom.xml 파일 에 수동으로 추가합니다.
설정 완료한 후 pom.xml 파일 다음 종속성이 포함되어 있는지 확인합니다.
<dependencies> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-smallrye-openapi</artifactId> </dependency> <dependency> <groupId>io.quarkiverse.jnosql</groupId> <artifactId>quarkus-jnosql-document-mongodb</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-reactive</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-reactive-jackson</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-arc</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <scope>test</scope> </dependency> </dependencies>
MongoDB 데이터베이스 구성합니다.
application.properties 파일 열고 다음 구성 속성을 추가하여 MongoDB 인스턴스 에 연결합니다.
quarkus.mongodb.connection-string = <your connection string> jnosql.document.database = fruits
이 구성을 사용하면 애플리케이션 지정된 연결 문자열 에서 MongoDB 클러스터 에 연결하고 fruits 데이터베이스 사용할 수 있습니다.
중요
프로덕션 환경에서는 액세스 제어를 활성화 하고 인증 시행하다 . 자세한 내용은 보안 체크리스트를 참조하세요.
환경 변수를 사용하여 이러한 속성을 재정의할 수 있으며, 이를 통해 코드를 수정하지 않고도 개발, 테스트 및 프로덕션을 위한 다양한 구성을 지정할 수 있습니다.
데이터 엔터티를 만듭니다.
src/main/java 디렉토리 에 Fruit 엔터티 클래스를 만듭니다. 다음 코드는 id 및 name 필드가 있는 엔터티를 정의합니다.
import jakarta.nosql.Column; import jakarta.nosql.Convert; import jakarta.nosql.Entity; import jakarta.nosql.Id; import org.eclipse.jnosql.databases.mongodb.mapping.ObjectIdConverter; public class Fruit { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return "Fruit{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; } public static Fruit of(String name) { Fruit fruit = new Fruit(); fruit.setName(name); return fruit; } }
리포지토리 인터페이스를 만듭니다.
BasicRepository 클래스를 확장하는 FruitRepository 인터페이스를 만듭니다. 다음 코드는 오프셋 및 커서 기반 페이지 매김에 대한 메서드를 정의합니다.
import jakarta.data.Sort; import jakarta.data.page.CursoredPage; import jakarta.data.page.Page; import jakarta.data.page.PageRequest; import jakarta.data.repository.BasicRepository; import jakarta.data.repository.Find; import jakarta.data.repository.OrderBy; import jakarta.data.repository.Repository; public interface FruitRepository extends BasicRepository<Fruit, String> { CursoredPage<Fruit> cursor(PageRequest pageRequest, Sort<Fruit> order); Page<Fruit> offSet(PageRequest pageRequest); long countBy(); }
프레임워크 이 인터페이스를 자동으로 구현하므로 상용구 코드를 작성하지 않고도 데이터베이스 작업을 수행할 수 있습니다.
데이터베이스 설정 클래스를 생성합니다.
src/main/java 디렉토리 에 SetupDatabase 클래스를 만듭니다. 다음 코드는 스타트업 시 샘플 데이터로 데이터베이스 채우고 종료 시 데이터를 삭제합니다.
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Observes; import io.quarkus.runtime.ShutdownEvent; import io.quarkus.runtime.StartupEvent; import org.jboss.logging.Logger; import java.util.List; public class SetupDatabase { private static final Logger LOGGER = Logger.getLogger(SetupDatabase.class.getName()); private final FruitRepository fruitRepository; public SetupDatabase(FruitRepository fruitRepository) { this.fruitRepository = fruitRepository; } void onStart( StartupEvent ev) { LOGGER.info("The application is starting..."); long count = fruitRepository.countBy(); if (count > 0) { LOGGER.info("Database already populated"); return; } List<Fruit> fruits = List.of( Fruit.of("apple"), Fruit.of("banana"), Fruit.of("cherry"), Fruit.of("date"), Fruit.of("elderberry"), Fruit.of("fig"), Fruit.of("grape"), Fruit.of("honeydew"), Fruit.of("kiwi"), Fruit.of("lemon") ); fruitRepository.saveAll(fruits); } void onStop( ShutdownEvent ev) { LOGGER.info("The application is stopping..."); fruitRepository.deleteAll(fruitRepository.findAll().toList()); } }
REST API 엔드포인트를 생성합니다.
src/main/java 디렉토리 에 FruitResource 클래스를 만듭니다. 그런 다음 클래스 파일 에 다음 코드를 붙여넣습니다.
import jakarta.data.Sort; import jakarta.data.page.PageRequest; import jakarta.ws.rs.DefaultValue; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; public class FruitResource { private final FruitRepository fruitRepository; private static final Sort<Fruit> ASC = Sort.asc("name"); private static final Sort<Fruit> DESC = Sort.desc("name"); public FruitResource(FruitRepository fruitRepository) { this.fruitRepository = fruitRepository; } public Iterable<Fruit> offset( long page, int size) { var pageRequest = PageRequest.ofPage(page).size(size); return fruitRepository.offSet(pageRequest).content(); } public Iterable<Fruit> cursor( String after, String before, int size) { if (!after.isBlank()) { var pageRequest = PageRequest.ofSize(size).afterCursor(PageRequest.Cursor.forKey(after)); return fruitRepository.cursor(pageRequest, ASC).content(); } else if (!before.isBlank()) { var pageRequest = PageRequest.ofSize(size).beforeCursor(PageRequest.Cursor.forKey(before)); return fruitRepository.cursor(pageRequest, DESC).stream().toList(); } var pageRequest = PageRequest.ofSize(size); return fruitRepository.cursor(pageRequest, ASC).content(); } }
이 클래스는 다음 엔드포인트를 정의합니다.
/fruits/offset:page쿼리 매개변수를 사용하여 오프셋 기반 페이지 매김을 지원합니다./fruits/cursor:after및before쿼리 매개변수를 사용하여 커서 기반 페이지 매김을 지원합니다.
또한 두 엔드포인트 모두 size 쿼리 변수를 허용하여 페이지당 항목 수를 지정합니다.
오프셋 기반 페이지 매김을 테스트합니다.
별도의 터미널 창 에서 다음 curl 명령을 사용하여 오프셋 페이지 매김 엔드포인트를 테스트합니다. 이러한 명령은 서로 다른 페이지의 과일 데이터를 요청 .
첫 번째 페이지를 가져오려면 다음 명령을 실행 .
curl --location http://localhost:8080/fruits/offset?page=1
두 번째 페이지를 가져오려면 다음 명령을 실행 .
curl --location http://localhost:8080/fruits/offset?page=2
다섯 번째 페이지를 가져오려면 다음 명령을 실행 .
curl --location http://localhost:8080/fruits/offset?page=5
커서 기반 페이지 매김을 테스트합니다.
다음 curl 명령을 사용하여 커서 매김 엔드포인트를 테스트합니다. 이 명령은 after 및 before 매개변수를 사용하여 데이터 세트를 탐색합니다.
초기 과일 설정하다 가져오려면 다음 명령을 실행 .
curl --location http://localhost:8080/fruits/cursor
"banana" 뒤에 name 필드 값이 있는 과일을 가져오려면 다음 명령을 실행 .
curl --location http://localhost:8080/fruits/cursor?after=banana
"date" 앞에 name 필드 값이 있는 과일을 가져오려면 다음 명령을 실행 .
curl --location http://localhost:8080/fruits/cursor?before=date
추가 리소스
MongoDB 의 페이지 매김에 대해 자세히 학습하려면 MongoDB Atlas 설명서의 결과 페이지 매김 가이드를 참조하세요.
Quarkus에 대해 자세히 학습하려면 Quarkus 설명서를 참조하세요.