Använda Spring Data R2DBC med Azure Database for PostgreSQL

Den här artikeln visar hur du skapar ett exempelprogram som använder Spring Data R2DBC för att lagra och hämta information i en Azure Database for PostgreSQL-databas . Exemplet använder R2DBC-implementeringen för PostgreSQL från lagringsplatsen r2dbc-postgresql på GitHub.

R2DBC tillhandahåller reaktiva API:er till traditionella relationsdatabaser. Du kan använda den med Spring WebFlux för att skapa helt reaktiva Spring Boot-program som använder icke-blockerande API:er. Det ger bättre skalbarhet än den klassiska metoden "en tråd per anslutning".

Förutsättningar

Se exempelprogrammet

I den här artikeln kodar du ett exempelprogram. Om du vill gå snabbare är det här programmet redan kodat och tillgängligt på https://github.com/Azure-Samples/quickstart-spring-data-r2dbc-postgresql.

Förbereda arbetsmiljön

Konfigurera först vissa miljövariabler genom att köra följande kommandon:

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>

Ersätt platshållarna med följande värden, som används i hela artikeln:

  • <YOUR_DATABASE_SERVER_NAME>: Namnet på din PostgreSQL-server, som ska vara unik i Hela Azure.
  • <YOUR_DATABASE_NAME>: Databasnamnet på PostgreSQL-servern, som ska vara unik i Azure.
  • <YOUR_AZURE_REGION>: Den Azure-region som du ska använda. Du kan använda eastus som standard, men vi rekommenderar att du konfigurerar den region som är närmast dig. Du kan se den fullständiga listan över tillgängliga regioner med hjälp az account list-locationsav .
  • <YOUR_POSTGRESQL_ADMIN_PASSWORD> och <YOUR_POSTGRESQL_NON_ADMIN_PASSWORD>: Lösenordet för PostgreSQL-databasservern, som ska innehålla minst åtta tecken. Tecknen ska vara från tre av följande kategorier: engelska versaler, engelska gemener, siffror (0–9) och icke-alfanumeriska tecken (!, $, #, %och så vidare).
  • <YOUR_LOCAL_IP_ADDRESS>: IP-adressen för den lokala datorn som du ska köra Spring Boot-programmet från. Ett praktiskt sätt att hitta det är att öppna whatismyip.akamai.com.

Skapa sedan en resursgrupp med hjälp av följande kommando:

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

Skapa en Azure Database for PostgreSQL-instans och konfigurera administratörsanvändaren

Det första du skapar är en hanterad PostgreSQL-server med en administratörsanvändare.

Kommentar

Du kan läsa mer detaljerad information om hur du skapar PostgreSQL-servrar i Skapa en Azure Database for PostgreSQL-server med hjälp av Azure-portalen.

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

Konfigurera en PostgreSQL-databas

PostgreSQL-servern som du skapade tidigare är tom. Använd följande kommando för att skapa en ny databas.

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

Konfigurera en brandväggsregel för PostgreSQL-servern

Azure Database for PostgreSQL-instanser skyddas som standard. Databaserna har en brandvägg som inte tillåter inkommande anslutningar. För att kunna använda databasen måste du lägga till en brandväggsregel som gör att den lokala IP-adressen kan komma åt databasservern.

Eftersom du konfigurerade din lokala IP-adress i början av den här artikeln kan du öppna serverns brandvägg genom att köra följande kommando:

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

Om du ansluter till PostgreSQL-servern från Windows-undersystem för Linux (WSL) på en Windows-dator måste du lägga till WSL-värd-ID:t i brandväggen.

Hämta IP-adressen för värddatorn genom att köra följande kommando i WSL:

cat /etc/resolv.conf

Kopiera IP-adressen efter termen nameserveroch använd sedan följande kommando för att ange en miljövariabel för WSL IP-adressen:

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

Använd sedan följande kommando för att öppna serverns brandvägg till din WSL-baserade 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

Skapa en PostgreSQL-användare som inte är administratör och bevilja behörighet

Skapa sedan en icke-administratörsanvändare och bevilja alla behörigheter till databasen.

Kommentar

Du kan läsa mer detaljerad information om hur du skapar PostgreSQL-användare i Skapa användare i Azure Database for PostgreSQL.

Skapa ett SQL-skript med namnet create_user.sql för att skapa en icke-administratörsanvändare. Lägg till följande innehåll och spara det lokalt:

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

Använd sedan följande kommando för att köra SQL-skriptet för att skapa microsoft Entra-användaren som inte är administratör:

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

Använd nu följande kommando för att ta bort den tillfälliga SQL-skriptfilen:

rm create_user.sql

Skapa ett reaktivt Spring Boot-program

För att skapa ett reaktivt Spring Boot-program använder vi Spring Initializr. Programmet som vi ska skapa använder:

  • Spring Boot 2.7.11.
  • Följande beroenden: Spring Reactive Web (kallas även Spring WebFlux) och Spring Data R2DBC.

Generera appen med Spring Initializr

Generera programmet på kommandoraden med hjälp av följande kommando:

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 -

Lägg till den reaktiva PostgreSQL-drivrutinsimplementeringen

Öppna det genererade projektets pom.xml-fil och lägg sedan till den reaktiva PostgreSQL-drivrutinen från lagringsplatsen r2dbc-postgresql på GitHub. Efter beroendet spring-boot-starter-webflux lägger du till följande text:

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

Konfigurera Spring Boot för att använda Azure Database for PostgreSQL

Öppna filen src/main/resources/application.properties och lägg till följande text:

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

Ersätt variablerna $AZ_DATABASE_SERVER_NAME, $AZ_DATABASE_NAMEoch $AZ_POSTGRESQL_NON_ADMIN_PASSWORD med de värden som du konfigurerade i början av den här artikeln.

Varning

Av säkerhetsskäl måste Azure Database for PostgreSQL använda SSL-anslutningar. Det är därför du måste lägga till konfigurationsegenskapen spring.r2dbc.properties.sslMode=REQUIRE , annars försöker R2DBC PostgreSQL-drivrutinen ansluta med en osäker anslutning, vilket misslyckas.

Kommentar

För bättre prestanda är egenskapen spring.r2dbc.url konfigurerad för att använda en anslutningspool med hjälp av r2dbc-pool.

Nu bör du kunna starta programmet med hjälp av den angivna Maven-omslutningen på följande sätt:

./mvnw spring-boot:run

Här är en skärmbild av när appen körs för första gången:

Screenshot of the running application.

Skapa databasschemat

I huvudklassen DemoApplication konfigurerar du en ny Spring-böna som skapar ett databasschema med hjälp av följande kod:

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

Den här Spring-bönan använder en fil med namnet schema.sql, så skapa filen i mappen src/main/resources och lägg till följande text:

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

Stoppa programmet som körs och starta det igen med hjälp av följande kommando. Programmet kommer nu att använda databasen demo, som du skapade tidigare, och skapa en todo-tabell i den.

./mvnw spring-boot:run

Här är en skärmbild av databastabellen när den skapas:

Screenshot of the creation of the database table.

Koda appen

Lägg sedan till Java-koden som använder R2DBC för att lagra och hämta data från PostgreSQL-servern.

Skapa en ny Todo Java-klass bredvid DemoApplication klassen med hjälp av följande kod:

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

Den här klassen är en domänmodell som är mappad på den todo-tabell som du skapade tidigare.

Om du vill hantera den här klassen behöver du en lagringsplats. Definiera ett nytt TodoRepository gränssnitt i samma paket med hjälp av följande kod:

package com.example.demo;

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

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

Den här lagringsplatsen är en reaktiv lagringsplats som Spring Data R2DBC hanterar.

Slutför programmet genom att skapa en kontrollant som kan lagra och hämta data. Implementera en TodoController-klass i samma paket och lägg till följande 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();
    }
}

