Использование Java и JDBC с База данных 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, создайте бесплатную учетную запись Azure перед началом работы. В настоящее время с бесплатной учетной записью Azure можно попробовать База данных Azure для MySQL — гибкий сервер бесплатно в течение 12 месяцев. Дополнительные сведения см. в разделе База данных Azure для MySQL — гибкий сервер бесплатно.
  • Azure Cloud Shell или Azure CLI Мы рекомендуем использовать Azure Cloud Shell, так вы автоматически войдете в систему и получите доступ ко всем необходимым средствам.
  • Поддерживаемый пакет средств разработки Java (JDK) версии 8 (включена в Azure Cloud Shell).
  • Средство сборки Apache Maven.

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

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

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)

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

  • <YOUR_DATABASE_NAME>: имя вашего База данных Azure для MySQL гибкого экземпляра сервера, который должен быть уникальным в Azure.
  • <YOUR_AZURE_REGION>: регион Azure, который вы будете использовать. Вы можете использовать eastus по умолчанию, но мы рекомендуем настроить регион, расположенный близко к месту проживания. Полный список доступных регионов можно просмотреть, введя az account list-locations.
  • <YOUR_USER_ASSIGNED_MANAGED_IDENTITY_NAME>: имя назначаемого пользователем управляемого сервера удостоверений, которое должно быть уникальным в Azure.

Затем создайте группу ресурсов:

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

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

Создание гибкого экземпляра сервера База данных Azure для MySQL и настройка пользователя администратора

Первое, что вы создаете, — это управляемый База данных Azure для MySQL гибкий экземпляр сервера.

Примечание.

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

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

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

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

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

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

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

Внимание

После создания удостоверения, назначаемого пользователем, попросите глобального Администратор istrator или привилегированного Администратор istrator предоставить следующие разрешения для этого удостоверения: User.Read.Allи GroupMember.Read.AllApplication.Read.ALL. Дополнительные сведения см. в разделе "Разрешения" проверки подлинности Active Directory.

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

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

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

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

Внимание

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

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

Созданный экземпляр гибкого сервера База данных Azure для MySQL имеет пустую базу данныхflexibleserverdb.

Возникли проблемы? Сообщите нам об этом.

Настройка правила брандмауэра для экземпляра гибкого сервера База данных Azure для MySQL

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

Этот шаг можно пропустить, если вы используете Bash, так как flexible-server create команда уже обнаружила локальный IP-адрес и установите ее на сервере MySQL.

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

sudo cat /etc/resolv.conf

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

AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

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

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

Создайте базу данных с именем demo, выполнив следующую команду:

az mysql flexible-server db create \
    --resource-group $AZ_RESOURCE_GROUP \
    --database-name demo \
    --server-name $AZ_DATABASE_NAME \
    --output tsv

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

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

Примечание.

Дополнительные сведения о создании пользователей 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 demo.* TO '$AZ_MYSQL_AD_NON_ADMIN_USERNAME'@'%';

FLUSH privileges;

EOF

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

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

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

rm create_ad_user.sql

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

Используя любимую интегрированную среду разработки, создайте проект Java и добавьте файл 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_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

Примечание.

Если вы используете класс 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_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

Примечание.

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

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

Для создания схемы базы данных вы будете использовать файл 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);

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

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

Затем добавьте код 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());
        }

        /*
        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, созданные ранее, чтобы подключиться к гибкому экземпляру сервера База данных Azure для 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

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