Partilhar via


Usar o Spring Data R2DBC com o Banco de Dados do Azure para MySQL

Este artigo demonstra a criação de um aplicativo de exemplo que usa o Spring Data R2DBC para armazenar e recuperar informações no Banco de Dados do Azure para MySQL usando a implementação R2DBC para MySQL do repositório GitHub r2dbc-mysql.

O R2DBC permite utilizar APIs reativas nas bases de dados relacionais tradicionais. Você pode usá-lo com o Spring WebFlux para criar aplicativos Spring Boot totalmente reativos que usam APIs sem bloqueio. Ele fornece melhor escalabilidade do que a abordagem clássica de "um thread por conexão".

Pré-requisitos

  • Cliente de linha de comando MySQL.

  • cURL ou um utilitário HTTP semelhante para testar a funcionalidade.

Veja o aplicativo de exemplo

Neste artigo, você codificará um aplicativo de exemplo. Se você quiser ir mais rápido, este aplicativo já está codificado e disponível em https://github.com/Azure-Samples/quickstart-spring-data-r2dbc-mysql.

Preparar o ambiente de trabalho

Primeiro, configure algumas variáveis de ambiente executando os seguintes comandos:

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>

Substitua os marcadores de posição pelos seguintes valores, que são utilizados ao longo deste artigo:

  • <YOUR_DATABASE_NAME>: O nome do seu servidor MySQL, que deve ser exclusivo no Azure.
  • <YOUR_AZURE_REGION>: A região do Azure que você usará. Pode utilizar a região eastus por predefinição, mas recomendamos que configure uma região mais próxima do local onde vive. Você pode ver a lista completa de regiões disponíveis usando az account list-locations.
  • <YOUR_MYSQL_ADMIN_PASSWORD> e <YOUR_MYSQL_NON_ADMIN_PASSWORD>: A senha do seu servidor de banco de dados MySQL, que deve ter um mínimo de oito caracteres. Os caracteres devem ser de três das seguintes categorias: letras maiúsculas inglesas, letras minúsculas inglesas, números (0-9) e caracteres não alfanuméricos (!, $, #, % e assim por diante).

Depois, crie um grupo de recursos:

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

Criar um Banco de Dados do Azure para instância MySQL e configurar o usuário administrador

A primeira coisa que você criará é um servidor MySQL gerenciado com um usuário administrador.

Nota

Pode ler informações mais detalhadas sobre a criação de servidores MySQL no artigo Criar um servidor MySQL da Base de Dados do Azure para MySQL através do portal do Azure.

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

Configurar uma base de dados MySQL

Crie um novo banco de dados chamado demo usando o seguinte comando:

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

Configurar uma regra de firewall para o servidor MySQL

As instâncias do Banco de Dados do Azure para MySQL são protegidas por padrão. O serviço tem uma firewall que não permite ligações de entrada.

Você pode pular esta etapa se estiver usando o Bash porque o flexible-server create comando já detetou seu endereço IP local e o definiu no servidor MySQL.

Se você estiver se conectando ao seu servidor MySQL a partir do Windows Subsystem for Linux (WSL) em um computador Windows, você precisará adicionar o ID de host WSL ao seu firewall. Obtenha o endereço IP da sua máquina host executando o seguinte comando no WSL:

cat /etc/resolv.conf

Copie o endereço IP após o termo nameservere, em seguida, use o seguinte comando para definir uma variável de ambiente para o endereço IP WSL:

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

Em seguida, use o seguinte comando para abrir o firewall do servidor para seu aplicativo baseado em WSL:

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

Crie um usuário não-administrador do MySQL e conceda permissão

Esta etapa criará um usuário não administrador e concederá todas as permissões no demo banco de dados a ele.

Nota

Você pode ler informações mais detalhadas sobre como criar usuários do MySQL em Criar usuários no Banco de Dados do Azure para MySQL.

Primeiro, crie um script SQL chamado create_user.sql para criar um usuário não administrador. Adicione o seguinte conteúdo e salve-o localmente:

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

Em seguida, use o seguinte comando para executar o script SQL para criar o usuário não administrador:

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

Agora use o seguinte comando para remover o arquivo de script SQL temporário:

rm create_user.sql

Criar uma aplicação Spring Boot reativa

Para criar um aplicativo Spring Boot reativo, usaremos o Spring Initializr. A aplicação que iremos criar utiliza:

  • Bota de mola 2.7.11.
  • As seguintes dependências: Spring Reative Web (também conhecido como Spring WebFlux) e Spring Data R2DBC.

Gerar a aplicação com o Spring Initializr

Gere a aplicação na linha de comandos ao introduzir:

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 -

Adicionar a implementação do controlador MySQL reativo

Abra o arquivo pom.xml do projeto gerado para adicionar o driver MySQL reativo do repositório r2dbc-mysql no GitHub.

Depois da dependência spring-boot-starter-webflux, adicione o seguinte fragmento:

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

Configurar o Spring Boot para utilizar a Base de Dados do Azure para MySQL

Abra o arquivo src/main/resources/application.properties e adicione:

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

Substitua as $AZ_DATABASE_NAME variáveis e $AZ_MYSQL_NON_ADMIN_PASSWORD pelos valores que você configurou no início deste artigo.

Nota

Para um melhor desempenho, a propriedade é configurada spring.r2dbc.url para usar um pool de conexões usando r2dbc-pool.

Agora você deve ser capaz de iniciar seu aplicativo usando o wrapper Maven fornecido:

./mvnw spring-boot:run

Eis uma captura de ecrã da aplicação em execução pela primeira vez:

Screenshot of the running application.

Criar o esquema da base de dados

Dentro da classe principal DemoApplication , configure um novo Spring bean que criará um esquema de banco de dados, usando o seguinte código:

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

Este Spring bean usa um arquivo chamado schema.sql, portanto, crie esse arquivo na pasta src/main/resources e adicione o seguinte texto:

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

Pare o aplicativo em execução e inicie-o novamente. Agora, a aplicação irá utilizar a base de dados demo que criou anteriormente e criar uma tabela todo na mesma.

./mvnw spring-boot:run

Aqui está uma captura de tela da tabela do banco de dados enquanto ela está sendo criada:

Screenshot of the creation of the database table.

Codificar a aplicação

Em seguida, adicione o código Java que usará o R2DBC para armazenar e recuperar dados do seu servidor MySQL.

Crie uma nova Todo classe Java, ao lado da DemoApplication classe, usando o seguinte código:

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

Esta classe é um modelo de domínio mapeado na tabela todo que criou anteriormente.

Para gerir essa classe, precisa de um repositório. Defina uma nova TodoRepository interface no mesmo pacote, usando o seguinte código:

package com.example.demo;

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

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

Este repositório é um repositório reativo que o Spring Data R2DBC gerencia.

Conclua o aplicativo criando um controlador que possa armazenar e recuperar dados. Implemente uma classe TodoController no mesmo pacote e adicione o seguinte código:

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

Por último, pare a aplicação e inicie-a novamente com o seguinte comando:

./mvnw spring-boot:run

Testar a aplicação

Pode utilizar o cURL para testar a aplicação.

Comece por criar um item "todo" na base de dados ao utilizar o seguinte comando:

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

Este comando deve retornar o item criado, conforme mostrado aqui:

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

Em seguida, recupere os dados usando uma nova solicitação cURL com o seguinte comando:

curl http://127.0.0.1:8080

Este comando retornará a lista de itens "todo", incluindo o item que você criou, conforme mostrado aqui:

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

Aqui está uma captura de tela dessas solicitações de cURL:

Screenshot of the cURL test.

Parabéns! Você criou um aplicativo Spring Boot totalmente reativo que usa o R2DBC para armazenar e recuperar dados do Banco de Dados do Azure para MySQL.

Clean up resources (Limpar recursos)

Para limpar todos os recursos usados durante este início rápido, exclua o grupo de recursos usando o seguinte comando:

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

Próximos passos

Para saber mais sobre como implantar um aplicativo Spring Data no Azure Spring Apps e usar a identidade gerenciada, consulte Tutorial: Implantar um aplicativo Spring no Azure Spring Apps com uma conexão sem senha para um banco de dados do Azure.

Para saber mais sobre o Spring e o Azure, avance para o centro de documentação relativa ao Spring no Azure.

Consulte também

Para obter mais informações sobre o Spring Data R2DBC, consulte a documentação de referência do Spring.

Para obter mais informações sobre a utilização do Azure com o Java, veja Azure para programadores de Java e Trabalhar com o Azure DevOps e Java.