Udostępnij za pośrednictwem


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

W tym artykule przedstawiono tworzenie przykładowej aplikacji korzystającej z narzędzia Spring Data R2DBC do przechowywania i pobierania informacji w usłudze Azure SQL Database przy użyciu implementacji R2DBC dla programu Microsoft SQL Server z repozytorium GitHub r2dbc-mssql.

Łą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

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

Przygotowywanie środowiska roboczego

Najpierw skonfiguruj niektóre zmienne środowiskowe za pomocą następujących poleceń:

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>

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

  • <YOUR_DATABASE_NAME>: nazwa serwera usługi Azure SQL Database, 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.
  • <AZ_SQL_SERVER_ADMIN_PASSWORD> i <AZ_SQL_SERVER_NON_ADMIN_PASSWORD>: Hasło serwera usługi Azure SQL Database, 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.

Uwaga

Firma Microsoft zaleca korzystanie z najbezpieczniejszego dostępnego przepływu uwierzytelniania. Przepływ uwierzytelniania opisany w tej procedurze, taki jak bazy danych, pamięci podręczne, komunikaty lub usługi sztucznej inteligencji, wymaga bardzo wysokiego stopnia zaufania w aplikacji i niesie ze sobą ryzyko, które nie występują w innych przepływach. Użyj tego przepływu tylko wtedy, gdy bardziej bezpieczne opcje, takie jak tożsamości zarządzane dla połączeń bez hasła lub bez kluczy, nie są opłacalne. W przypadku operacji maszyny lokalnej preferuj tożsamości użytkowników dla połączeń bez hasła lub bez klucza.

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

Następnie utwórz zarządzane wystąpienie serwera usługi Azure SQL Database, uruchamiając następujące polecenie.

Uwaga

Hasło MS SQL musi spełniać określone kryteria, a konfiguracja zakończy się niepowodzeniem z niezgodnym hasłem. Aby uzyskać więcej informacji, zobacz Zasady haseł.

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

Konfigurowanie reguły zapory dla serwera usługi Azure SQL Database

Wystąpienia usługi Azure SQL Database 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 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

Jeśli łączysz się z serwerem usługi Azure SQL Database 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 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

Konfigurowanie bazy danych Azure SQL Database

Utworzony wcześniej serwer usługi Azure SQL Database jest pusty. Nie ma on żadnej bazy danych, której można użyć z aplikacją platformy Spring Boot. Utwórz nową bazę danych o nazwie demo , uruchamiając następujące polecenie:

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

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

Ten krok spowoduje utworzenie użytkownika niebędącego administratorem i przyznanie mu wszystkich uprawnień do demo bazy danych.

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:

Uwaga

Firma Microsoft zaleca korzystanie z najbezpieczniejszego dostępnego przepływu uwierzytelniania. Przepływ uwierzytelniania opisany w tej procedurze, taki jak bazy danych, pamięci podręczne, komunikaty lub usługi sztucznej inteligencji, wymaga bardzo wysokiego stopnia zaufania w aplikacji i niesie ze sobą ryzyko, które nie występują w innych przepływach. Użyj tego przepływu tylko wtedy, gdy bardziej bezpieczne opcje, takie jak tożsamości zarządzane dla połączeń bez hasła lub bez kluczy, nie są opłacalne. W przypadku operacji maszyny lokalnej preferuj tożsamości użytkowników dla połączeń bez hasła lub bez klucza.

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

Następnie użyj następującego polecenia, aby uruchomić skrypt SQL w celu utworzenia użytkownika niebędącego administratorem:

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

Uwaga

Aby uzyskać więcej informacji na temat tworzenia użytkowników bazy danych SQL, zobacz CREATE USER (Transact-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, uruchamiając następujące polecenie:

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 usługi Azure SQL Database

Otwórz plik pom.xml wygenerowanego projektu, aby dodać reaktywny sterownik usługi Azure SQL Database z repozytorium GitHub r2dbc-mssql.

spring-boot-starter-webflux Po zależności dodaj następujący tekst:

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

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

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: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

Zastąp dwie $AZ_DATABASE_NAME zmienne i $AZ_SQL_SERVER_NON_ADMIN_PASSWORD zmienną wartościami skonfigurowanymi na początku tego artykułu.

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:

Zrzut ekranu przedstawiający uruchomioną aplikację.

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

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:

Zrzut ekranu przedstawiający tworzenie tabeli bazy danych.

Kodowanie aplikacji

Następnie dodaj kod Java, który będzie używać R2DBC do przechowywania i pobierania danych z serwera usługi Azure SQL Database.

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:

Zrzut ekranu przedstawiający test cURL.

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

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.