Używanie rozwiązania Spring Data R2DBC z usługą Azure Database for PostgreSQL

W tym artykule przedstawiono tworzenie przykładowej aplikacji korzystającej z narzędzia Spring Data R2DBC do przechowywania i pobierania informacji w bazie danych usługi Azure Database for PostgreSQL . W przykładzie użyto implementacji R2DBC dla bazy danych PostgreSQL z repozytorium r2dbc-postgresql w usłudze GitHub.

Łączność R2DBC wprowadza reaktywne interfejsy API do tradycyjnych relacyjnych baz danych. Można go używać z platformą Spring WebFlux, aby utworzyć w pełni reaktywne aplikacje Spring Boot korzystające z nieblokujących interfejsów API. Zapewnia lepszą skalowalność niż klasyczne podejście "jeden wątek na połączenie".

Wymagania wstępne

  • Klient wiersza polecenia postgreSQL.

  • cURL lub podobne narzędzie HTTP do testowania funkcjonalności.

Zobacz przykładową aplikację

W tym artykule kodujesz przykładową aplikację. Jeśli chcesz przyspieszyć, ta aplikacja jest już kodowana i dostępna pod adresem https://github.com/Azure-Samples/quickstart-spring-data-r2dbc-postgresql.

Przygotowywanie środowiska roboczego

Najpierw skonfiguruj niektóre zmienne środowiskowe, uruchamiając następujące polecenia:

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>

