Início Rápido: Usar o Java e o JDBC com o Banco de Dados do Azure para MySQL

APLICA-SE A: Banco de Dados do Azure para MySQL – Servidor Único

Importante

O servidor único do Banco de Dados do Azure para MySQL está no caminho da desativação. É altamente recomendável que você atualize para o servidor flexível do Banco de Dados do Azure para MySQL. Para obter mais informações sobre a migração para o servidor flexível do Banco de Dados do Azure para MySQL, confira O que está acontecendo com o Servidor Único do Banco de Dados do Azure para MySQL?

Este artigo demonstra como criar um aplicativo de exemplo que usa o Java e o JDBC para armazenar e recuperar informações no Banco de Dados do Azure para MySQL.

O JDBC é a API Java padrão para se conectar a bancos de dados relacionais tradicionais.

Neste artigo, vamos incluir dois métodos de autenticação: autenticação do Microsoft Entra e autenticação do MySQL. A guia Sem senha mostra a autenticação do Microsoft Entra e a guia Senha mostra a autenticação do MySQL.

A autenticação do Microsoft Entra é um mecanismo para conexão ao Banco de Dados do Azure para MySQL que usa as identidades definidas no Microsoft Entra ID. Com a autenticação do Microsoft Entra, você pode gerenciar as identidades de usuários do banco de dados e outros serviços da Microsoft em uma só localização central, o que simplifica o gerenciamento de permissões.

A autenticação do MySQL usa as contas armazenadas no MySQL. Se você optar por usar senhas como credenciais para as contas, essas credenciais serão armazenadas na tabela user. Como essas senhas são armazenadas no MySQL, você precisará gerenciar a rotação das senhas sozinho.

Pré-requisitos

  • Uma conta do Azure. Se você não tiver uma, obtenha uma avaliação gratuita.
  • Azure Cloud Shell ou CLI do Azure. É recomendável usar o Azure Cloud Shell para que o logon seja feito automaticamente e você tenha acesso a todas as ferramentas necessárias.
  • Um Java Development Kit compatível, versão 8 (incluído no Azure Cloud Shell).
  • A ferramenta de build Apache Maven.
  • Cliente da linha de comando MySQL. Você pode se conectar ao servidor usando a ferramenta de linha de comando mysql.exe com o Azure Cloud Shell. Como alternativa, use a linha de comando do mysql em seu ambiente local.

Preparar o ambiente de trabalho

Primeiro, vamos configurar algumas variáveis de ambiente. No Azure Cloud Shell, execute os seguintes comandos:

export AZ_RESOURCE_GROUP=database-workshop
export AZ_DATABASE_SERVER_NAME=<YOUR_DATABASE_SERVER_NAME>
export AZ_DATABASE_NAME=demo
export AZ_LOCATION=<YOUR_AZURE_REGION>
export AZ_MYSQL_AD_NON_ADMIN_USERNAME=demo-non-admin
export AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>
export CURRENT_USERNAME=$(az ad signed-in-user show --query userPrincipalName -o tsv)
export CURRENT_USER_OBJECTID=$(az ad signed-in-user show --query id -o tsv)

Substitua os espaços reservados pelos seguintes valores, que são usados em todo este artigo:

  • <YOUR_DATABASE_SERVER_NAME>: o nome do servidor MySQL, que deve ser exclusivo no Azure.
  • <YOUR_AZURE_REGION>: A região do Azure que você usará. Você pode usar eastus por padrão, mas é recomendável configurar uma região mais próxima de onde você mora. Você pode ver a lista completa de regiões disponíveis inserindo az account list-locations.
  • <YOUR_LOCAL_IP_ADDRESS>: o endereço IP do computador local, no qual você executará o aplicativo. Uma forma conveniente de encontrá-lo é abrir whatismyip.akamai.com.

Em seguida, crie um grupo de recursos usando o seguinte comando:

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

Criar uma instância do Banco de Dados do Azure para MySQL

Criar um servidor MySQL e configurar um usuário administrador

A primeira coisa que você irá criar é um servidor MySQL gerenciado.

