Dela via


Använda Spring Data R2DBC med Azure SQL Database

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 Azure SQL Database med hjälp av R2DBC-implementeringen för Microsoft SQL Server från GitHub-lagringsplatsen r2dbc-mssql.

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-sql-server.

Förbereda arbetsmiljön

Konfigurera först några miljövariabler med följande kommandon:

export AZ_RESOURCE_GROUP=database-workshop
export AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
export AZ_LOCATION=<YOUR_AZURE_REGION>
export AZ_SQL_SERVER_ADMIN_USERNAME=spring
export AZ_SQL_SERVER_ADMIN_PASSWORD=<YOUR_AZURE_SQL_ADMIN_PASSWORD>
export AZ_SQL_SERVER_NON_ADMIN_USERNAME=nonspring
export AZ_SQL_SERVER_NON_ADMIN_PASSWORD=<YOUR_AZURE_SQL_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_NAME>: Namnet på din Azure SQL Database-server, som ska vara unik i Hela 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 .
  • <AZ_SQL_SERVER_ADMIN_PASSWORD> och <AZ_SQL_SERVER_NON_ADMIN_PASSWORD>: Lösenordet för din Azure SQL Database-server, 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 SQL Database-instans

Skapa sedan en hanterad Azure SQL Database-serverinstans genom att köra följande kommando.

Kommentar

MS SQL-lösenordet måste uppfylla specifika kriterier och installationen misslyckas med ett lösenord som inte är kompatibelt. Mer information finns i Lösenordsprincip.

az sql server create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME \
    --location $AZ_LOCATION \
    --admin-user $AZ_SQL_SERVER_ADMIN_USERNAME \
    --admin-password $AZ_SQL_SERVER_ADMIN_PASSWORD \
    --output tsv

Konfigurera en brandväggsregel för din Azure SQL Database-server

Azure SQL Database-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 sql server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME-database-allow-local-ip \
    --server $AZ_DATABASE_NAME \
    --start-ip-address $AZ_LOCAL_IP_ADDRESS \
    --end-ip-address $AZ_LOCAL_IP_ADDRESS \
    --output tsv

Om du ansluter till Din Azure SQL Database-server 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 sql server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME-database-allow-local-ip-wsl \
    --server $AZ_DATABASE_NAME \
    --start-ip-address $AZ_WSL_IP_ADDRESS \
    --end-ip-address $AZ_WSL_IP_ADDRESS \
    --output tsv

Konfigurera en Azure SQL-databas

Azure SQL Database-servern som du skapade tidigare är tom. Den har ingen databas du kan använda med Spring Boot-appen. Skapa en ny databas med namnet demo genom att köra följande kommando:

az sql db create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name demo \
    --server $AZ_DATABASE_NAME \
    --output tsv

Skapa en SQL-databas som inte är administratör och bevilja behörighet

Det här steget skapar en icke-administratörsanvändare och beviljar alla behörigheter för databasen till den demo .

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
USE demo;
GO
CREATE USER $AZ_SQL_SERVER_NON_ADMIN_USERNAME WITH PASSWORD='$AZ_SQL_SERVER_NON_ADMIN_PASSWORD'
GO
GRANT CONTROL ON DATABASE::demo TO $AZ_SQL_SERVER_NON_ADMIN_USERNAME;
GO
EOF

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

sqlcmd -S $AZ_DATABASE_NAME.database.windows.net,1433  -d demo -U $AZ_SQL_SERVER_ADMIN_USERNAME -P $AZ_SQL_SERVER_ADMIN_PASSWORD  -i create_user.sql

Kommentar

Mer information om hur du skapar SQL-databasanvändare finns i CREATE USER (Transact-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 genom att köra 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 implementeringen av den reaktiva Azure SQL Database-drivrutinen

Öppna det genererade projektets pom.xml-fil för att lägga till den reaktiva Azure SQL Database-drivrutinen från GitHub-lagringsplatsen r2dbc-mssql.

Efter beroendet spring-boot-starter-webflux lägger du till följande text:

<dependency>
    <groupId>io.r2dbc</groupId>
    <artifactId>r2dbc-mssql</artifactId>
    <scope>runtime</scope>
</dependency>

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

Ö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:mssql://$AZ_DATABASE_NAME.database.windows.net:1433/demo
spring.r2dbc.username=nonspring@$AZ_DATABASE_NAME
spring.r2dbc.password=$AZ_SQL_SERVER_NON_ADMIN_PASSWORD

Ersätt de två $AZ_DATABASE_NAME variablerna och variabeln $AZ_SQL_SERVER_NON_ADMIN_PASSWORD med de värden som du konfigurerade i början av den här artikeln.

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 INT IDENTITY PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BIT);

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 ska använda R2DBC för att lagra och hämta data från din Azure SQL Database-server.

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 SQL Database.

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.