Использование Java и JDBC с База данных 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", чтобы бесплатно попробовать База данных 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
Внимание
После создания удостоверения, назначаемого пользователем, попросите пользователя по крайней мере роль администратора привилегированных ролей предоставить следующие разрешения для этого управляемого удостоверения, назначаемого пользователем: User.Read.All
и GroupMember.Read.All
Application.Read.ALL
. Кроме того, предоставьте управляемому удостоверению , назначенному пользователем, роль читателя каталогов . Дополнительные сведения см. в разделе "Разрешения" проверки подлинности Microsoft Entra для База данных Azure для MySQL — гибкий сервер.
Выполните следующую команду, чтобы назначить удостоверение База данных 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 с полными разрешениями администратора. Для каждого экземпляра гибкого сервера можно База данных Azure для MySQL создать только один администратор Microsoft Entra, а другой перезаписывает существующий администратор 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=$(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
Затем выполните следующую команду, чтобы запустить скрипт 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
Примечание.
Если вы используете класс MysqlConnectionPoolDataSource в качестве источника данных в приложении, удалите "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