Quickstart: Java en JDBC gebruiken met Azure Database for MySQL

VAN TOEPASSING OP: Azure Database for MySQL - enkele server

Belangrijk

Azure Database for MySQL enkele server bevindt zich op het buitengebruikstellingspad. We raden u ten zeerste aan een upgrade uit te voeren naar een flexibele Azure Database for MySQL-server. Zie Wat gebeurt er met Azure Database for MySQL Enkele server voor meer informatie over migreren naar Azure Database for MySQL Flexibele server ?

In dit artikel wordt gedemonstreerd hoe u een voorbeeldtoepassing maakt die gebruikmaakt van Java en JDBC om informatie op te slaan en op te halen in Azure Database for MySQL.

JDBC is de standaard Java-API voor het maken van verbinding met traditionele relationele databases.

In dit artikel bevatten we twee verificatiemethoden: Microsoft Entra-verificatie en MySQL-verificatie. Op het tabblad Wachtwoordloos ziet u de Microsoft Entra-verificatie en op het tabblad Wachtwoord wordt de MySQL-verificatie weergegeven.

Microsoft Entra-verificatie is een mechanisme voor het maken van verbinding met Azure Database for MySQL met behulp van identiteiten die zijn gedefinieerd in Microsoft Entra-id. Met Microsoft Entra-verificatie kunt u databasegebruikersidentiteiten en andere Microsoft-services op een centrale locatie beheren, waardoor het beheer van machtigingen wordt vereenvoudigd.

MySQL-verificatie maakt gebruik van accounts die zijn opgeslagen in MySQL. Als u ervoor kiest om wachtwoorden als referenties voor de accounts te gebruiken, worden deze referenties opgeslagen in de user tabel. Omdat deze wachtwoorden zijn opgeslagen in MySQL, moet u de rotatie van de wachtwoorden zelf beheren.

Vereisten

De werkomgeving voorbereiden

Stel eerst enkele omgevingsvariabelen in. Voer in Azure Cloud Shell de volgende opdrachten uit:

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)

Vervang de tijdelijke aanduidingen door de volgende waarden, die overal in dit artikel worden gebruikt:

  • <YOUR_DATABASE_SERVER_NAME>: De naam van uw MySQL-server, die uniek moet zijn in Azure.
  • <YOUR_AZURE_REGION>: de Azure-regio die u gaat gebruiken. U kunt standaard eastus gebruiken, maar we raden u aan om een regio dichtbij uw locatie te configureren. U kunt de volledige lijst met beschikbare regio's bekijken door deze in te voeren az account list-locations.
  • <YOUR_LOCAL_IP_ADDRESS>: Het IP-adres van uw lokale computer, van waaruit u uw toepassing uitvoert. Een handige manier om het te vinden is door whatismyip.akamai.com te openen.

Maak vervolgens een resourcegroep met de volgende opdracht:

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

Een Azure Database for MySQL-instantie maken

Een MySQL-server maken en een gebruiker met beheerdersrechten instellen

Het eerste wat u maakt, is een beheerde MySQL-server.

Notitie

Meer gedetailleerde informatie over het maken van MySQL-servers vindt u in quickstart: Een Azure Database for MySQL-server maken met behulp van Azure Portal.

Als u Azure CLI gebruikt, voert u de volgende opdracht uit om te controleren of deze voldoende machtigingen heeft:

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

Voer vervolgens de volgende opdracht uit om de server te maken:

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

Voer vervolgens de volgende opdracht uit om de Microsoft Entra-beheerdergebruiker in te stellen:

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

Belangrijk

Wanneer u de beheerder instelt, wordt er een nieuwe gebruiker toegevoegd aan de Azure Database for MySQL-server met volledige beheerdersmachtigingen. U kunt slechts één Microsoft Entra-beheerder per MySQL-server maken. De selectie van een andere gebruiker overschrijft de bestaande Microsoft Entra-beheerder die is geconfigureerd voor de server.

