Azure Database for PostgreSQL에서 Spring Data R2DBC 사용
이 문서에서는 Spring Data R2DBC를 사용하여 Azure Database for PostgreSQL 데이터베이스에서 정보를 저장하고 검색하는 애플리케이션 샘플을 만드는 방법을 보여줍니다. 샘플은 GitHub의 r2dbc-postgresql 리포지토리에서 PostgreSQL 용 R2DBC 구현을 사용합니다.
R2DBC 는 기존의 관계형 데이터베이스에 반응형 API를 제공합니다. Spring WebFlux와 함께 사용하여 비차단 API를 사용하는 완전 반응형 Spring Boot 애플리케이션을 만들 수 있습니다. 클래식 "연결당 하나의 스레드" 접근 방식보다 더 나은 확장성을 제공합니다.
필수 조건
Azure 구독 - 체험 구독 만들기
JDK(Java Development Kit), 버전 8 이상.
cURL 또는 유사한 HTTP 유틸리티를 사용하여 기능을 테스트합니다.
샘플 애플리케이션 참조
이 문서에서는 샘플 애플리케이션을 코딩합니다. 더 빠르게 이동하려는 경우 이 애플리케이션은 이미 코딩되어 있습니다 https://github.com/Azure-Samples/quickstart-spring-data-r2dbc-postgresql.
작업 환경 준비
먼저 다음 명령을 실행하여 일부 환경 변수를 설정합니다.
export AZ_RESOURCE_GROUP=database-workshop
export AZ_DATABASE_SERVER_NAME=<YOUR_DATABASE_SERVER_NAME>
export AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
export AZ_LOCATION=<YOUR_AZURE_REGION>
export AZ_POSTGRESQL_ADMIN_USERNAME=spring
export AZ_POSTGRESQL_ADMIN_PASSWORD=<YOUR_POSTGRESQL_ADMIN_PASSWORD>
export AZ_POSTGRESQL_NON_ADMIN_USERNAME=nonspring
export AZ_POSTGRESQL_NON_ADMIN_PASSWORD=<YOUR_POSTGRESQL_NON_ADMIN_PASSWORD>
export AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>
자리 표시자를 이 문서 전체에서 사용되는 다음 값으로 바꿉니다.
<YOUR_DATABASE_SERVER_NAME>
: Azure에서 고유해야 하는 PostgreSQL 서버의 이름입니다.<YOUR_DATABASE_NAME>
: Azure 내에서 고유해야 하는 PostgreSQL 서버의 데이터베이스 이름입니다.<YOUR_AZURE_REGION>
: 사용할 Azure 지역. 기본적으로eastus
를 사용할 수 있지만 거주지와 더 가까운 지역을 구성하는 것이 좋습니다. 를 사용하여az account list-locations
사용 가능한 지역의 전체 목록을 볼 수 있습니다.<YOUR_POSTGRESQL_ADMIN_PASSWORD>
및<YOUR_POSTGRESQL_NON_ADMIN_PASSWORD>
: 최소 8자여야 하는 PostgreSQL 데이터베이스 서버의 암호입니다. 문자는 영어 대문자, 영어 소문자, 숫자(0-9) 및 영숫자가 아닌 문자(!, $, #, % 등) 중 세 가지 범주에 속해야 합니다.<YOUR_LOCAL_IP_ADDRESS>
: Spring Boot 애플리케이션을 실행할 로컬 컴퓨터의 IP 주소입니다. 이를 찾는 편리한 방법 중 하나는 whatismyip.akamai.com을 여는 것입니다.
참고 항목
사용 가능한 가장 안전한 인증 흐름을 사용하는 것이 권장됩니다. 데이터베이스, 캐시, 메시징 또는 AI 서비스와 같이 이 절차에서 설명하는 인증 흐름은 애플리케이션에 대한 신뢰 수준이 매우 높고 다른 흐름에 존재하지 않는 위험을 수반합니다. 암호 없는 연결 또는 키 없는 연결에 대한 관리 ID와 같은 더 안전한 옵션이 실행 가능하지 않은 경우에만 이 흐름을 사용합니다. 로컬 컴퓨터 작업의 경우 암호 없는 연결이나 키 없는 연결에 사용자 ID를 사용하는 것이 좋습니다.
다음으로, 다음 명령을 사용하여 리소스 그룹을 만듭니다.
az group create \
--name $AZ_RESOURCE_GROUP \
--location $AZ_LOCATION \
--output tsv
Azure Database for PostgreSQL 인스턴스 만들기 및 관리 사용자 설정
가장 먼저 관리 사용자로 관리되는 PostgreSQL 서버를 만듭니다.
참고 항목
PostgreSQL 서버 만들기에 관한 자세한 정보는 Azure portal을 사용하여 Azure Database for PostgreSQL 서버 만들기에서 확인할 수 있습니다.
az postgres flexible-server create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_SERVER_NAME \
--location $AZ_LOCATION \
--admin-user $AZ_POSTGRESQL_ADMIN_USERNAME \
--admin-password $AZ_POSTGRESQL_ADMIN_PASSWORD \
--yes \
--output tsv
PostgreSQL 데이터베이스 구성
이전에 만든 PostgreSQL 서버가 비어 있습니다. 다음 명령을 사용하여 새 데이터베이스를 만듭니다.
az postgres flexible-server db create \
--resource-group $AZ_RESOURCE_GROUP \
--database-name $AZ_DATABASE_NAME \
--server-name $AZ_DATABASE_SERVER_NAME \
--output tsv
PostgreSQL 서버에 대한 방화벽 규칙 구성
Azure Database for PostgreSQL 인스턴스는 기본적으로 보호됩니다. 들어오는 연결을 허용하지 않는 방화벽이 있습니다. 데이터베이스를 사용하려면 로컬 IP 주소에서 데이터베이스 서버에 액세스할 수 있도록 하는 방화벽 규칙을 추가해야 합니다.
이 문서의 시작 부분에서 로컬 IP 주소를 구성했으므로 다음 명령을 실행하여 서버의 방화벽을 열 수 있습니다.
az postgres flexible-server firewall-rule create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_SERVER_NAME \
--rule-name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip \
--start-ip-address $AZ_LOCAL_IP_ADDRESS \
--end-ip-address $AZ_LOCAL_IP_ADDRESS \
--output tsv
Windows 컴퓨터의 WSL(Linux용 Windows 하위 시스템)에서 PostgreSQL 서버에 연결하는 경우 방화벽에 WSL 호스트 ID를 추가해야 합니다.
WSL에서 다음 명령을 실행하여 호스트 머신의 IP 주소를 가져옵니다.
cat /etc/resolv.conf
용어 nameserver
다음에 IP 주소를 복사한 다음, 다음 명령을 사용하여 WSL IP 주소에 대한 환경 변수를 설정합니다.
export AZ_WSL_IP_ADDRESS=<the-copied-IP-address>
그런 다음, 다음 명령을 사용하여 WSL 기반 앱에 대한 서버의 방화벽을 엽니다.
az postgres flexible-server firewall-rule create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_SERVER_NAME \
--rule-name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip \
--start-ip-address $AZ_WSL_IP_ADDRESS \
--end-ip-address $AZ_WSL_IP_ADDRESS \
--output tsv
PostgreSQL 비관리 사용자 만들기 및 권한 부여
그런 다음 관리 사용자가 아닌 사용자를 만들고 데이터베이스에 대한 모든 권한을 부여합니다.
참고 항목
Azure Database for PostgreSQL에서 사용자 만들기에서 PostgreSQL 사용자 만들기에 대한 자세한 내용을 확인할 수 있습니다.
관리 사용자가 아닌 사용자를 만들기 위해 create_user.sql이라는 SQL 스크립트를 만듭니다. 다음 콘텐츠를 추가하고 로컬에 저장합니다.
참고 항목
사용 가능한 가장 안전한 인증 흐름을 사용하는 것이 권장됩니다. 데이터베이스, 캐시, 메시징 또는 AI 서비스와 같이 이 절차에서 설명하는 인증 흐름은 애플리케이션에 대한 신뢰 수준이 매우 높고 다른 흐름에 존재하지 않는 위험을 수반합니다. 암호 없는 연결 또는 키 없는 연결에 대한 관리 ID와 같은 더 안전한 옵션이 실행 가능하지 않은 경우에만 이 흐름을 사용합니다. 로컬 컴퓨터 작업의 경우 암호 없는 연결이나 키 없는 연결에 사용자 ID를 사용하는 것이 좋습니다.
cat << EOF > create_user.sql
CREATE ROLE "$AZ_POSTGRESQL_NON_ADMIN_USERNAME" WITH LOGIN PASSWORD '$AZ_POSTGRESQL_NON_ADMIN_PASSWORD';
GRANT ALL PRIVILEGES ON DATABASE $AZ_DATABASE_NAME TO "$AZ_POSTGRESQL_NON_ADMIN_USERNAME";
EOF
그런 다음, 다음 명령을 사용하여 SQL 스크립트를 실행하여 Microsoft Entra 비관리 사용자를 만듭니다.
psql "host=$AZ_DATABASE_SERVER_NAME.postgres.database.azure.com user=$AZ_POSTGRESQL_ADMIN_USERNAME dbname=$AZ_DATABASE_NAME port=5432 password=$AZ_POSTGRESQL_ADMIN_PASSWORD sslmode=require" < create_user.sql
이제 다음 명령을 사용하여 임시 SQL 스크립트 파일을 제거합니다.
rm create_user.sql
반응형 Spring Boot 애플리케이션 만들기
반응형 Spring Boot 애플리케이션을 만들기 위해 Spring Initializr를 사용합니다. 여기서 만들 애플리케이션은 다음을 사용합니다.
- Spring Boot 2.7.11.
- 다음 종속성: Spring Reactive 웹(Spring WebFlux라고도 함) 및 Spring Data R2DBC.
Spring Initializr를 사용하여 애플리케이션 생성
다음 명령을 사용하여 명령 줄에서애플리케이션을 생성합니다.
curl https://start.spring.io/starter.tgz -d dependencies=webflux,data-r2dbc -d baseDir=azure-database-workshop -d bootVersion=2.7.11 -d javaVersion=17 | tar -xzvf -
반응형 PostgreSQL 드라이버 구현 추가
생성된 프로젝트의 pom .xml 파일을 연 다음, GitHub의 r2dbc-postgresql 리포지토리에서 반응형 PostgreSQL 드라이버를 추가합니다. spring-boot-starter-webflux
종속성 후에 다음 텍스트를 추가합니다.
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-postgresql</artifactId>
<version>0.8.12.RELEASE</version>
<scope>runtime</scope>
</dependency>
Azure Database for PostgreSQL을 사용하도록 Spring Boot 구성
src/main/resources/application.properties 파일을 열고 다음 텍스트를 추가합니다.
logging.level.org.springframework.data.r2dbc=DEBUG
spring.r2dbc.url=r2dbc:pool:postgres://$AZ_DATABASE_SERVER_NAME.postgres.database.azure.com:5432/$AZ_DATABASE_NAME
spring.r2dbc.username=nonspring
spring.r2dbc.password=$AZ_POSTGRESQL_NON_ADMIN_PASSWORD
spring.r2dbc.properties.sslMode=REQUIRE
$AZ_DATABASE_SERVER_NAME
변수 $AZ_DATABASE_NAME
및 $AZ_POSTGRESQL_NON_ADMIN_PASSWORD
변수를 이 문서의 시작 부분에서 구성한 값으로 바꿉니다.
Warning
보안상의 이유로 Azure Database for PostgreSQL은 SSL 연결을 사용해야 합니다. 이것이 spring.r2dbc.properties.sslMode=REQUIRE
구성 속성을 추가해야 하는 이유입니다. 그렇지 않으면 R2DBC PostgreSQL 드라이버는 안전하지 않은 연결을 시도하며, 이는 곧 실패합니다.
참고 항목
성능을 향상시키려면 spring.r2dbc.url
r2dbc-pool을 사용하여 연결 풀을 사용하도록 속성이 구성됩니다.
이제 제공된 Maven 래퍼를 사용하여 다음과 같이 애플리케이션을 시작할 수 있습니다.
./mvnw spring-boot:run
처음으로 실행 중인 이 애플리케이션의 스크린샷은 다음과 같습니다.
데이터베이스 스키마 만들기
주 DemoApplication
클래스 내에서 다음 코드를 사용하여 데이터베이스 스키마를 만드는 새 Spring bean을 구성합니다.
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.r2dbc.connectionfactory.init.ConnectionFactoryInitializer;
import org.springframework.data.r2dbc.connectionfactory.init.ResourceDatabasePopulator;
import io.r2dbc.spi.ConnectionFactory;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public ConnectionFactoryInitializer initializer(ConnectionFactory connectionFactory) {
ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
initializer.setConnectionFactory(connectionFactory);
ResourceDatabasePopulator populator = new ResourceDatabasePopulator(new ClassPathResource("schema.sql"));
initializer.setDatabasePopulator(populator);
return initializer;
}
}
이 Spring bean은 schema.sql 파일을 사용하므로 src/main/resources 폴더에 해당 파일을 만들고 다음 텍스트를 추가합니다.
DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id SERIAL PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BOOLEAN);
다음 명령을 사용하여 실행 중인 애플리케이션을 중지하고 다시 시작합니다. 이제 애플리케이션이 이전에 생성된 demo
데이터베이스를 사용하고 내부에 todo
테이블을 만듭니다.
./mvnw spring-boot:run
생성되는 데이터베이스 테이블의 스크린샷은 다음과 같습니다.
애플리케이션 코딩
다음으로, R2DBC를 사용하여 PostgreSQL 서버에서 데이터를 저장하고 검색하는 Java 코드를 추가합니다.
다음 코드를 사용하여 클래스 옆에 DemoApplication
새 Todo
Java 클래스를 만듭니다.
package com.example.demo;
import org.springframework.data.annotation.Id;
public class Todo {
public Todo() {
}
public Todo(String description, String details, boolean done) {
this.description = description;
this.details = details;
this.done = done;
}
@Id
private Long id;
private String description;
private String details;
private boolean done;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
public boolean isDone() {
return done;
}
public void setDone(boolean done) {
this.done = done;
}
}
이 클래스는 이전에 만든 todo
테이블에 매핑된 도메인 모델입니다.
해당 클래스를 관리하려면 리포지토리가 필요합니다. 다음 코드를 사용하여 동일한 패키지에 새 TodoRepository
인터페이스를 정의합니다.
package com.example.demo;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
public interface TodoRepository extends ReactiveCrudRepository<Todo, Long> {
}
이 리포지토리는 Spring Data R2DBC에서 관리하는 반응형 리포지토리입니다.
데이터를 저장하고 검색할 수 있는 컨트롤러를 만들어 애플리케이션을 완성합니다. 동일한 패키지에 TodoController
클래스를 구현하고 다음 코드를 추가합니다.
package com.example.demo;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@RestController
@RequestMapping("/")
public class TodoController {
private final TodoRepository todoRepository;
public TodoController(TodoRepository todoRepository) {
this.todoRepository = todoRepository;
}
@PostMapping("/")
@ResponseStatus(HttpStatus.CREATED)
public Mono<Todo> createTodo(@RequestBody Todo todo) {
return todoRepository.save(todo);
}
@GetMapping("/")
public Flux<Todo> getTodos() {
return todoRepository.findAll();
}
}
마지막으로, 다음 명령을 사용하여 애플리케이션을 중지하고 다시 시작합니다.
./mvnw spring-boot:run
애플리케이션 테스트
애플리케이션을 테스트할 때 cURL을 사용할 수 있습니다.
먼저 다음 명령을 사용하여 데이터베이스에 새 "todo" 항목을 만듭니다.
curl --header "Content-Type: application/json" \
--request POST \
--data '{"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done": "true"}' \
http://127.0.0.1:8080
이 명령은 다음과 같이 만든 항목을 반환해야 합니다.
{"id":1,"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done":true}
다음으로, 다음 명령을 사용하여 새 cURL 요청을 사용하여 데이터를 검색합니다.
curl http://127.0.0.1:8080
이 명령은 다음과 같이 만든 항목을 포함하여 "todo" 항목 목록을 반환합니다.
[{"id":1,"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done":true}]
다음은 이러한 cURL 요청의 스크린샷입니다.
축하합니다! R2DBC를 사용하여 Azure Database for PostgreSQL에서 데이터를 저장하고 검색하는 완전한 반응형 Spring Boot 애플리케이션을 만들었습니다.
리소스 정리
이 빠른 시작 중에 사용되는 모든 리소스를 정리하려면 다음 명령을 사용하여 리소스 그룹을 삭제합니다.
az group delete \
--name $AZ_RESOURCE_GROUP \
--yes
다음 단계
Spring Data 애플리케이션을 Azure Spring Apps에 배포하고 관리 ID를 사용하는 방법에 대한 자세한 내용은 자습서: Azure 데이터베이스에 암호 없는 연결을 사용하여 Azure Spring Apps에 Spring 애플리케이션 배포를 참조하세요.
Spring과 Azure에 대한 자세한 사항은 Azure의 Spring 설명서 센터를 참조합니다.
참고 항목
Spring Data R2DBC에 대한 자세한 내용은 Spring의 참조 설명서를 참조하세요.
Java와 함께 Azure를 사용하는 방법에 관한 자세한 정보는 Java 개발자를 위한 Azure와 Azure DevOps 및 Java 사용하기를 참조하세요.