Share via


Spring Data R2DBC gebruiken met Azure Database for PostgreSQL

In dit artikel wordt gedemonstreerd hoe u een voorbeeldtoepassing maakt die Spring Data R2DBC gebruikt om informatie op te slaan en op te halen in een Azure Database for PostgreSQL-database. In het voorbeeld wordt de R2DBC-implementatie voor PostgreSQL gebruikt vanuit de r2dbc-postgresql-opslagplaats op GitHub.

R2DBC brengt reactieve API's naar traditionele relationele databases. U kunt het gebruiken met Spring WebFlux om volledig reactieve Spring Boot-toepassingen te maken die gebruikmaken van niet-blokkerende API's. Het biedt een betere schaalbaarheid dan de klassieke benadering 'één thread per verbinding'.

Vereisten

Bekijk de voorbeeldtoepassing

In dit artikel codet u een voorbeeldtoepassing. Als u sneller wilt gaan, is deze toepassing al gecodeerd en beschikbaar op https://github.com/Azure-Samples/quickstart-spring-data-r2dbc-postgresql.

De werkomgeving voorbereiden

Stel eerst enkele omgevingsvariabelen in door de volgende opdrachten uit te voeren:

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>

Vervang de tijdelijke aanduidingen door de volgende waarden, die overal in dit artikel worden gebruikt:

  • <YOUR_DATABASE_SERVER_NAME>: De naam van uw PostgreSQL-server, die uniek moet zijn in Azure.
  • <YOUR_DATABASE_NAME>: De databasenaam van de PostgreSQL-server, die uniek moet zijn binnen Azure.
  • <YOUR_AZURE_REGION>: de Azure-regio die u gaat gebruiken. U kunt standaard eastus gebruiken, maar we raden u aan om een regio dichtbij uw locatie te configureren. U kunt de volledige lijst met beschikbare regio's bekijken met behulp van az account list-locations.
  • <YOUR_POSTGRESQL_ADMIN_PASSWORD> en <YOUR_POSTGRESQL_NON_ADMIN_PASSWORD>: het wachtwoord van uw PostgreSQL-databaseserver, die minimaal acht tekens moet bevatten. De tekens moeten uit drie van de volgende categorieën bestaan: Nederlandse hoofdletters, Nederlandse kleine letters, cijfers (0-9) en niet-alfanumerieke tekens (!, $, #, %, enzovoort).
  • <YOUR_LOCAL_IP_ADDRESS>: Het IP-adres van uw lokale computer, van waaruit u uw Spring Boot-toepassing uitvoert. Een handige manier om het te vinden is door whatismyip.akamai.com te openen.

Maak vervolgens een resourcegroep met de volgende opdracht:

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

Een Azure Database for PostgreSQL-exemplaar maken en de gebruiker met beheerdersrechten instellen

Het eerste wat u maakt, is een beheerde PostgreSQL-server met een gebruiker met beheerdersrechten.

Notitie

Meer gedetailleerde informatie over het maken van PostgreSQL-servers leest u in Een Azure Database for PostgreSQL-server maken via Azure Portal.

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

Een PostgreSQL-database configureren

De PostgreSQL-server die u eerder hebt gemaakt, is leeg. Gebruik de volgende opdracht om een nieuwe database te maken.

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

Een firewallregel voor uw PostgreSQL-server configureren

Azure Database for PostgreSQL-instanties worden standaard beveiligd. Ze hebben een firewall die geen enkele binnenkomende verbinding toestaat. Om uw database te kunnen gebruiken, moet u een firewallregel toevoegen waarmee het lokale IP-adres toegang krijgt tot de databaseserver.

Aangezien u aan het begin van dit artikel een lokaal IP-adres hebt geconfigureerd, kunt u de firewall van de server openen door de volgende opdracht uit te voeren:

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

Als u verbinding maakt met uw PostgreSQL-server vanaf Windows-subsysteem voor Linux (WSL) op een Windows-computer, moet u de WSL-host-id toevoegen aan uw firewall.

Haal het IP-adres van uw hostcomputer op door de volgende opdracht uit te voeren in WSL:

cat /etc/resolv.conf

Kopieer het IP-adres na de term nameserveren gebruik vervolgens de volgende opdracht om een omgevingsvariabele in te stellen voor het WSL IP-adres:

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

Gebruik vervolgens de volgende opdracht om de firewall van de server te openen naar uw WSL-app:

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

Een postgreSQL-gebruiker zonder beheerdersrechten maken en toestemming verlenen

Maak vervolgens een niet-beheerder en verdeel alle machtigingen aan de database.

Notitie

Meer gedetailleerde informatie over het maken van PostgreSQL-gebruikers vindt u in Create users in Azure Database for PostgreSQL.

Maak een SQL-script met de naam create_user.sql voor het maken van een niet-beheerdersgebruiker. Voeg de volgende inhoud toe en sla deze lokaal op:

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

Gebruik vervolgens de volgende opdracht om het SQL-script uit te voeren om de niet-beheerdersgebruiker van Microsoft Entra te maken:

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

Gebruik nu de volgende opdracht om het tijdelijke SQL-scriptbestand te verwijderen:

rm create_user.sql

Een reactieve Spring Boot-toepassing maken

Als u een reactieve Spring Boot-toepassing wilt maken, gebruiken we Spring Initializr. De toepassing die we gaan maken, maakt gebruik van:

  • Spring Boot 2.7.11.
  • De volgende afhankelijkheden: Spring Reactive Web (ook wel Bekend als Spring WebFlux) en Spring Data R2DBC.

De toepassing genereren met Spring Initializr

Genereer de toepassing op de opdrachtregel met behulp van de volgende opdracht:

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 -

De implementatie van het reactieve PostgreSQL-stuurprogramma toevoegen

Open het pom.xml-bestand van het gegenereerde project en voeg vervolgens het reactieve PostgreSQL-stuurprogramma toe vanuit de r2dbc-postgresql-opslagplaats op GitHub. Voeg na de spring-boot-starter-webflux afhankelijkheid de volgende tekst toe:

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

Spring Boot configureren voor het gebruik van Azure Database for PostgreSQL

Open het bestand src/main/resources/application.properties en voeg de volgende tekst toe:

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

Vervang de $AZ_DATABASE_SERVER_NAME, $AZ_DATABASE_NAMEen $AZ_POSTGRESQL_NON_ADMIN_PASSWORD variabelen door de waarden die u aan het begin van dit artikel hebt geconfigureerd.

Waarschuwing

Om veiligheidsredenen moet Azure Database for PostgreSQL SSL-verbindingen gebruiken. Daarom moet u de spring.r2dbc.properties.sslMode=REQUIRE configuratie-eigenschap toevoegen, anders probeert het R2DBC PostgreSQL-stuurprogramma verbinding te maken met behulp van een onveilige verbinding, wat mislukt.

Notitie

Voor betere prestaties is de spring.r2dbc.url eigenschap geconfigureerd voor het gebruik van een verbindingsgroep met behulp van r2dbc-pool.

U moet nu uw toepassing als volgt kunnen starten met behulp van de meegeleverde Maven-wrapper:

./mvnw spring-boot:run

Hier volgt een schermopname van de toepassing die voor de eerste keer wordt uitgevoerd:

Screenshot of the running application.

Het databaseschema maken

Configureer in de hoofdklasse DemoApplication een nieuwe Spring-bean die een databaseschema maakt met behulp van de volgende code:

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

Deze Spring bean maakt gebruik van een bestand met de naam schema.sql, dus maak dat bestand in de map src/main/resources en voeg de volgende tekst toe:

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

Stop de actieve toepassing en start deze opnieuw met behulp van de volgende opdracht. De toepassing gebruikt nu de demo-database die u eerder hebt gemaakt, en er wordt een tabel todo in deze database gemaakt.

./mvnw spring-boot:run

Hier volgt een schermopname van de databasetabel terwijl deze wordt gemaakt:

Screenshot of the creation of the database table.

De toepassing coderen

Voeg vervolgens de Java-code toe die R2DBC gebruikt om gegevens op te slaan en op te halen van uw PostgreSQL-server.

Maak een nieuwe Todo Java-klasse naast de DemoApplication klasse met behulp van de volgende code:

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

Deze klasse is een domeinmodel dat is toegewezen aan de tabel todo die u eerder hebt gemaakt.

Als u deze klasse wilt beheren, hebt u een opslagplaats nodig. Definieer een nieuwe TodoRepository interface in hetzelfde pakket met behulp van de volgende code:

package com.example.demo;

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

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

Deze opslagplaats is een reactieve opslagplaats die Spring Data R2DBC beheert.

Voltooi de toepassing door een controller te maken die gegevens kan opslaan en ophalen. Implementeer een TodoController-klasse in hetzelfde pakket en voeg de volgende code toe:

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

Stop tot slot de toepassing en start deze opnieuw met behulp van de volgende opdracht:

./mvnw spring-boot:run

De toepassing testen

Als u de toepassing wilt testen, kunt u cURL gebruiken.

Maak eerst een nieuw 'todo'-item in de database met behulp van de volgende opdracht:

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

Met deze opdracht wordt het gemaakte item geretourneerd, zoals hier wordt weergegeven:

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

Haal vervolgens de gegevens op met behulp van een nieuwe cURL-aanvraag met de volgende opdracht:

curl http://127.0.0.1:8080

Met deze opdracht wordt de lijst met todo-items geretourneerd, inclusief het item dat u hebt gemaakt, zoals hier wordt weergegeven:

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

Hier volgt een schermopname van deze cURL-aanvragen:

Screenshot of the cURL test.

Gefeliciteerd. U hebt een volledig reactieve Spring Boot-toepassing gemaakt die gebruikmaakt van R2DBC om gegevens op te slaan en op te halen uit Azure Database for PostgreSQL.

Resources opschonen

Als u alle resources wilt opschonen die tijdens deze quickstart worden gebruikt, verwijdert u de resourcegroep met behulp van de volgende opdracht:

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

Volgende stappen

Zie zelfstudie: Een Spring-toepassing implementeren in Azure Spring Apps met een wachtwoordloze verbinding met een Azure-database voor meer informatie over het implementeren van een Spring Data-toepassing in Azure Spring Apps en het gebruik van beheerde identiteiten.

Voor meer informatie over Spring en Azure gaat u door naar het documentatiecentrum van Spring op Azure.

Zie ook

Zie de referentiedocumentatie van Spring voor meer informatie over Spring Data R2DBC.

Voor meer informatie over Azure gebruiken met Java, raadpleegt u Azure voor Java-ontwikkelaars en Werken met Azure DevOps en Java.