Краткое руководство. Использование Java и JDBC с База данных Azure для MySQL

ОБЛАСТЬ ПРИМЕНЕНИЯ: База данных Azure для MySQL — отдельный сервер

Важно!

База данных Azure для MySQL один сервер находится на пути выхода на пенсию. Настоятельно рекомендуется выполнить обновление до База данных Azure для MySQL гибкого сервера. Дополнительные сведения о миграции на гибкий сервер База данных Azure для MySQL см. в статье "Что происходит с одним сервером База данных Azure для MySQL?"

В этой статье показано создание примера приложения, использующего Java и JDBC для хранения и получения сведений в База данных Azure для MySQL.

JDBC — это стандартный API Java для подключения к классическим реляционным базам данных.

В этой статье мы рассмотрим два метода проверки подлинности: проверку подлинности Microsoft Entra и проверку подлинности MySQL. На вкладке "Без пароля" показана проверка подлинности Microsoft Entra, а на вкладке "Пароль " отображается проверка подлинности MySQL.

Проверка подлинности Microsoft Entra — это механизм подключения к База данных Azure для MySQL с помощью удостоверений, определенных в идентификаторе Microsoft Entra. С помощью проверки подлинности Microsoft Entra можно управлять удостоверениями пользователей базы данных и другими службы Майкрософт в центральном расположении, что упрощает управление разрешениями.

Проверка подлинности MySQL использует учетные записи, хранящиеся в MySQL. Если вы решили использовать пароли в качестве учетных данных для учетных записей, эти учетные данные будут храниться в user таблице. Так как эти пароли хранятся в MySQL, вам потребуется самостоятельно управлять сменой паролей.

Необходимые компоненты

  • Учетная запись Azure. Если у вас ее нет, получите бесплатную пробную версию.
  • Azure Cloud Shell или Azure CLI Мы рекомендуем использовать Azure Cloud Shell, так вы автоматически войдете в систему и получите доступ ко всем необходимым средствам.
  • Поддерживаемый пакет средств разработки Java (JDK) версии 8 (включена в Azure Cloud Shell).
  • Средство сборки Apache Maven.
  • Клиент командной строки MySQL. Вы можете подключиться к серверу с помощью средства командной строки mysql.exe с помощью Azure Cloud Shell. Кроме того, можно использовать командную mysql строку в локальной среде.

Подготовка среды выполнения

Сначала настройте некоторые переменные среды. В Azure Cloud Shell выполните следующие команды:

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)

Замените заполнители следующими значениями, которые используются в этой статье:

  • <YOUR_DATABASE_SERVER_NAME>: имя сервера MySQL, который должен быть уникальным в Azure.
  • <YOUR_AZURE_REGION>: регион Azure, который вы будете использовать. Вы можете использовать eastus по умолчанию, но мы рекомендуем настроить регион, расположенный близко к месту проживания. Полный список доступных регионов можно просмотреть, введя az account list-locations.
  • <YOUR_LOCAL_IP_ADDRESS>: IP-адрес локального компьютера, с которого вы запустите приложение. Один из удобных способов найти его — открыть whatismyip.akamai.com.

Чтобы создать группу ресурсов, выполните следующую команду:

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

Создание экземпляра Базы данных Azure для MySQL

Создание сервера MySQL и настройка пользователя администратора

Первое, что вы создадите, — это управляемый сервер MySQL.

Примечание.

Дополнительные сведения о создании серверов MySQL см. в кратком руководстве. Создание сервера База данных Azure для MySQL с помощью портал Azure.

Если вы используете Azure CLI, выполните следующую команду, чтобы убедиться, что у вас достаточно разрешений:

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

Затем выполните следующую команду, чтобы создать сервер:

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

Затем выполните следующую команду, чтобы задать пользователя администратора 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

Важно!

При настройке администратора в Базу данных Azure для сервера MySQL добавляется новый пользователь со всеми разрешениями администратора. На сервере MySQL можно создать только одного администратора Microsoft Entra. Выбор другого пользователя перезаписывает существующего администратора Microsoft Entra, настроенного для сервера.

Эта команда создает небольшой сервер MySQL и задает администратору Active Directory имя пользователя, выполнившего вход.

Настройка правила брандмауэра для сервера MySQL

По умолчанию службы "Базы данных Azure для MySQL" защищены. Эти экземпляры имеют брандмауэр, который не разрешает входящее подключение. Чтобы вы могли использовать нашу базу данных, добавьте правило брандмауэра, которое разрешит локальному IP-адресу обращаться к серверу базы данных.

Так как вы настроили локальный IP-адрес ранее, вы можете открыть брандмауэр сервера, выполнив следующую команду:

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

Если вы подключаетесь к серверу MySQL из подсистема Windows для Linux (WSL) на компьютере Windows, необходимо добавить идентификатор узла WSL в брандмауэр.

Получите IP-адрес хост-компьютера, выполнив следующую команду в WSL:

cat /etc/resolv.conf

Скопируйте IP-адрес после термина nameserver, а затем используйте следующую команду, чтобы задать переменную среды для IP-адреса WSL:

AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

Затем используйте следующую команду, чтобы открыть брандмауэр сервера в приложении на основе 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

Настройка базы данных MySQL

Созданный вами ранее сервер MySQL пуст. Чтобы создать новую базу данных, используйте следующую команду.

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

Создание пользователя, отличного от администратора MySQL, и предоставление разрешений