Zastąp symbole zastępcze następującymi wartościami, które są używane w tym artykule:

  • <YOUR_DATABASE_SERVER_NAME>: nazwa serwera PostgreSQL, który powinien być unikatowy na platformie Azure.
  • <YOUR_DATABASE_NAME>: nazwa bazy danych serwera PostgreSQL, który powinien być unikatowy na platformie Azure.
  • <YOUR_AZURE_REGION>: region platformy Azure, którego będziesz używać. Możesz domyślnie zastosować region eastus, ale zalecamy skonfigurowanie regionu bliżej Twojego miejsca zamieszkania. Pełną listę dostępnych regionów można wyświetlić przy użyciu polecenia az account list-locations.
  • <YOUR_POSTGRESQL_ADMIN_PASSWORD> i <YOUR_POSTGRESQL_NON_ADMIN_PASSWORD>: hasło serwera bazy danych PostgreSQL, które powinno zawierać co najmniej osiem znaków. Znaki powinny pochodzić z trzech z następujących kategorii: wielkie litery angielskie, małe litery angielskie, cyfry (0–9) i znaki inne niż alfanumeryczne (!, $, #, %itd.).
  • <YOUR_LOCAL_IP_ADDRESS>: adres IP komputera lokalnego, z którego będzie uruchamiana aplikacja Spring Boot. Jednym z wygodnych sposobów znalezienia go jest otwarcie whatismyip.akamai.com.

Następnie utwórz grupę zasobów przy użyciu następującego polecenia:

az group create \
    --name $AZ_RESOURCE_GROUP \
    --location $AZ_LOCATION \
    --output tsv

Tworzenie wystąpienia usługi Azure Database for PostgreSQL i konfigurowanie użytkownika administratora

Pierwszą rzeczą, którą utworzysz, jest zarządzany serwer PostgreSQL z użytkownikiem administratora.

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

Konfigurowanie bazy danych PostgreSQL

Utworzony wcześniej serwer PostgreSQL jest pusty. Użyj następującego polecenia, aby utworzyć nową bazę danych.

az postgres flexible-server db create \
    --resource-group $AZ_RESOURCE_GROUP \
    --database-name $AZ_DATABASE_NAME \
    --server-name $AZ_DATABASE_SERVER_NAME \
    --output tsv

Konfigurowanie reguły zapory dla serwera PostgreSQL

Wystąpienia usługi Azure Database for PostgreSQL są domyślnie zabezpieczone. Ma ona zaporę, która nie zezwala na żadne połączenie przychodzące. Aby móc używać bazy danych, należy dodać regułę zapory, która umożliwi lokalnemu adresowi IP dostęp do serwera bazy danych.

Ponieważ na początku tego artykułu skonfigurowano lokalny adres IP, możesz otworzyć zaporę serwera, uruchamiając następujące polecenie:

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

Jeśli łączysz się z serwerem PostgreSQL z Podsystem Windows dla systemu Linux (WSL) na komputerze z systemem Windows, musisz dodać identyfikator hosta WSL do zapory.

Uzyskaj adres IP maszyny hosta, uruchamiając następujące polecenie w programie WSL:

cat /etc/resolv.conf

Skopiuj adres IP zgodnie z terminem nameserver, a następnie użyj następującego polecenia, aby ustawić zmienną środowiskową dla adresu IP WSL:

export AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

Następnie użyj następującego polecenia, aby otworzyć zaporę serwera w aplikacji opartej na protokole 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

Tworzenie użytkownika niebędącego administratorem bazy danych PostgreSQL i udzielanie uprawnień

Następnie utwórz użytkownika niebędącego administratorem i przyznaj wszystkie uprawnienia do bazy danych.

Uwaga

Więcej szczegółowych informacji na temat tworzenia użytkowników postgreSQL można znaleźć w temacie Tworzenie użytkowników w usłudze Azure Database for PostgreSQL.

Utwórz skrypt SQL o nazwie create_user.sql na potrzeby tworzenia użytkownika niebędącego administratorem. Dodaj następującą zawartość i zapisz ją lokalnie:

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

Następnie użyj następującego polecenia, aby uruchomić skrypt SQL w celu utworzenia użytkownika innego niż administrator firmy Microsoft:

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

Teraz użyj następującego polecenia, aby usunąć tymczasowy plik skryptu SQL:

rm create_user.sql

Tworzenie reaktywnej aplikacji Spring Boot

Aby utworzyć reaktywną aplikację Spring Boot, użyjemy narzędzia Spring Initializr. Aplikacja, którą utworzymy, używa następujących funkcji:

  • Spring Boot 2.7.11.
  • Następujące zależności: Spring Reactive Web (znany również jako Spring WebFlux) i Spring Data R2DBC.

Generowanie aplikacji przy użyciu narzędzia Spring Initializr

Wygeneruj aplikację w wierszu polecenia przy użyciu następującego polecenia:

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 -

Dodawanie reaktywnej implementacji sterownika PostgreSQL

Otwórz plik pom.xml wygenerowanego projektu, a następnie dodaj reaktywny sterownik PostgreSQL z repozytorium r2dbc-postgresql w usłudze GitHub. spring-boot-starter-webflux Po zależności dodaj następujący tekst:

<dependency>
    <groupId>io.r2dbc</groupId>
    <artifactId>r2dbc-postgresql</artifactId>
    <version>0.8.12.RELEASE</version>
    <scope>runtime</scope>
</dependency>

Konfigurowanie platformy Spring Boot do korzystania z usługi Azure Database for PostgreSQL

Otwórz plik src/main/resources/application.properties i dodaj następujący tekst:

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

Zastąp $AZ_DATABASE_SERVER_NAMEzmienne , $AZ_DATABASE_NAMEi $AZ_POSTGRESQL_NON_ADMIN_PASSWORD wartościami skonfigurowanymi na początku tego artykułu.

Ostrzeżenie

Ze względów bezpieczeństwa usługa Azure Database for PostgreSQL wymaga używania połączeń SSL. Dlatego należy dodać spring.r2dbc.properties.sslMode=REQUIRE właściwość konfiguracji. W przeciwnym razie sterownik R2DBC PostgreSQL spróbuje nawiązać połączenie przy użyciu niezabezpieczonego połączenia, co zakończy się niepowodzeniem.

Uwaga

Aby uzyskać lepszą wydajność, spring.r2dbc.url właściwość jest skonfigurowana do używania puli połączeń przy użyciu puli r2dbc-pool.

Teraz powinno być możliwe uruchomienie aplikacji przy użyciu podanej otoki Narzędzia Maven w następujący sposób:

./mvnw spring-boot:run

Oto zrzut ekranu przedstawiający aplikację uruchomioną po raz pierwszy:

Screenshot of the running application.

Tworzenie schematu bazy danych

W klasie głównej DemoApplication skonfiguruj nową fasolę Spring, która utworzy schemat bazy danych przy użyciu następującego kodu:

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;
    }
}