Observação

Você pode ler informações mais detalhadas sobre como criar servidores MySQL em Início Rápido: Criar um servidor de Banco de Dados do Azure para MySQL usando o portal do Azure.

Se você estiver usando a CLI do Azure, execute o seguinte comando para garantir que ele tenha permissão suficiente:

az login --scope https://graph.microsoft.com/.default

Então execute o seguinte comando para criar o servidor:

az mysql server create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_SERVER_NAME \
    --location $AZ_LOCATION \
    --sku-name B_Gen5_1 \
    --storage-size 5120 \
    --output tsv

Em seguida, execute o seguinte comando para definir o usuário administrador do Microsoft Entra:

az mysql server ad-admin create \
    --resource-group $AZ_RESOURCE_GROUP \
    --server-name $AZ_DATABASE_SERVER_NAME \
    --display-name $CURRENT_USERNAME \
    --object-id $CURRENT_USER_OBJECTID

Importante

Ao definir o administrador, um novo usuário é adicionado ao servidor do Banco de Dados do Azure para MySQL com permissões completas de administrador. Você só pode criar um administrador do Microsoft Entra por servidor MySQL. A seleção de outro usuário substituirá o administrador existente do Microsoft Entra configurado para o servidor.

Esse comando cria um servidor MySQL pequeno e define o administrador do Active Directory como o usuário conectado.

Configurar uma regra de firewall para o servidor MySQL

As instâncias dos Bancos de Dados do Azure para MySQL são protegidas por padrão. Essas instâncias têm um firewall que não permite nenhuma conexão de entrada. Para usar o banco de dados, você precisa adicionar uma regra de firewall que permitirá que o endereço IP local acesse o servidor de banco de dados.

Como você configurou seu endereço IP local no início deste artigo, abra o firewall do servidor executando o seguinte comando:

az mysql server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip \
    --server $AZ_DATABASE_SERVER_NAME \
    --start-ip-address $AZ_LOCAL_IP_ADDRESS \
    --end-ip-address $AZ_LOCAL_IP_ADDRESS \
    --output tsv

Se você estiver se conectando ao servidor MySQL do Subsistema do Windows para Linux (WSL) em um computador Windows, precisará adicionar a ID do host WSL ao firewall.

Obtenha o endereço IP do computador host executando o seguinte comando no WSL:

cat /etc/resolv.conf

Copie o endereço IP após o termo nameserver e use o seguinte comando para definir uma variável de ambiente para o endereço IP WSL:

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 server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip-wsl \
    --server $AZ_DATABASE_SERVER_NAME \
    --start-ip-address $AZ_WSL_IP_ADDRESS \
    --end-ip-address $AZ_WSL_IP_ADDRESS \
    --output tsv

Configurar um banco de dados MySQL

O servidor MySQL que você criou anteriormente está vazio. Use o comando a seguir para criar um banco de dados.

az mysql db create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME \
    --server-name $AZ_DATABASE_SERVER_NAME \
    --output tsv

Criar um usuário não administrador do MySQL e conceder permissão

Em seguida, crie um usuário não administrador e conceda a ele todas as permissões para o banco de dados.

Observação

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

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

export AZ_MYSQL_AD_NON_ADMIN_USERID=$CURRENT_USER_OBJECTID

cat << EOF > create_ad_user.sql
SET aad_auth_validate_oids_in_tenant = OFF;

CREATE AADUSER '$AZ_MYSQL_AD_NON_ADMIN_USERNAME' IDENTIFIED BY '$AZ_MYSQL_AD_NON_ADMIN_USERID';

GRANT ALL PRIVILEGES ON $AZ_DATABASE_NAME.* TO '$AZ_MYSQL_AD_NON_ADMIN_USERNAME'@'%';

FLUSH privileges;

EOF

Em seguida, use o seguinte comando para executar o script SQL, a fim de criar o usuário não administrador do Microsoft Entra:

