Rychlý start: Použití Javy a JDBC se službou Azure Database for MySQL

PLATÍ PRO: Jednoúčelový server Azure Database for MySQL

Důležité

Jednoúčelový server Azure Database for MySQL je na cestě vyřazení. Důrazně doporučujeme upgradovat na flexibilní server Azure Database for MySQL. Další informace o migraci na flexibilní server Azure Database for MySQL najdete v tématu Co se děje s jednoúčelovým serverem Azure Database for MySQL?

Tento článek ukazuje vytvoření ukázkové aplikace, která k ukládání a načítání informací ve službě Azure Database for MySQL používá Javu a JDBC.

JDBC je standardní rozhraní Java API pro připojení k tradičním relačním databázím.

V tomto článku budeme zahrnovat dvě metody ověřování: ověřování Microsoft Entra a ověřování MySQL. Karta Bez hesla zobrazuje ověřování Microsoft Entra a karta Heslo zobrazuje ověřování MySQL.

Ověřování Microsoft Entra je mechanismus pro připojení ke službě Azure Database for MySQL pomocí identit definovaných v MICROSOFT Entra ID. Pomocí ověřování Microsoft Entra můžete spravovat identity uživatelů databáze a další služby Microsoft v centrálním umístění, což zjednodušuje správu oprávnění.

Ověřování MySQL používá účty uložené v MySQL. Pokud se rozhodnete používat hesla jako přihlašovací údaje pro účty, budou tyto přihlašovací údaje uloženy v user tabulce. Vzhledem k tomu, že tato hesla jsou uložená v MySQL, budete muset spravovat rotaci hesel sami.

Požadavky

Příprava pracovního prostředí

Nejprve nastavte některé proměnné prostředí. V Azure Cloud Shellu spusťte následující příkazy:

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)

Zástupné symboly nahraďte následujícími hodnotami, které se používají v tomto článku:

  • <YOUR_DATABASE_SERVER_NAME>: Název vašeho serveru MySQL, který by měl být jedinečný v rámci Azure.
  • <YOUR_AZURE_REGION>: Oblast Azure, kterou použijete. Standardně můžete použít eastus, ale doporučujeme nakonfigurovat oblast blíže k místu, kde se nacházíte. Úplný seznam dostupných oblastí můžete zobrazit zadáním az account list-locations.
  • <YOUR_LOCAL_IP_ADDRESS>: IP adresa místního počítače, ze které spustíte aplikaci. Jedním z pohodlných způsobů, jak ji najít, je otevřít whatismyip.akamai.com.

Dále pomocí následujícího příkazu vytvořte skupinu prostředků:

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

Vytvoření instance Azure Database for MySQL

Vytvoření serveru MySQL a nastavení uživatele správce

První věc, kterou vytvoříte, je spravovaný server MySQL.

Poznámka:

Podrobnější informace o vytváření serverů MySQL najdete v rychlém startu: Vytvoření serveru Azure Database for MySQL pomocí webu Azure Portal.

Pokud používáte Azure CLI, spusťte následující příkaz, abyste měli jistotu, že má dostatečná oprávnění:

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

Pak spuštěním následujícího příkazu vytvořte server:

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

Potom spuštěním následujícího příkazu nastavte uživatele microsoft Entra admin:

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

Důležité

Při nastavování správce se na server Azure Database for MySQL přidá nový uživatel s úplnými oprávněními správce. Na server MySQL můžete vytvořit pouze jednoho správce Microsoft Entra. Výběr jiného uživatele přepíše existujícího správce Microsoft Entra nakonfigurovaného pro server.

Tento příkaz vytvoří malý server MySQL a nastaví správce služby Active Directory na přihlášeného uživatele.

Konfigurace pravidla brány firewall pro server MySQL

Instance Azure Database for MySQL jsou ve výchozím nastavení zabezpečené. Tyto instance mají bránu firewall, která nepovoluje žádné příchozí připojení. Abyste mohli databázi používat, musíte přidat pravidlo brány firewall, které umožní přístup k databázovému serveru místní IP adresou.

Vzhledem k tomu, že jste na začátku tohoto článku nakonfigurovali místní IP adresu, můžete bránu firewall serveru otevřít spuštěním následujícího příkazu:

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

Pokud se připojujete k serveru MySQL z Subsystém Windows pro Linux (WSL) na počítači s Windows, budete muset do brány firewall přidat ID hostitele WSL.

Získejte IP adresu hostitelského počítače spuštěním následujícího příkazu ve WSL:

cat /etc/resolv.conf

Zkopírujte IP adresu za termínem nameservera pak pomocí následujícího příkazu nastavte proměnnou prostředí pro IP adresu WSL:

AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

Pak pomocí následujícího příkazu otevřete bránu firewall serveru pro vaši aplikaci založenou na 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

Konfigurace databáze MySQL

Server MySQL, který jste vytvořili dříve, je prázdný. K vytvoření nové databáze použijte následující příkaz.

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

Vytvoření uživatele bez oprávnění správce MySQL a udělení oprávnění

Dále vytvořte uživatele bez oprávnění správce a udělte mu všechna oprávnění.

Poznámka:

Podrobnější informace o vytváření uživatelů MySQL najdete v tématu Vytváření uživatelů ve službě Azure Database for MySQL.

Vytvořte skript SQL s názvem create_ad_user.sql pro vytvoření uživatele bez oprávnění správce. Přidejte následující obsah a uložte ho místně:

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

Potom pomocí následujícího příkazu spusťte skript SQL a vytvořte uživatele Microsoft Entra bez oprávnění správce:

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

