Share via


Verwenden von Spring Data R2DBC mit Azure Database for MySQL

In diesem Artikel wird die Erstellung einer Beispielanwendung veranschaulicht, die Spring Data R2DBC verwendet, um Informationen in einer Azure Database for MySQL-Instanz mithilfe der R2DBC-Implementierung für MySQL aus dem GitHub-Repository „r2dbc-mysql“ zu speichern und abzurufen.

R2DBC ermöglicht die Nutzung reaktiver APIs mit herkömmlichen relationalen Datenbanken. Sie können es zusammen mit Spring WebFlux verwenden, um vollständig reaktive Spring Boot-Anwendungen zu erstellen, die nicht blockierende APIs verwenden. Dies bietet bessere Skalierbarkeit als der klassische „Ein-Thread-pro-Verbindung“-Ansatz.

Voraussetzungen

Sehen Sie sich die Beispielanwendung an

In diesem Artikel codierten Sie eine Beispielanwendung. Wenn Sie schneller vorgehen möchten, ist diese Anwendung unter https://github.com/Azure-Samples/quickstart-spring-data-r2dbc-mysql bereits programmiert und verfügbar.

Vorbereiten der Arbeitsumgebung

Richten Sie zunächst einige Umgebungsvariablen ein, indem Sie die folgenden Befehle ausführen:

export AZ_RESOURCE_GROUP=database-workshop
export AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
export AZ_LOCATION=<YOUR_AZURE_REGION>
export AZ_MYSQL_ADMIN_USERNAME=spring
export AZ_MYSQL_ADMIN_PASSWORD=<YOUR_MYSQL_ADMIN_PASSWORD>
export AZ_MYSQL_NON_ADMIN_USERNAME=spring-non-admin
export AZ_MYSQL_NON_ADMIN_PASSWORD=<YOUR_MYSQL_NON_ADMIN_PASSWORD>