mysql -h $AZ_DATABASE_SERVER_NAME.mysql.database.azure.com --user $CURRENT_USERNAME@$AZ_DATABASE_SERVER_NAME --enable-cleartext-plugin --password=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken) < create_ad_user.sql

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

rm create_ad_user.sql

Criar um projeto Java

Usando seu IDE favorito, crie um projeto Java usando Java 8 ou superior. Crie um arquivo pom.xml em seu diretório raiz e adicione o seguinte conteúdo:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>

    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-identity-extensions</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
</project>

Esse arquivo é um arquivo Apache Maven que configura seu projeto para usar o Java 8 e um driver MySQL recente para Java.

Preparar um arquivo de configuração para se conectar ao Banco de Dados do Azure para MySQL

Execute o seguinte script no diretório raiz do projeto para criar um arquivo src/main/resources/database.properties e adicionar detalhes de configuração:

mkdir -p src/main/resources && touch src/main/resources/database.properties

cat << EOF > src/main/resources/database.properties
url=jdbc:mysql://${AZ_DATABASE_SERVER_NAME}.mysql.database.azure.com:3306/${AZ_DATABASE_NAME}?sslMode=REQUIRED&serverTimezone=UTC&defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin
user=${AZ_MYSQL_AD_NON_ADMIN_USERNAME}@${AZ_DATABASE_SERVER_NAME}
EOF

Observação

Se você estiver usando a classe MysqlConnectionPoolDataSource como fonte de dados em seu aplicativo, remova "defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin" da URL.

mkdir -p src/main/resources && touch src/main/resources/database.properties

cat << EOF > src/main/resources/database.properties
url=jdbc:mysql://${AZ_DATABASE_SERVER_NAME}.mysql.database.azure.com:3306/${AZ_DATABASE_NAME}?sslMode=REQUIRED&serverTimezone=UTC&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin
user=${AZ_MYSQL_AD_NON_ADMIN_USERNAME}@${AZ_DATABASE_SERVER_NAME}
EOF

Observação

A propriedade de configuração url foi acrescentada a ?serverTimezone=UTC para instruir o driver JDBC a usar o formato de data UTC (Tempo Universal Coordenado) ao conectar-se ao banco de dados. Caso contrário, seu servidor Java não usaria o mesmo formato de data que o banco de dados, o que resultaria em um erro.

Criar um arquivo SQL para gerar o esquema de banco de dados

Em seguida, você usará um arquivo src/main/resources/schema.sql para criar um esquema de banco de dados. Crie esse arquivo e adicione os seguintes conteúdos:

touch src/main/resources/schema.sql

cat << EOF > src/main/resources/schema.sql
DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id SERIAL PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BOOLEAN);
EOF

Codificar o aplicativo

Conectar-se ao banco de dados

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

Crie um arquivo src/main/java/DemoApplication.java e adicione o seguinte conteúdo:

package com.example.demo;

import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;

import java.sql.*;
import java.util.*;
import java.util.logging.Logger;

public class DemoApplication {

    private static final Logger log;

    static {
        System.setProperty("java.util.logging.SimpleFormatter.format", "[%4$-7s] %5$s %n");
        log =Logger.getLogger(DemoApplication.class.getName());
    }

    public static void main(String[] args) throws Exception {
        log.info("Loading application properties");
        Properties properties = new Properties();
        properties.load(DemoApplication.class.getClassLoader().getResourceAsStream("database.properties"));

        log.info("Connecting to the database");
        Connection connection = DriverManager.getConnection(properties.getProperty("url"), properties);
        log.info("Database connection test: " + connection.getCatalog());

        log.info("Create database schema");
        Scanner scanner = new Scanner(DemoApplication.class.getClassLoader().getResourceAsStream("schema.sql"));
        Statement statement = connection.createStatement();
        while (scanner.hasNextLine()) {
            statement.execute(scanner.nextLine());
        }

        /* Prepare to store and retrieve data from the MySQL server.
        Todo todo = new Todo(1L, "configuration", "congratulations, you have set up JDBC correctly!", true);
        insertData(todo, connection);
        todo = readData(connection);
        todo.setDetails("congratulations, you have updated data!");
        updateData(todo, connection);
        deleteData(todo, connection);
        */

        log.info("Closing database connection");
        connection.close();
        AbandonedConnectionCleanupThread.uncheckedShutdown();
    }
}