Stoppa slutligen appen och starta den igen med följande kommando:

./mvnw spring-boot:run

Testa programmet

Du kan testa appen med cURL.

Skapa först ett nytt ”att göra”-objekt i databasen med följande kommando:

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

Det här kommandot ska returnera det skapade objektet, som du ser här:

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

Hämta sedan data med hjälp av en ny cURL-begäran med följande kommando:

curl http://127.0.0.1:8080

Det här kommandot returnerar listan med "att göra"-objekt, inklusive det objekt som du har skapat, enligt följande:

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

Här är en skärmbild av dessa cURL-begäranden:

Screenshot of the cURL test.

Klar! Du har skapat ett helt reaktivt Spring Boot-program som använder R2DBC för att lagra och hämta data från Azure Database for PostgreSQL.

Rensa resurser

Om du vill rensa alla resurser som används under den här snabbstarten tar du bort resursgruppen med hjälp av följande kommando:

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

Nästa steg

Mer information om hur du distribuerar ett Spring Data-program till Azure Spring Apps och använder hanterad identitet finns i Självstudie: Distribuera ett Spring-program till Azure Spring Apps med en lösenordslös anslutning till en Azure-databas.

Om du vill veta mer om Spring och Azure kan du fortsätta till dokumentationscentret för Spring i Azure.

Se även

Mer information om Spring Data R2DBC finns i Spring referensdokumentation.

Mer information om hur du använder Azure med Java finns i Azure för Java-utvecklare och Arbeta med Azure DevOps och Java.