Ersetzen Sie die Platzhalter durch die folgenden Werte, die in diesem Artikel verwendet werden:

  • <YOUR_DATABASE_NAME>: Der Name Ihres MySQL-Servers, der in Azure eindeutig sein sollte.
  • <YOUR_AZURE_REGION>: Die von Ihnen verwendete Azure-Region. Sie können standardmäßig eastus verwenden, wir empfehlen aber, eine Region zu konfigurieren, die näher an Ihrem Standort liegt. Sie können die vollständige Liste der verfügbaren Regionen mithilfe az account list-locationsvon .
  • <YOUR_MYSQL_ADMIN_PASSWORD> und <YOUR_MYSQL_NON_ADMIN_PASSWORD>: Das Kennwort Ihres MySQL-Datenbankservers, der mindestens acht Zeichen enthalten sollte. Es muss Zeichen aus drei der folgenden Kategorien enthalten: Englische Großbuchstaben, englische Kleinbuchstaben, Zahlen (0-9) und nicht alphanumerische Zeichen (!, $, #, % usw.).

Erstellen Sie als Nächstes eine Ressourcengruppe:

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

Erstellen einer Azure-Datenbank für MySQL-Instanz und Einrichten des Administratorbenutzers

Als Erstes erstellen Sie einen verwalteten MySQL-Server mit einem Administratorbenutzer.

Hinweis

Ausführlichere Informationen zum Erstellen von MySQL-Servern finden Sie unter Erstellen eines Azure Database for MySQL-Servers im Azure-Portal.

az mysql flexible-server create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME \
    --location $AZ_LOCATION \
    --admin-user $AZ_MYSQL_ADMIN_USERNAME \
    --admin-password $AZ_MYSQL_ADMIN_PASSWORD \
    --yes \
    --output tsv

Konfigurieren einer MySQL-Datenbank

Erstellen Sie mit dem folgenden Befehl eine neue Datenbank namens demo:

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

Konfigurieren einer Firewallregel für den MySQL-Server

Azure Database for MySQL-Instanzen sind standardmäßig gesichert. Sie besitzen eine Firewall, die keine eingehenden Verbindungen zulässt.

Sie können diesen Schritt überspringen, wenn Sie Bash verwenden, da der flexible-server create-Befehl Ihre lokale IP-Adresse bereits erkannt und auf dem MySQL-Server festgelegt hat.

Wenn Sie eine Verbindung mit Ihrem MySQL-Server von Windows-Subsystem für Linux (WSL) auf einem Windows-Computer herstellen, müssen Sie der Firewall die WSL-Host-ID hinzufügen. Rufen Sie die IP-Adresse Ihres Hostcomputers ab, indem Sie den folgenden Befehl in WSL ausführen:

cat /etc/resolv.conf

Kopieren Sie die IP-Adresse nach dem Ausdruck nameserver, und verwenden Sie dann den folgenden Befehl, um eine Umgebungsvariable für die WSL-IP-Adresse festzulegen:

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

Verwenden Sie dann den folgenden Befehl, um die Firewall des Servers für Ihre WSL-basierte App zu öffnen:

az mysql flexible-server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME \
    --start-ip-address $AZ_WSL_IP_ADDRESS \
    --end-ip-address $AZ_WSL_IP_ADDRESS \
    --rule-name allowiprange \
    --output tsv

Erstellen eines MySQL-Nicht-Administratorbenutzers und Erteilen von Berechtigungen

In diesem Schritt wird ein Nicht-Administrator-Benutzer erstellt und ihm alle Berechtigungen für die demo Datenbank erteilt.

Hinweis

Ausführlichere Informationen zum Erstellen von MySQL-Benutzern finden Sie unter Erstellen von Benutzern in Azure Database for MySQL.

Erstellen Sie zunächst ein SQL-Skript namens create_user.sql zum Erstellen eines Nicht-Administratorbenutzers. Fügen Sie den folgenden Inhalt hinzu, und speichern Sie das Skript lokal:

cat << EOF > create_user.sql
CREATE USER '$AZ_MYSQL_NON_ADMIN_USERNAME'@'%' IDENTIFIED BY '$AZ_MYSQL_NON_ADMIN_PASSWORD';
GRANT ALL PRIVILEGES ON demo.* TO '$AZ_MYSQL_NON_ADMIN_USERNAME'@'%';
FLUSH PRIVILEGES;
EOF

Verwenden Sie dann den folgenden Befehl, um das SQL-Skript auszuführen, um den Nicht-Administratorbenutzer zu erstellen:

mysql -h $AZ_DATABASE_NAME.mysql.database.azure.com --user $AZ_MYSQL_ADMIN_USERNAME --enable-cleartext-plugin --password=$AZ_MYSQL_ADMIN_PASSWORD < create_user.sql

Verwenden Sie nun den folgenden Befehl, um die temporäre SQL-Skriptdatei zu entfernen:

rm create_user.sql

Erstellen einer reaktiven Spring Boot-Anwendung

Zum Erstellen einer reaktiven Spring Boot-Anwendung wird Spring Initializr verwendet. Die von uns erstellte Anwendung verwendet Folgendes:

  • Spring Boot 2.7.11.
  • Die folgenden Abhängigkeiten: Spring Reactive Web (auch als Spring WebFlux bezeichnet) und Spring Data R2DBC.

Erstellen der Anwendung mithilfe von Spring Initializr

Generieren der Anwendung an der Befehlszeile durch Eingeben von:

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 -

Hinzufügen der reaktiven MySQL-Treiberimplementierung

Öffnen Sie die pom.xml-Datei des generierten Projekts, um den reaktiven MySQL-Treiber aus dem r2dbc-mysql-Repository auf GitHub hinzuzufügen.

Fügen Sie nach der Abhängigkeit spring-boot-starter-webflux den folgenden Codeausschnitt hinzu:

<dependency>
  <groupId>io.asyncer</groupId>
  <artifactId>r2dbc-mysql</artifactId>
  <version>0.9.1</version>
</dependency>

Konfigurieren von Spring Boot für die Verwendung von Azure Database for MySQL

Öffnen Sie die Datei src/main/resources/application.properties, und fügen Sie Folgendes hinzu:

logging.level.org.springframework.data.r2dbc=DEBUG

spring.r2dbc.url=r2dbc:pool:mysql://$AZ_DATABASE_NAME.mysql.database.azure.com:3306/demo?tlsVersion=TLSv1.2
spring.r2dbc.username=spring-non-admin
spring.r2dbc.password=$AZ_MYSQL_NON_ADMIN_PASSWORD

Ersetzen Sie die $AZ_DATABASE_NAME Und-Variablen $AZ_MYSQL_NON_ADMIN_PASSWORD durch die Werte, die Sie am Anfang dieses Artikels konfiguriert haben.

Hinweis

Zur Verbesserung der Leistung ist die spring.r2dbc.url-Eigenschaft so konfiguriert, dass ein Verbindungspool mit r2dbc-pool verwendet wird.

Sie sollten Ihre Anwendung nun mithilfe des angegebenen Maven-Wrappers starten können:

./mvnw spring-boot:run

Hier sehen Sie einen Screenshot der Anwendung bei der ersten Ausführung:

Screenshot of the running application.

Erstellen des Datenbankschemas

Konfigurieren Sie in der DemoApplication-Hauptklasse mit dem folgenden Code eine neue Spring Bean, die ein Datenbankschema erstellt:

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

Diese Spring Bean verwendet eine Datei namens schema.sql. Erstellen Sie daher diese Datei im Ordner src/main/resources, und fügen Sie den folgenden Text hinzu:

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

Halten Sie die ausgeführte Anwendung an, und starten Sie sie erneut. Die Anwendung verwendet nun die Datenbank demo, die Sie zuvor erstellt haben, und erstellt darin eine todo-Tabelle.

./mvnw spring-boot:run

Hier sehen Sie einen Screenshot der Datenbanktabelle während der Erstellung:

Screenshot of the creation of the database table.

Codieren der Anwendung

Fügen Sie als Nächstes den Java-Code hinzu, der R2DBC zum Speichern und Abrufen von Daten aus Ihrem MySQL-Server verwendet.

Erstellen Sie neben der Klasse DemoApplication mit dem folgenden Code eine neue Todo-Java-Klasse:

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

Bei dieser Klasse handelt es sich um ein Domänenmodell, das der zuvor erstellten todo-Tabelle zugeordnet ist.

Sie benötigen ein Repository, um diese Klasse zu verwalten. Definieren Sie mit dem folgenden Code eine neue TodoRepository-Schnittstelle im gleichen Paket:

package com.example.demo;

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

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

Dieses Repository ist ein reaktives Repository, das von Spring Data R2DBC verwaltet wird.

Stellen Sie die Anwendung fertig, indem Sie einen Controller erstellen, der Daten speichern und abrufen kann. Implementieren Sie eine TodoController-Klasse im gleichen Paket, und fügen Sie den folgenden Code hinzu:

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

Halten Sie die Anwendung schließlich an, und starten Sie sie mit dem folgenden Befehl erneut:

./mvnw spring-boot:run

Testen der Anwendung

Zum Testen der Anwendung können Sie cURL verwenden.

Erstellen Sie zunächst mit dem folgenden Befehl ein neues todo-Element in der Datenbank:

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

Mit diesem Befehl sollte das erstellte Element wie hier gezeigt zurückgegeben werden:

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

Rufen Sie anschließend die Daten mithilfe einer neuen cURL-Anforderung mit dem folgenden Befehl ab:

curl http://127.0.0.1:8080

Mit dem folgenden Befehl wird wie hier gezeigt die Liste der „todo“-Elemente zurückgegeben, einschließlich des von Ihnen erstellten Elements:

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

Hier sehen Sie einen Screenshot dieser cURL-Anforderungen:

Screenshot of the cURL test.

Herzlichen Glückwunsch! Sie haben eine vollständig reaktive Spring Boot-Anwendung erstellt, die R2DBC zum Speichern und Abrufen von Daten in bzw. aus Azure Database for MySQL verwendet.

Bereinigen von Ressourcen

Um alle während dieser Schnellstartanleitung verwendeten Ressourcen zu sauber, löschen Sie die Ressourcengruppe mithilfe des folgenden Befehls:

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

Nächste Schritte

Weitere Informationen zum Bereitstellen einer Spring Data-Anwendung für Azure Spring Apps und die Verwendung verwalteter Identitäten finden Sie im Lernprogramm: Bereitstellen einer Spring-Anwendung in Azure Spring Apps mit einer kennwortlosen Verbindung zu einer Azure-Datenbank.

Weitere Informationen zu Spring und Azure finden Sie im Dokumentationscenter zu Spring in Azure.

Siehe auch

Weitere Informationen zu Spring Data R2DBC finden Sie in der Referenzdokumentation zu Spring.

Weitere Informationen zur Verwendung von Azure mit Java finden Sie unter Azure für Java-Entwickler und Working with Azure DevOps and Java (Arbeiten mit Azure DevOps und Java).