Esse código Java usará os arquivos database.properties e schema.sql criados anteriormente. Depois de se conectar ao servidor MySQL, você pode criar um esquema para armazenar seus dados.

Neste arquivo, você pode ver que comentamos os métodos para inserir, ler, atualizar e excluir dados. Você implementará esses métodos no restante deste artigo e poderá remover as marcas de comentário uma após a outra.

Observação

As credenciais de banco de dados são armazenadas nas propriedades user e password no arquivo database.properties. Essas credenciais são usadas durante a execução de DriverManager.getConnection(properties.getProperty("url"), properties);, pois o arquivo de propriedades é passado como um argumento.

Observação

A linha AbandonedConnectionCleanupThread.uncheckedShutdown(); no final é um comando do driver MySQL para destruir um thread interno ao desligar o aplicativo. Você pode ignorar esta linha com segurança.

Agora, você pode executar esta classe principal com a sua ferramenta favorita:

  • Usando o IDE, você deve clicar com o botão direito do mouse na classe DemoApplication e executá-la.
  • Usando o Maven, você pode executar o aplicativo com o seguinte comando: mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication".

O aplicativo deve se conectar ao Banco de Dados do Azure para MySQL, criar um esquema de banco de dados e fechar a conexão. Você deverá ver uma saída semelhante ao seguinte exemplo nos logs do console:

[INFO   ] Loading application properties
[INFO   ] Connecting to the database
[INFO   ] Database connection test: demo
[INFO   ] Create database schema
[INFO   ] Closing database connection

Criar uma classe de domínio

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

package com.example.demo;

public class Todo {

    private Long id;
    private String description;
    private String details;
    private boolean done;

    public Todo() {
    }

    public Todo(Long id, String description, String details, boolean done) {
        this.id = id;
        this.description = description;
        this.details = details;
        this.done = 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;
    }

    @Override
    public String toString() {
        return "Todo{" +
                "id=" + id +
                ", description='" + description + '\'' +
                ", details='" + details + '\'' +
                ", done=" + done +
                '}';
    }
}

Essa classe é um modelo de domínio mapeado na tabela todo que você criou ao executar o script schema.sql.

Inserir dados no Banco de Dados do Azure para MySQL

No arquivo src/main/java/DemoApplication.java, após o método principal, adicione o seguinte método para inserir dados no banco de dados:

private static void insertData(Todo todo, Connection connection) throws SQLException {
    log.info("Insert data");
    PreparedStatement insertStatement = connection
            .prepareStatement("INSERT INTO todo (id, description, details, done) VALUES (?, ?, ?, ?);");

    insertStatement.setLong(1, todo.getId());
    insertStatement.setString(2, todo.getDescription());
    insertStatement.setString(3, todo.getDetails());
    insertStatement.setBoolean(4, todo.isDone());
    insertStatement.executeUpdate();
}

Agora você pode remover a marca de comentário das seguintes duas linhas no método main:

Todo todo = new Todo(1L, "configuration", "congratulations, you have set up JDBC correctly!", true);
insertData(todo, connection);

A execução da classe principal deve produzir a seguinte saída:

[INFO   ] Loading application properties
[INFO   ] Connecting to the database
[INFO   ] Database connection test: demo
[INFO   ] Create database schema
[INFO   ] Insert data
[INFO   ] Closing database connection

Como ler dados do Banco de Dados do Azure para MySQL

Em seguida, leia os dados inseridos anteriormente para validar se o código funciona corretamente.

No arquivo src/main/java/DemoApplication.java, após o método insertData, adicione o seguinte método para ler dados do banco de dados:

