Použití Spring Data R2DBC se službou Azure SQL Database

Tento článek ukazuje, jak vytvořit ukázkovou aplikaci, která používá Spring Data R2DBC k ukládání a načítání informací v Azure SQL Database pomocí implementace R2DBC pro Microsoft SQL Server z úložiště r2dbc-mssql GitHub.

R2DBC přináší reaktivní rozhraní API do tradičních relačních databází. Pomocí aplikace Spring WebFlux můžete vytvářet plně reaktivní aplikace Spring Boot, které používají neblokující rozhraní API. Poskytuje lepší škálovatelnost než klasický přístup „jedno vlákno na jedno připojení“.

Požadavky

Zobrazení ukázkové aplikace

V tomto článku zakódujete ukázkovou aplikaci. Pokud chcete přejít rychleji, tato aplikace je již kódována a k dispozici na adrese https://github.com/Azure-Samples/quickstart-spring-data-r2dbc-sql-server.

Příprava pracovního prostředí

Nejprve pomocí následujících příkazů nastavte několik proměnných prostředí:

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>

Zástupné symboly nahraďte následujícími hodnotami, které se používají v tomto článku:

  • <YOUR_DATABASE_NAME>: Název vašeho serveru Azure SQL Database, který by měl být jedinečný v rámci Azure.
  • <YOUR_AZURE_REGION>: Oblast Azure, kterou použijete. Ve výchozím nastavení můžete používat eastus, ale nastavte si oblast, která je blíže místu, kde žijete. Úplný seznam dostupných oblastí zobrazíte pomocí az account list-locations.
  • <AZ_SQL_SERVER_ADMIN_PASSWORD> a <AZ_SQL_SERVER_NON_ADMIN_PASSWORD>: Heslo vašeho serveru Azure SQL Database, které by mělo mít minimálně osm znaků. Znaky by měly být ze tří z následujících kategorií: velká písmena anglické abecedy, malá písmena anglické abecedy, číslice (0–9) a jiné než alfanumerické znaky (!, $, #, %atd.).
  • <YOUR_LOCAL_IP_ADDRESS>: IP adresa místního počítače, ze kterého spustíte aplikaci Spring Boot. Jedním z pohodlných způsobů, jak ji najít, je otevřít whatismyip.akamai.com.

Poznámka:

Microsoft doporučuje používat nejbezpečnější dostupný tok ověřování. Tok ověřování popsaný v tomto postupu, například pro databáze, mezipaměti, zasílání zpráv nebo služby AI, vyžaduje velmi vysoký stupeň důvěryhodnosti v aplikaci a nese rizika, která nejsou přítomna v jiných tocích. Tento postup používejte pouze v případě, že bezpečnější možnosti, například spravované identity pro připojení bez hesla nebo bez klíčů, nejsou proveditelné. V případě místních operací počítačů upřednostňujete identity uživatelů pro připojení bez hesla nebo bez klíčů.

Dále pomocí následujícího příkazu vytvořte skupinu prostředků:

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

Vytvoření instance azure SQL Database

V dalším kroku vytvořte spravovanou instanci serveru Azure SQL Database spuštěním následujícího příkazu.

Poznámka:

Heslo MS SQL musí splňovat konkrétní kritéria a nastavení selže s nevyhovujícím heslem. Další informace najdete v tématu Zásady hesel.

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

Nakonfigurujte pravidlo brány firewall pro server Azure SQL Database

Instance Azure SQL Database jsou ve výchozím nastavení zabezpečené. Mají firewall, který neumožňuje žádná příchozí spojení. Pokud chcete použít databázi, musíte přidat pravidlo brány firewall, které umožňuje přístup k databázovému serveru vaší místní IP adrese.

Vzhledem k tomu, že jste na začátku tohoto článku nakonfigurovali místní IP adresu, můžete bránu firewall serveru otevřít spuštěním následujícího příkazu:

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

Pokud se k serveru Azure SQL Database připojujete ze Subsystému Windows pro Linux (WSL) na počítači se systémem Windows, musíte do brány firewall přidat ID hostitele WSL.

Spuštěním následujícího příkazu ve WSL získejte IP adresu vašeho hostitelského počítače:

cat /etc/resolv.conf

Zkopírujte IP adresu za termínem nameservera pak pomocí následujícího příkazu nastavte proměnnou prostředí pro IP adresu WSL:

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

Pak pomocí následujícího příkazu otevřete bránu firewall serveru pro vaši aplikaci založenou na WSL:


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

Konfigurace databáze Azure SQL

Server Azure SQL Database, který jste vytvořili dříve, je prázdný. Neobsahuje žádnou databázi, kterou můžete s aplikací Spring Boot použít. Vytvořte novou databázi volanou demo spuštěním následujícího příkazu:

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

Vytvoření uživatele, který není správcem databáze SQL, a udělení oprávnění

V tomto kroku vytvoříte uživatele bez oprávnění správce a udělíte mu všechna oprávnění k demo databázi.

Vytvořte skript SQL s názvem create_user.sql pro vytvoření uživatele bez oprávnění správce. Přidejte následující obsah a uložte ho místně:

Poznámka:

Microsoft doporučuje používat nejbezpečnější dostupný tok ověřování. Tok ověřování popsaný v tomto postupu, například pro databáze, mezipaměti, zasílání zpráv nebo služby AI, vyžaduje velmi vysoký stupeň důvěryhodnosti v aplikaci a nese rizika, která nejsou přítomna v jiných tocích. Tento postup používejte pouze v případě, že bezpečnější možnosti, například spravované identity pro připojení bez hesla nebo bez klíčů, nejsou proveditelné. V případě místních operací počítačů upřednostňujete identity uživatelů pro připojení bez hesla nebo bez klíčů.

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

Pak pomocí následujícího příkazu spusťte skript SQL a vytvořte uživatele bez oprávnění správce:

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

Poznámka:

Další informace o vytváření uživatelů databáze SQL naleznete v tématu CREATE USER (Transact-SQL).


Vytvoření reaktivní aplikace Spring Boot

K vytvoření reaktivní aplikace Spring Boot použijeme Spring Initializr. Aplikace, kterou vytvoříme, používá:

  • Spring Boot 2.7.11.
  • Následující závislosti: Spring Reactive Web (označovaný také jako Spring WebFlux) a Spring Data R2DBC.

Vygenerování aplikace pomocí Spring Initializr

Spuštěním následujícího příkazu vygenerujte aplikaci na příkazovém řádku:

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 -

Přidání reaktivní implementace ovladače služby Azure SQL Database

Otevřete soubor pom.xml vygenerovaného projektu a přidejte reaktivní ovladač Azure SQL Database z úložiště GitHub r2dbc-mssql.

Po závislosti spring-boot-starter-webflux přidejte následující text:

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

Konfigurace Spring Bootu pro použití služby Azure SQL Database

Otevřete soubor src/main/resources/application.properties a přidejte následující 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

Nahraďte dvě $AZ_DATABASE_NAME proměnné a $AZ_SQL_SERVER_NON_ADMIN_PASSWORD proměnnou hodnotami, které jste nakonfigurovali na začátku tohoto článku.

Poznámka:

Pro lepší výkon je vlastnost spring.r2dbc.url nakonfigurována tak, aby používala fond připojení s využitím r2dbc-pool.

Teď můžete aplikaci spustit pomocí poskytnuté obálky Maven následujícím způsobem:

./mvnw spring-boot:run

Zde je obrázek poprvé spuštěné aplikace:

Snímek obrazovky se spuštěnou aplikací

Vytvoření schématu databáze

V hlavní DemoApplication třídě nakonfigurujte novou sadu Spring bean, která vytvoří schéma databáze pomocí následujícího kódu:

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

Tato aplikace Spring bean používá soubor s názvem schema.sql, takže ho vytvořte ve složce src/main/resources a přidejte následující text:

DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id INT IDENTITY PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BIT);

