Sdílet prostřednictvím


Použití Javy a JDBC s flexibilní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í na flexibilním serveru 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 obsahujeme 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í k flexibilnímu serveru 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, jsou tyto přihlašovací údaje uloženy v user tabulce. Vzhledem k tomu, že tato hesla jsou uložená v MySQL, musíte spravovat rotaci hesel sami.

Požadavky

Příprava pracovního prostředí

Nejprve pomocí následujícího příkazu nastavte některé proměnné prostředí.

export AZ_RESOURCE_GROUP=database-workshop
export AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
export AZ_LOCATION=<YOUR_AZURE_REGION>
export AZ_MYSQL_AD_NON_ADMIN_USERNAME=demo-non-admin
export AZ_USER_IDENTITY_NAME=<YOUR_USER_ASSIGNED_MANAGED_IDENTITY_NAME>
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_NAME>: Název instance flexibilního serveru Azure Database for MySQL, který by měl být jedinečný v rámci Azure.
  • <YOUR_AZURE_REGION>: Oblast Azure, kterou používáte. 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_USER_ASSIGNED_MANAGED_IDENTITY_NAME>: Název serveru spravované identity přiřazeného uživatelem, který by měl být jedinečný v rámci Azure.

Následně 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í instance flexibilního serveru Azure Database for MySQL a nastavení uživatele s rolí správce

První věc, kterou vytvoříte, je spravovaná instance flexibilního serveru Azure Database for MySQL.

Poznámka:

Podrobnější informace o vytváření serverů MySQL najdete v rychlém startu: Vytvoření instance Služby 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

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

az mysql flexible-server create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME \
    --location $AZ_LOCATION \
    --yes \
    --output tsv

Spuštěním následujícího příkazu vytvořte identitu přiřazenou uživatelem pro přiřazení:

az identity create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_USER_IDENTITY_NAME

Důležité

Po vytvoření identity přiřazené uživatelem požádejte uživatele s alespoň rolí Správce privilegovaných rolí, aby pro tuto spravovanou identitu přiřazenou uživatelem udělila následující oprávnění: User.Read.All, a .GroupMember.Read.AllApplication.Read.ALL Případně udělte spravované identitě přiřazené uživatelem roli Čtenáři adresáře. Další informace najdete v části Oprávnění ověřování Microsoft Entra pro flexibilní server Azure Database for MySQL.

Spuštěním následujícího příkazu přiřaďte identitu flexibilnímu serveru Azure Database for MySQL pro vytvoření správce Microsoft Entra:

az mysql flexible-server identity assign \
    --resource-group $AZ_RESOURCE_GROUP \
    --server-name $AZ_DATABASE_NAME \
    --identity $AZ_USER_IDENTITY_NAME

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

az mysql flexible-server ad-admin create \
    --resource-group $AZ_RESOURCE_GROUP \
    --server-name $AZ_DATABASE_NAME \
    --display-name $CURRENT_USERNAME \
    --object-id $CURRENT_USER_OBJECTID \
    --identity $AZ_USER_IDENTITY_NAME

Důležité

Při nastavování správce se do instance flexibilního serveru Azure Database for MySQL přidá nový uživatel s úplnými oprávněními správce. K dispozici je pouze jeden správce Microsoft Entra na instanci serveru. Výběr jiného přepíše existujícího správce Microsoft Entra.

Tento příkaz vytvoří malou instanci flexibilního serveru Azure Database for MySQL a nastaví správce služby Active Directory na přihlášeného uživatele.

Instance flexibilního serveru Azure Database for MySQL, kterou jste vytvořili, má prázdnou databázi s názvem flexibleserverdb.

Máte nějaké problémy? Dejte nám vědět.

Konfigurace pravidla brány firewall pro instanci flexibilního serveru Azure Database for MySQL

Výchozí nastavení zabezpečené brány firewall je nakonfigurováno tak, aby odepřelo jakékoli příchozí připojení.

Tento krok můžete přeskočit, pokud používáte Bash, protože flexible-server create příkaz už detekoval vaši místní IP adresu a nastavil ji na serveru MySQL.

Pokud se připojujete k instanci serveru ze subsystému Windows pro Linux (WSL) na počítači s Windows, musíte do brány firewall přidat ID hostitele WSL. Získejte IP adresu hostitelského počítače spuštěním tohoto příkazu ve WSL:

sudo cat /etc/resolv.conf

Zkopírujte IP adresu za termínem nameservera pak pomocí tohoto 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 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

Konfigurace databáze MySQL

Pomocí tohoto příkazu vytvořte novou databázi:demo

az mysql flexible-server db create \
    --resource-group $AZ_RESOURCE_GROUP \
    --database-name demo \
    --server-name $AZ_DATABASE_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í k demo databázi.

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=$(az ad signed-in-user show --query id --output tsv)

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 demo.* 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_NAME.mysql.database.azure.com --user $CURRENT_USERNAME --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 a do kořenového adresáře přidejte soubor pom.xml :

<?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.33</version>
        </dependency>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-identity-extensions</artifactId>
            <version>1.2.0</version>
        </dependency>
    </dependencies>
</project>

Tento soubor je soubor Apache Maven , který konfiguruje váš projekt tak, aby používal:

  • Java 8
  • Nedávný ovladač MySQL pro Javu

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

V kořenovém adresáři projektu vytvořte soubor src/main/resources/database.properties pomocí těchto skriptů:

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

cat << EOF > src/main/resources/database.properties
url=jdbc:mysql://${AZ_DATABASE_NAME}.mysql.database.azure.com:3306/demo?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}
EOF

Poznámka:

Pokud ve své aplikaci používáte třídu MysqlConnectionPoolDataSource jako zdroj dat, 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_NAME}.mysql.database.azure.com:3306/demo?sslMode=REQUIRED&serverTimezone=UTC&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin
user=${AZ_MYSQL_AD_NON_ADMIN_USERNAME}
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). Jinak by váš server Java nepoužil stejný formát data jako databáze, což by vedlo k chybě.

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

Vytvořte schéma databáze pomocí souboru 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
);

Vytvoření kódu aplikace

Připojte se k databázi.

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

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

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

Máte nějaké problémy? Dejte nám vědět.

Tento kód Java používá database.properties a schema.sql soubory, které jste vytvořili dříve pro připojení k databázi, a vytvoří schéma.

V tomto souboru vidíte, že jsme okomentovali metody pro vložení, čtení, aktualizaci a odstranění dat: tyto metody zakódujete ve zbývající části tohoto článku a jeden po druhém odkomentujete.

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 specifický pro ovladač MySQL, který při vypínání aplikace zničí interní vlákno. Můžete ho 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 spuštěním příkazu: mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication".

Aplikace by se měla připojit k instanci flexibilního serveru Azure Database for MySQL, vytvořit schéma databáze a pak připojení zavřít, jak byste měli vidět 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

Máte nějaké problémy? Dejte nám vědět.

Aktualizace dat na flexibilním serveru 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 na flexibilním serveru 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ů

Blahopřejeme! Vytvořili jste aplikaci v Javě, která používá JDBC k ukládání a načítání dat z flexibilního serveru Azure Database for MySQL.

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ší krok