Затем создайте пользователя без администратора и предоставьте всем разрешения для базы данных.

Примечание.

Дополнительные сведения о создании пользователей MySQL см. в статье "Создание пользователей" в База данных Azure для MySQL.

Создайте скрипт SQL с именем create_ad_user.sql для создания пользователя без администратора. Добавьте следующее содержимое и сохраните его локально:

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

Затем выполните следующую команду, чтобы запустить скрипт SQL для создания пользователя, отличного от администратора 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

Теперь используйте следующую команду, чтобы удалить временный файл скрипта SQL:

rm create_ad_user.sql

Создание нового проекта Java

Используя любимую интегрированную среду разработки, создайте проект Java с помощью Java 8 или более поздней версии. Создайте файл 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.30</version>
        </dependency>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-identity-extensions</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
</project>

Этот файл — это файл Apache Maven , который настраивает проект для использования Java 8 и недавнего драйвера MySQL для Java.

Подготовка файла конфигурации для подключения к Базе данных Azure для MySQL

Выполните следующий скрипт в корневом каталоге проекта, чтобы создать файл src/main/resources/database.properties и добавить сведения о конфигурации:

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

Примечание.

Если вы используете класс Mysql Подключение ionPoolDataSource в качестве источника данных в приложении, удалите значение defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin» в 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

Примечание.

Свойство url конфигурации добавлено ?serverTimezone=UTC , чтобы сообщить драйверу JDBC использовать формат даты UTC (или универсальное время координированного времени) при подключении к базе данных. В противном случае сервер Java не будет использовать тот же формат даты, что и база данных, что приведет к ошибке.

Создание файла SQL для генерации схемы базы данных

Затем вы будете использовать src/main/resources/schema.sql-файл для создания схемы базы данных. Создайте этот файл, а затем добавьте следующее содержимое:

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

Добавление кода приложения

Подключение к базе данных

Затем добавьте код Java, который будет использовать JDBC для сохранения и извлечения данных на сервере MySQL.

Создайте файл src/main/java/DemoApplication.java и добавьте следующее содержимое:

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

Этот код Java будет использовать database.properties и файлы schema.sql , созданные ранее. После подключения к серверу MySQL можно создать схему для хранения данных.

В этом файле можно увидеть, что мы закомментировали методы вставки, чтения, обновления и удаления данных. Эти методы будут реализованы в остальной части этой статьи, и вы сможете раскомментировать их друг за другом.

Примечание.

Учетные данные базы данных хранятся в свойствах пользователя и пароля файла database.properties. Эти учетные данные используются при выполнении DriverManager.getConnection(properties.getProperty("url"), properties);, так как файл свойств передается в качестве аргумента.

Примечание.

Строка AbandonedConnectionCleanupThread.uncheckedShutdown(); в конце — это команда драйвера MySQL, чтобы уничтожить внутренний поток при завершении работы приложения. Эту строку можно безопасно игнорировать.

Теперь вы можете выполнить класс main в любом удобном инструменте.

  • В любой среде IDE щелкните правой кнопкой мыши класс DemoApplication и выполните его.
  • С помощью Maven можно запустить приложение с помощью следующей команды: mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication"

Приложение должно подключиться к База данных Azure для MySQL, создать схему базы данных и закрыть подключение. Вы должны увидеть выходные данные, аналогичные следующему примеру, в журналах консоли:

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

Создание доменного класса

Создайте новый класс Java Todo рядом с классом DemoApplication и добавьте следующий код:

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

Этот класс является доменной моделью, сопоставленной с таблицей todo, которую вы создали при выполнении скрипта schema.sql.

Вставка данных в Базу данных Azure для MySQL

В файле src/main/java/demoapplication.java добавьте после метода main следующий метод, который вставляет данные в базу данных.

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

Теперь можно раскомментировать две следующие строки в методе main.

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

Теперь при запуске класса main вы увидите следующие выходные данные.

[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

Считывание данных из Базы данных Azure для MySQL

Затем прочтите ранее вставленные данные, чтобы убедиться, что код работает правильно.

В файле src/main/java/demoapplication.java добавьте после метода insertData следующий метод, который считывает данные из базы данных.

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

Теперь можно раскомментировать следующую строку в методе main.

todo = readData(connection);

Теперь при запуске класса main вы увидите следующие выходные данные.

[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

Обновление данных в Базе данных Azure для MySQL

Затем обновите ранее вставленные данные.

В том же файле src/main/java/demoapplication.java добавьте после метода readData следующий метод, который обновляет данные в базе данных.

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

Теперь можно раскомментировать две следующие строки в методе main.

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

Теперь при запуске класса main вы увидите следующие выходные данные.

[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

Удаление данных в Базе данных Azure для MySQL

Наконец, удалите ранее вставленные данные.

В том же файле src/main/java/demoapplication.java добавьте после метода updateData следующий метод, который удаляет данные из базы данных.

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

Теперь можно раскомментировать следующую строку в методе main.

deleteData(todo, connection);

Теперь при запуске класса main вы увидите следующие выходные данные.

[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

Очистка ресурсов

Поздравляем! Вы создали приложение Java, которое использует JDBC для сохранения данных в Базе данных Azure для MySQL и их извлечения из нее.

Чтобы очистить все ресурсы, используемые во время этого краткого руководства, удалите группу ресурсов с помощью следующей команды:

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

Следующие шаги