Använda Spring Data R2DBC med Azure Database for MySQL
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 Database for MySQL med R2DBC-implementeringen för MySQL från GitHub-lagringsplatsen r2dbc-mysql.
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
En Azure-prenumeration – skapa en kostnadsfritt.
Java Development Kit (JDK), version 8 eller senare.
cURL eller ett liknande HTTP-verktyg för att testa funktioner.
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-mysql.
Förbereda arbetsmiljön
Konfigurera först vissa miljövariabler genom att köra följande kommandon:
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>
Ersätt platshållarna med följande värden, som används i hela artikeln:
<YOUR_DATABASE_NAME>
: Namnet på din MySQL-server, som ska vara unik i Hela Azure.<YOUR_AZURE_REGION>
: Den Azure-region som du ska använda. Du kan användaeastus
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älpaz account list-locations
av .<YOUR_MYSQL_ADMIN_PASSWORD>
och<YOUR_MYSQL_NON_ADMIN_PASSWORD>
: Lösenordet för mySQL-databasservern, 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).
Kommentar
Microsoft rekommenderar att du använder det säkraste tillgängliga autentiseringsflödet. Det autentiseringsflöde som beskrivs i den här proceduren, till exempel för databaser, cacheminnen, meddelanden eller AI-tjänster, kräver en mycket hög grad av förtroende för programmet och medför risker som inte finns i andra flöden. Använd endast det här flödet när säkrare alternativ, till exempel hanterade identiteter för lösenordslösa eller nyckellösa anslutningar, inte är genomförbara. För lokala datoråtgärder föredrar du användaridentiteter för lösenordslösa eller nyckellösa anslutningar.
Skapa sedan en resursgrupp:
az group create \
--name $AZ_RESOURCE_GROUP \
--location $AZ_LOCATION \
--output tsv
Skapa en Azure Database for MySQL-instans och konfigurera administratörsanvändaren
Det första du skapar är en hanterad MySQL-server med en administratörsanvändare.
Kommentar
Du kan läsa mer om att skapa MySQL-servrar i Skapa en Azure Database for MySQL-server i Azure-portalen.
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
Konfigurera en MySQL-databas
Skapa en ny databas med demo
namnet med hjälp av följande kommando:
az mysql flexible-server db create \
--resource-group $AZ_RESOURCE_GROUP \
--database-name demo \
--server-name $AZ_DATABASE_NAME \
--output tsv
Konfigurera en brandväggsregel för MySQL-servern
Azure Database for MySQL-instanser skyddas som standard. Databaserna har en brandvägg som inte tillåter inkommande anslutningar.
Du kan hoppa över det här steget om du använder Bash eftersom flexible-server create
kommandot redan har identifierat din lokala IP-adress och angett den på MySQL-servern.
Om du ansluter till MySQL-servern 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 nameserver
och 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 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
Skapa en MySQL-användare 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
.
Kommentar
Du kan läsa mer detaljerad information om hur du skapar MySQL-användare i Skapa användare i Azure Database for MySQL.
Skapa först 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:
Kommentar
Microsoft rekommenderar att du använder det säkraste tillgängliga autentiseringsflödet. Det autentiseringsflöde som beskrivs i den här proceduren, till exempel för databaser, cacheminnen, meddelanden eller AI-tjänster, kräver en mycket hög grad av förtroende för programmet och medför risker som inte finns i andra flöden. Använd endast det här flödet när säkrare alternativ, till exempel hanterade identiteter för lösenordslösa eller nyckellösa anslutningar, inte är genomförbara. För lokala datoråtgärder föredrar du användaridentiteter för lösenordslösa eller nyckellösa anslutningar.
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
Använd sedan följande kommando för att köra SQL-skriptet för att skapa användaren som inte är administratör:
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
Använd nu följande kommando för att ta bort den tillfälliga SQL-skriptfilen:
rm create_user.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 appen via kommandoraden genom att ange följande:
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ägga till den reaktiva implementeringen av MySQL-drivrutinen
Öppna det genererade projektets pom.xml-fil för att lägga till den reaktiva MySQL-drivrutinen från lagringsplatsen r2dbc-mysql på GitHub.
Efter beroendet spring-boot-starter-webflux
lägger du till följande kodavsnitt:
<dependency>
<groupId>io.asyncer</groupId>
<artifactId>r2dbc-mysql</artifactId>
<version>0.9.1</version>
</dependency>
Konfigurera Spring Boot för att använda Azure Database for MySQL
Öppna filen src/main/resources/application.properties och lägg till:
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
Ersätt variablerna $AZ_DATABASE_NAME
och $AZ_MYSQL_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:
./mvnw spring-boot:run
Här är en skärmbild av när appen körs för första gången:
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 SERIAL PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BOOLEAN);
Stoppa programmet som körs och starta det igen. 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:
Koda appen
Lägg sedan till Java-koden som använder R2DBC för att lagra och hämta data från MySQL-servern.
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:
Grattis! Du har skapat ett helt reaktivt Spring Boot-program som använder R2DBC för att lagra och hämta data från Azure Database for MySQL.
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.