Met deze opdracht maakt u een kleine MySQL-server en stelt u de Active Directory-beheerder in op de aangemelde gebruiker.

Een firewallregel voor uw MySQL-server configureren

Azure Databases for MySQL-exemplaren worden standaard beveiligd. Deze exemplaren hebben een firewall die geen binnenkomende verbinding toestaat. Om uw database te kunnen gebruiken, moet u een firewallregel toevoegen waarmee het lokale IP-adres toegang krijgt tot de databaseserver.

Aangezien u aan het begin van dit artikel een lokaal IP-adres hebt geconfigureerd, kunt u de firewall van de server openen door de volgende opdracht uit te voeren:

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

Als u verbinding maakt met uw MySQL-server vanaf Windows-subsysteem voor Linux (WSL) op een Windows-computer, moet u de WSL-host-id toevoegen aan uw firewall.

Haal het IP-adres van uw hostcomputer op door de volgende opdracht uit te voeren in WSL:

cat /etc/resolv.conf

Kopieer het IP-adres na de term nameserveren gebruik vervolgens de volgende opdracht om een omgevingsvariabele in te stellen voor het WSL IP-adres:

AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

Gebruik vervolgens de volgende opdracht om de firewall van de server te openen naar uw WSL-app:

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

Een MySQL-database configureren

De MySQL-server die u eerder hebt gemaakt, is leeg. Gebruik de volgende opdracht om een nieuwe database te maken.

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

Een MySQL-gebruiker maken die niet-beheerder is en machtigingen verlenen

Maak vervolgens een niet-beheerder en verdeel alle machtigingen aan de database.

Notitie

Meer gedetailleerde informatie over het maken van MySQL-gebruikers vindt u in Create users in Azure Database for MySQL.

Maak een SQL-script met de naam create_ad_user.sql voor het maken van een niet-beheerdersgebruiker. Voeg de volgende inhoud toe en sla deze lokaal op:

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

Gebruik vervolgens de volgende opdracht om het SQL-script uit te voeren om de niet-beheerdersgebruiker van Microsoft Entra te maken:

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

Gebruik nu de volgende opdracht om het tijdelijke SQL-scriptbestand te verwijderen:

rm create_ad_user.sql

Een nieuw Java-project maken

Maak met uw favoriete IDE een nieuw Java-project met Java 8 of hoger. Maak een pom.xml-bestand in de hoofdmap en voeg de volgende inhoud toe:

<?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>

Dit bestand is een Apache Maven-bestand waarmee uw project wordt geconfigureerd voor het gebruik van Java 8 en een recent MySQL-stuurprogramma voor Java.

Een configuratiebestand voorbereiden om verbinding te maken met Azure Database for MySQL

Voer het volgende script uit in de hoofdmap van het project om een src/main/resources/database.properties-bestand te maken en configuratiegegevens toe te voegen:

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

Notitie

Als u Mysql Verbinding maken ionPoolDataSource-klasse gebruikt als de gegevensbron in uw toepassing, verwijdert u 'defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin' in de 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

Notitie

De configuratie-eigenschap url heeft ?serverTimezone=UTC toegevoegd om het JDBC-stuurprogramma te laten weten dat de UTC-datumnotatie (of Coordinated Universal Time) moet worden gebruikt bij het maken van verbinding met de database. Anders zou uw Java-server niet dezelfde datumnotatie gebruiken als de database, wat tot een fout zou leiden.

Een SQL-bestand maken om het databaseschema te genereren

Vervolgens gebruikt u een src/main/resources/schema.sql-bestand om een databaseschema te maken. Maak dat bestand en voeg vervolgens de volgende inhoud toe:

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

De toepassing coderen

Verbinding maken met de database

Voeg vervolgens de Java-code toe die gebruik gaat maken van JDBC om gegevens op te slaan en op te halen van uw MySQL-server.

Maak een src/main/java/DemoApplication.java-bestand en voeg de volgende inhoud toe:

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