Teď pomocí následujícího příkazu odeberte dočasný soubor skriptu SQL:

rm create_ad_user.sql

Vytvoření nového projektu v Javě

Pomocí svého oblíbeného integrovaného vývojového prostředí (IDE) vytvořte nový projekt Java pomocí Javy 8 nebo novější. V kořenovém adresáři vytvořte soubor pom.xml a přidejte následující obsah:

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

Tento soubor je soubor Apache Maven , který konfiguruje váš projekt tak, aby používal Java 8 a nedávný ovladač MySQL pro Javu.

Příprava konfiguračního souboru pro připojení ke službě Azure Database for MySQL

Spuštěním následujícího skriptu v kořenovém adresáři projektu vytvořte soubor src/main/resources/database.properties a přidejte podrobnosti o konfiguraci:

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

Poznámka:

Pokud jako zdroj dat ve své aplikaci používáte třídu MysqlConnectionPoolDataSource, odeberte v adrese URL "defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin".

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

Poznámka:

Vlastnost url konfigurace byla připojena ?serverTimezone=UTC , aby ovladač JDBC při připojování k databázi použil formát data UTC (nebo koordinovaný univerzální čas). V opačném případě server Java nebude používat stejný formát data jako databáze, což by vedlo k chybě.

Vytvoření souboru SQL pro vygenerování schématu databáze

Dále použijete soubor src/main/resources/schema.sql k vytvoření schématu databáze. Vytvořte tento soubor a přidejte následující obsah:

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

Vytvoření kódu aplikace

Připojte se k databázi.

Dále přidejte kód Java, který bude používat JDBC k ukládání a načítání dat ze serveru MySQL.

Vytvořte soubor src/main/java/DemoApplication.java a přidejte následující obsah:

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

Tento kód Java bude používat database.properties a schema.sql soubory, které jste vytvořili dříve. Po připojení k serveru MySQL můžete vytvořit schéma pro ukládání dat.

V tomto souboru vidíte, že jsme okomentovali metody vložení, čtení, aktualizace a odstranění dat. Tyto metody implementujete ve zbytku tohoto článku a budete je moct navzájem odkomentovat.

Poznámka:

Přihlašovací údaje databáze jsou uloženy ve vlastnostech uživatele a hesla souboru database.properties. Tyto přihlašovací údaje se používají při provádění DriverManager.getConnection(properties.getProperty("url"), properties);, protože soubor vlastností se předává jako argument.

Poznámka:

Řádek AbandonedConnectionCleanupThread.uncheckedShutdown(); na konci je příkaz ovladače MySQL, který při vypnutí aplikace zničí interní vlákno. Tento řádek můžete bezpečně ignorovat.

Teď můžete tuto hlavní třídu spustit pomocí svého oblíbeného nástroje:

  • Pomocí integrovaného vývojového prostředí (IDE) byste měli být schopni kliknout pravým tlačítkem myši na třídu DemoApplication a spustit ji.
  • Pomocí Mavenu můžete aplikaci spustit pomocí následujícího příkazu: mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication".

Aplikace by se měla připojit ke službě Azure Database for MySQL, vytvořit schéma databáze a pak připojení zavřít. Výstup by měl být podobný následujícímu příkladu v protokolech konzoly:

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

Vytvoření doménové třídy

Vytvořte novou Todo třídu Java vedle DemoApplication třídy a přidejte následující kód:

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

Tato třída je doménový model mapovaný na todo tabulku, kterou jste vytvořili při provádění skriptu schema.sql .

Vložení dat do služby Azure Database for MySQL

Do souboru src/main/java/DemoApplication.java za hlavní metodu přidejte následující metodu pro vložení dat do databáze:

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

Teď můžete zrušit komentář ke dvěma následujícím řádkům main v metodě:

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

Spuštění hlavní třídy by teď mělo vytvořit následující výstup:

[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

Čtení dat ze služby Azure Database for MySQL

Pak si přečtěte data, která jste předtím vložili, a ověřte, že váš kód funguje správně.

Do souboru src/main/java/DemoApplication.java za metodu insertData přidejte následující metodu pro čtení dat z databáze:

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

V metodě teď můžete odkomentovat následující řádek main :

todo = readData(connection);

Spuštění hlavní třídy by teď mělo vytvořit následující výstup:

[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

Aktualizace dat ve službě Azure Database for MySQL

Dále aktualizujte data, která jste předtím vložili.

Stále v souboru src/main/java/DemoApplication.java přidejte za metodu readData následující metodu pro aktualizaci dat uvnitř databáze:

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

Teď můžete zrušit komentář ke dvěma následujícím řádkům main v metodě:

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

Spuštění hlavní třídy by teď mělo vytvořit následující výstup:

[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

Odstranění dat ve službě Azure Database for MySQL

Nakonec odstraňte data, která jste předtím vložili.

Stále v souboru src/main/java/DemoApplication.java přidejte za metodu updateData následující metodu pro odstranění dat uvnitř databáze:

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

V metodě teď můžete odkomentovat následující řádek main :

deleteData(todo, connection);

Spuštění hlavní třídy by teď mělo vytvořit následující výstup:

[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

Vyčištění prostředků

Gratulujeme! Vytvořili jste aplikaci Java, která k ukládání a načítání dat ze služby Azure Database for MySQL používá JDBC.

Pokud chcete vyčistit všechny prostředky použité během tohoto rychlého startu, odstraňte skupinu prostředků pomocí následujícího příkazu:

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

Další kroky