private static Todo readData(Connection connection) throws SQLException {
    log.info("Read data");
    PreparedStatement readStatement = connection.prepareStatement("SELECT * FROM todo;");
    ResultSet resultSet = readStatement.executeQuery();
    if (!resultSet.next()) {
        log.info("There is no data in the database!");
        return null;
    }
    Todo todo = new Todo();
    todo.setId(resultSet.getLong("id"));
    todo.setDescription(resultSet.getString("description"));
    todo.setDetails(resultSet.getString("details"));
    todo.setDone(resultSet.getBoolean("done"));
    log.info("Data read from the database: " + todo.toString());
    return todo;
}

Agora você pode remover a marca de comentário da seguinte linha no método main:

todo = readData(connection);

A execução da classe principal deve produzir a seguinte saída:

[INFO   ] Loading application properties
[INFO   ] Connecting to the database
[INFO   ] Database connection test: demo
[INFO   ] Create database schema
[INFO   ] Insert data
[INFO   ] Read data
[INFO   ] Data read from the database: Todo{id=1, description='configuration', details='congratulations, you have set up JDBC correctly!', done=true}
[INFO   ] Closing database connection

Como atualizar dados no Banco de Dados do Azure para MySQL

Então atualize os dados inseridos anteriormente.

Ainda no arquivo src/main/java/DemoApplication.java, após o método readData, adicione o seguinte método para atualizar os dados no banco de dados:

private static void updateData(Todo todo, Connection connection) throws SQLException {
    log.info("Update data");
    PreparedStatement updateStatement = connection
            .prepareStatement("UPDATE todo SET description = ?, details = ?, done = ? WHERE id = ?;");

    updateStatement.setString(1, todo.getDescription());
    updateStatement.setString(2, todo.getDetails());
    updateStatement.setBoolean(3, todo.isDone());
    updateStatement.setLong(4, todo.getId());
    updateStatement.executeUpdate();
    readData(connection);
}

Agora você pode remover a marca de comentário das seguintes duas linhas no método main:

todo.setDetails("congratulations, you have updated data!");
updateData(todo, connection);

A execução da classe principal deve produzir a seguinte saída:

[INFO   ] Loading application properties
[INFO   ] Connecting to the database
[INFO   ] Database connection test: demo
[INFO   ] Create database schema
[INFO   ] Insert data
[INFO   ] Read data
[INFO   ] Data read from the database: Todo{id=1, description='configuration', details='congratulations, you have set up JDBC correctly!', done=true}
[INFO   ] Update data
[INFO   ] Read data
[INFO   ] Data read from the database: Todo{id=1, description='configuration', details='congratulations, you have updated data!', done=true}
[INFO   ] Closing database connection

Como excluir dados no Banco de Dados do Azure para MySQL

Por fim, atualize os dados inseridos anteriormente.

Ainda no arquivo src/main/java/DemoApplication.java, após o método updateData, adicione o seguinte método para excluir os dados no banco de dados:

private static void deleteData(Todo todo, Connection connection) throws SQLException {
    log.info("Delete data");
    PreparedStatement deleteStatement = connection.prepareStatement("DELETE FROM todo WHERE id = ?;");
    deleteStatement.setLong(1, todo.getId());
    deleteStatement.executeUpdate();
    readData(connection);
}

Agora você pode remover a marca de comentário da seguinte linha no método main:

deleteData(todo, connection);

A execução da classe principal deve produzir a seguinte saída:

[INFO   ] Loading application properties
[INFO   ] Connecting to the database
[INFO   ] Database connection test: demo
[INFO   ] Create database schema
[INFO   ] Insert data
[INFO   ] Read data
[INFO   ] Data read from the database: Todo{id=1, description='configuration', details='congratulations, you have set up JDBC correctly!', done=true}
[INFO   ] Update data
[INFO   ] Read data
[INFO   ] Data read from the database: Todo{id=1, description='configuration', details='congratulations, you have updated data!', done=true}
[INFO   ] Delete data
[INFO   ] Read data
[INFO   ] There is no data in the database!
[INFO   ] Closing database connection

Limpar os recursos

Parabéns! Você criou um aplicativo Java que usa o JDBC para armazenar e recuperar dados do Banco de Dados do Azure para MySQL.

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

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

Próximas etapas