Deze Java-code gebruikt de database.properties en de schema.sql-bestanden die u eerder hebt gemaakt. Nadat u verbinding hebt gemaakt met de MySQL-server, kunt u een schema maken om uw gegevens op te slaan.

In dit bestand ziet u dat we methoden hebben toegevoegd om gegevens in te voegen, te lezen, bij te werken en te verwijderen. U implementeert deze methoden in de rest van dit artikel en u kunt opmerkingen erna verwijderen.

Notitie

De databasereferenties worden opgeslagen in de eigenschappen van de gebruiker en het wachtwoord van het bestand database.properties. Deze referenties worden gebruikt bij het uitvoeren van DriverManager.getConnection(properties.getProperty("url"), properties);, omdat het eigenschappenbestand als argument wordt doorgegeven.

Notitie

De AbandonedConnectionCleanupThread.uncheckedShutdown(); regel aan het einde is een MySQL-stuurprogrammaopdracht om een interne thread te vernietigen bij het afsluiten van de toepassing. U kunt deze regel veilig negeren.

U kunt nu deze main-klasse uitvoeren met uw favoriete tool:

  • Klik in uw IDE met de rechtermuisknop op de klasse DemoApplication en voer deze uit.
  • Met Behulp van Maven kunt u de toepassing uitvoeren met de volgende opdracht: mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication".

De toepassing moet verbinding maken met Azure Database for MySQL, een databaseschema maken en vervolgens de verbinding sluiten. U ziet uitvoer die lijkt op het volgende voorbeeld in de consolelogboeken:

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

Een domeinklasse maken

Maak een nieuwe Java-klasse Todo, naast de klasse DemoApplication, en voeg de volgende code toe:

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

Deze klasse is een domeinmodel dat is toegewezen aan de tabel todo die u eerder hebt gemaakt tijdens het uitvoeren van het script schema.sql.

Gegevens invoegen in Azure Database for MySQL

Voeg na de methode main in het bestand src/main/java/DemoApplication.java de volgende methode toe om gegevens in te voegen in de database:

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

U kunt nu de commentaartekens verwijderen van de twee volgende regels in de methode main:

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

Als u nu de main-klasse uitvoert, zou dit de volgende uitvoer moeten opleveren:

[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

Gegevens lezen uit Azure Database for MySQL

Lees vervolgens de gegevens die eerder zijn ingevoegd om te controleren of uw code correct werkt.

Voeg in het bestand src/main/java/DemoApplication.java, na de methode insertData, de volgende methode toe om gegevens te lezen uit de database:

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

U kunt nu de commentaartekens verwijderen van de volgende regel in de methode main:

todo = readData(connection);

Als u nu de main-klasse uitvoert, zou dit de volgende uitvoer moeten opleveren:

[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

Gegevens bijwerken in Azure Database for MySQL

Werk vervolgens de gegevens bij die u eerder hebt ingevoegd.

Voeg in het bestand src/main/java/DemoApplication.java, na de methode readData, de volgende methode toe om gegevens bij te werken in de database:

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

U kunt nu de commentaartekens verwijderen van de twee volgende regels in de methode main:

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

Als u nu de main-klasse uitvoert, zou dit de volgende uitvoer moeten opleveren:

[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

Gegevens verwijderen in Azure Database for MySQL

Verwijder ten slotte de gegevens die u eerder hebt ingevoegd.

Voeg in het bestand src/main/java/DemoApplication.java, na de methode updateData, de volgende methode toe om gegevens te verwijderen uit de database:

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

U kunt nu de commentaartekens verwijderen van de volgende regel in de methode main:

deleteData(todo, connection);

Als u nu de main-klasse uitvoert, zou dit de volgende uitvoer moeten opleveren:

[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

Resources opschonen

Gefeliciteerd. U hebt een Java-app gemaakt die gebruikmaakt van JDBC om gegevens op te slaan en op te halen uit Azure Database for MySQL.

Als u alle resources wilt opschonen die tijdens deze quickstart zijn gebruikt, verwijdert u de resourcegroep. Dit kan met de volgende opdracht:

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

Volgende stappen