Zastavte spuštěnou aplikaci a spusťte ji znovu pomocí následujícího příkazu. Aplikace teď používá demo databázi, kterou jste vytvořili dříve, a vytvoří todo v ní tabulku.

./mvnw spring-boot:run

Tady je snímek obrazovky s tabulkou databáze při vytváření:

Snímek obrazovky s vytvořením databázové tabulky

Vytvoření kódu aplikace

Dále přidejte Java kód, který používá R2DBC k ukládání a načítání dat z vašeho Azure SQL Database serveru.

Vytvořte novou Todo třídu Java vedle DemoApplication třídy pomocí následujícího kódu:

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

Tato třída je doménový model mapovaný na tabulku todo, kterou jste vytvořili dřív.

Ke správě této třídy budete potřebovat úložiště. Pomocí následujícího kódu definujte nové TodoRepository rozhraní ve stejném balíčku:

package com.example.demo;

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

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

Toto úložiště je reaktivní úložiště, které spravuje Spring Data R2DBC.

Dokončete aplikaci vytvořením kontroleru, který může ukládat a načítat data. Ve stejném balíčku implementujte třídu TodoController a přidejte následující kód:

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

Nakonec aplikaci zastavte a znovu ji spusťte pomocí následujícího příkazu:

./mvnw spring-boot:run

Testování aplikace

K otestování aplikace můžete použít cURL.

Nejprve pomocí následujícího příkazu vytvořte v databázi novou položku „úkolu“:

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

Tento příkaz by měl vrátit vytvořenou položku, jak je znázorněno tady:

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

Potom načtěte data pomocí nového požadavku cURL pomocí následujícího příkazu:

curl http://127.0.0.1:8080

Tento příkaz vrátí seznam položek "todo", včetně položky, kterou jste vytvořili, jak je znázorněno tady:

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

Tady je snímek obrazovky s těmito požadavky cURL:

Snímek obrazovky s testem cURL

Gratulujeme! Vytvořili jste plně reaktivní aplikaci Spring Boot, která k ukládání a načítání dat z Azure SQL Database používá R2DBC.

Vyčištění prostředků

Pokud chcete vyčistit všechny prostředky použité během tohoto rychlého startu, odstraňte skupinu prostředků pomocí následujícího příkazu:

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

Další kroky

Další informace o nasazení aplikace Spring Data do Azure Spring Apps a použití spravované identity najdete v tématu Kurz: Nasazení aplikace Spring do Azure Spring Apps s bez heslem připojení k databázi Azure.

Pokud se chcete dozvědět více o architektuře Spring a Azure, přejděte do centra dokumentace Spring v Azure.

Viz také

Další informace o Spring Data R2DBC najdete v referenční dokumentaci spring.

Další informace o používání Azure s jazykem Java najdete v článku Azure pro vývojáře v jazyce Java a Práce s Azure DevOps a jazykem Java.