Verwenden von Spring Data R2DBC mit Azure SQL-Datenbank
In diesem Artikel wird die Erstellung einer Beispielanwendung veranschaulicht, die Spring Data R2DBC verwendet, um Informationen in Azure SQL-Datenbank mithilfe der R2DBC-Implementierung für Microsoft SQL Server aus dem GitHub-Repository „r2dbc-mssql“ 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
Azure-Abonnement (kostenloses Abonnement erstellen)
Java Development Kit (JDK), Version 8 oder höher.
cURL oder ein ähnliches HTTP-Hilfsprogramm zum Testen der Funktionalität.
Siehe die Beispielanwendung
In diesem Artikel wird eine Beispielanwendung codiert. Wenn Sie schneller vorgehen möchten, ist diese Anwendung unter https://github.com/Azure-Samples/quickstart-spring-data-r2dbc-sql-server bereits programmiert und verfügbar.
Vorbereiten der Arbeitsumgebung
Richten Sie zunächst mithilfe der folgenden Befehle einige Umgebungsvariablen ein:
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>
Ersetzen Sie die Platzhalter durch die folgenden Werte, die in diesem Artikel verwendet werden:
<YOUR_DATABASE_NAME>
: Der Name Ihres Azure SQL-Datenbank-Servers, der in Azure eindeutig sein soll.<YOUR_AZURE_REGION>
: Die von Ihnen verwendete Azure-Region. Sie können standardmäßigeastus
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 mithilfeaz account list-locations
von .<AZ_SQL_SERVER_ADMIN_PASSWORD>
und<AZ_SQL_SERVER_NON_ADMIN_PASSWORD>
: Das Kennwort Ihres Azure SQL-Datenbank-Servers, das 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.).<YOUR_LOCAL_IP_ADDRESS>
: Die IP-Adresse Ihres lokalen Computers, auf dem Sie die Spring Boot-Anwendung ausführen. Sie können sie ganz einfach ermitteln, indem Sie whatismyip.akamai.com öffnen.
Hinweis
Microsoft empfiehlt, immer den sichersten Authentifizierungsflow zu verwenden, der verfügbar ist. Der in diesem Verfahren beschriebene Authentifizierungsfluss, z. B. für Datenbanken, Caches, Nachrichten oder KI-Dienste, erfordert ein sehr hohes Vertrauen in die Anwendung und trägt Risiken, die in anderen Flüssen nicht vorhanden sind. Verwenden Sie diesen Fluss nur, wenn sicherere Optionen wie verwaltete Identitäten für kennwortlose oder schlüssellose Verbindungen nicht geeignet sind. Bei Vorgängen des lokalen Computers bevorzugen Sie Benutzeridentitäten für kennwortlose oder schlüssellose Verbindungen.
Erstellen Sie nun mithilfe des folgenden Befehls eine Ressourcengruppe:
az group create \
--name $AZ_RESOURCE_GROUP \
--location $AZ_LOCATION \
--output tsv
Erstellen einer Azure SQL-Datenbankinstanz
Erstellen Sie als Nächstes eine verwaltete Azure SQL-Datenbank Serverinstanz, indem Sie den folgenden Befehl ausführen.
Hinweis
Das MS SQL-Kennwort muss bestimmte Kriterien erfüllen, und das Setup schlägt mit einem nicht kompatiblen Kennwort fehl. Weitere Informationen finden Sie unter Password Policy.
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
Konfigurieren einer Firewallregel für den Azure SQL-Datenbank-Server
Azure SQL-Datenbankinstanzen sind standardmäßig gesichert. Sie besitzen eine Firewall, die keine eingehenden Verbindungen zulässt. Damit Sie die Datenbank verwenden können, müssen Sie eine Firewallregel hinzufügen, die den Zugriff der lokalen IP-Adresse auf den Datenbankserver zulässt.
Da Sie die lokale IP-Adresse zu Beginn dieses Artikels konfiguriert haben, können Sie die Firewall des Servers öffnen, indem Sie den folgenden Befehl ausführen:
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
Wenn Sie über das Windows-Subsystem für Linux (WSL) auf einem Windows-Computer eine Verbindung mit Ihrem Azure SQL-Datenbank-Server 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 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
Konfigurieren einer Azure SQL-Datenbank
Der von Ihnen zuvor erstellte Azure SQL-Datenbank-Server ist leer. Er verfügt über keine Datenbank, die Sie mit der Spring Boot-Anwendung verwenden können. Erstellen Sie durch Ausführen des folgenden Befehls eine neue Datenbank namens demo
:
az sql db create \
--resource-group $AZ_RESOURCE_GROUP \
--name demo \
--server $AZ_DATABASE_NAME \
--output tsv
Erstellen eines SQL-Datenbankbenutzers ohne Administratorrechte und Erteilen von Berechtigungen
In diesem Schritt wird ein Benutzer ohne Administratorrechte erstellt und ihm alle Berechtigungen für die demo
Datenbank erteilt.
Erstellen Sie 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:
Hinweis
Microsoft empfiehlt, immer den sichersten Authentifizierungsflow zu verwenden, der verfügbar ist. Der in diesem Verfahren beschriebene Authentifizierungsfluss, z. B. für Datenbanken, Caches, Nachrichten oder KI-Dienste, erfordert ein sehr hohes Vertrauen in die Anwendung und trägt Risiken, die in anderen Flüssen nicht vorhanden sind. Verwenden Sie diesen Fluss nur, wenn sicherere Optionen wie verwaltete Identitäten für kennwortlose oder schlüssellose Verbindungen nicht geeignet sind. Bei Vorgängen des lokalen Computers bevorzugen Sie Benutzeridentitäten für kennwortlose oder schlüssellose Verbindungen.
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
Verwenden Sie dann den folgenden Befehl, um das SQL-Skript auszuführen, um den Benutzer ohne Administratorrechte zu erstellen:
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
Hinweis
Weitere Informationen zum Erstellen von SQL-Datenbankbenutzern finden Sie unter CREATE USER (Transact-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 Sie die Anwendung durch Ausführen des folgenden Befehls in der Befehlszeile:
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 Treiberimplementierung für Azure SQL-Datenbank
Öffnen Sie die Datei pom.xml des generierten Projekts, um den reaktiven Azure SQL-Datenbank-Treiber aus dem GitHub-Repository „r2dbc-mssql“ hinzuzufügen.
Fügen Sie nach der Abhängigkeit spring-boot-starter-webflux
den folgenden Text hinzu:
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-mssql</artifactId>
<scope>runtime</scope>
</dependency>
Konfigurieren von Spring Boot für die Verwendung von Azure SQL-Datenbank
Öffnen Sie die Datei src/main/resources/application.properties, und fügen Sie den folgenden Text hinzu:
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
Ersetzen Sie die beiden $AZ_DATABASE_NAME
-Variablen und die $AZ_SQL_SERVER_NON_ADMIN_PASSWORD
-Variable durch die Werte, die Sie zu Beginn 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 wie folgt starten können:
./mvnw spring-boot:run
Hier sehen Sie einen Screenshot der Anwendung bei der ersten Ausführung:
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 INT IDENTITY PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BIT);
Halten Sie die ausgeführte Anwendung an, und starten Sie sie mit dem folgenden Befehl 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:
Codieren der Anwendung
Fügen Sie als Nächstes den Java-Code hinzu, der R2DBC zum Speichern und Abrufen von Daten auf bzw. aus Ihrem Azure SQL-Datenbank-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:
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 SQL-Datenbank verwendet.
Bereinigen von Ressourcen
Um alle während dieser Schnellstartanleitung verwendeten Ressourcen zu bereinigen, 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).