Ten fasola Spring używa pliku o nazwie schema.sql, więc utwórz ten plik w folderze src/main/resources i dodaj następujący tekst:

DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id SERIAL PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BOOLEAN);

Zatrzymaj uruchomioną aplikację i uruchom ją ponownie, używając następującego polecenia. Aplikacja będzie teraz korzystać z utworzonej wcześniej bazy danych demo i utworzy w niej tabelę todo.

./mvnw spring-boot:run

Oto zrzut ekranu przedstawiający tabelę bazy danych podczas jej tworzenia:

Screenshot of the creation of the database table.

Kodowanie aplikacji

Następnie dodaj kod Java, który będzie używać R2DBC do przechowywania i pobierania danych z serwera PostgreSQL.

Utwórz nową Todo klasę Języka Java obok DemoApplication klasy przy użyciu następującego kodu:

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;
    }
}

Ta klasa jest modelem domeny zamapowanym na utworzonej wcześniej tabeli todo.

Do zarządzania tą klasą potrzebujesz repozytorium. Zdefiniuj nowy TodoRepository interfejs w tym samym pakiecie przy użyciu następującego kodu:

package com.example.demo;

import org.springframework.data.repository.reactive.ReactiveCrudRepository;

public interface TodoRepository extends ReactiveCrudRepository<Todo, Long> {
}

To repozytorium jest reaktywnym repozytorium, które zarządza rozwiązaniem Spring Data R2DBC.

Zakończ aplikację, tworząc kontroler, który może przechowywać i pobierać dane. Zaimplementuj klasę TodoController w tym samym pakiecie i dodaj następujący kod:

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();
    }
}

Na koniec wstrzymaj działanie aplikacji i uruchom ją ponownie za pomocą następującego polecenia:

./mvnw spring-boot:run

Testowanie aplikacji

Do przetestowania aplikacji możesz użyć narzędzia cURL.

Najpierw utwórz nowy element typu „czynność do wykonania” w bazie danych przy użyciu następującego polecenia:

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

To polecenie powinno zwrócić utworzony element, jak pokazano poniżej:

{"id":1,"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done":true}

Następnie pobierz dane przy użyciu nowego żądania cURL za pomocą następującego polecenia:

curl http://127.0.0.1:8080

To polecenie zwróci listę elementów "todo", w tym utworzony element, jak pokazano poniżej:

[{"id":1,"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done":true}]

Oto zrzut ekranu przedstawiający te żądania cURL:

Screenshot of the cURL test.

Gratulacje! Utworzono w pełni reaktywną aplikację Spring Boot, która używa protokołu R2DBC do przechowywania i pobierania danych z usługi Azure Database for PostgreSQL.

Czyszczenie zasobów

Aby wyczyścić wszystkie zasoby używane w tym przewodniku Szybki start, usuń grupę zasobów przy użyciu następującego polecenia:

az group delete \
    --name $AZ_RESOURCE_GROUP \
    --yes

Następne kroki

Aby dowiedzieć się więcej na temat wdrażania aplikacji Spring Data w usłudze Azure Spring Apps i używania tożsamości zarządzanej, zobacz Samouczek: wdrażanie aplikacji Spring w usłudze Azure Spring Apps przy użyciu połączenia bez hasła z bazą danych platformy Azure.

Aby dowiedzieć się więcej na temat oprogramowania Spring i platformy Azure, przejdź do centrum dokumentacji dotyczącej oprogramowania Spring na platformie Azure.

Zobacz też

Aby uzyskać więcej informacji na temat rozwiązania Spring Data R2DBC, zobacz dokumentację referencyjną platformy Spring.

Aby uzyskać więcej informacji na temat używania platformy Azure z językiem Java, zobacz artykuły dotyczące platformy Azure dla deweloperów języka Java oraz pracy z usługą Azure DevOps i językiem Java.