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

Область применения: гибкий сервер Базы данных Azure для PostgreSQL

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

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

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

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

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

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

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

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

export AZ_RESOURCE_GROUP=database-workshop
export AZ_DATABASE_SERVER_NAME=<YOUR_DATABASE_SERVER_NAME>
export AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
export AZ_LOCATION=<YOUR_AZURE_REGION>
export AZ_POSTGRESQL_AD_NON_ADMIN_USERNAME=<YOUR_POSTGRESQL_AD_NON_ADMIN_USERNAME>
export AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>
export CURRENT_USERNAME=$(az ad signed-in-user show --query userPrincipalName -o tsv)

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

  • <YOUR_DATABASE_SERVER_NAME>: имя гибкого экземпляра База данных Azure для PostgreSQL сервера, который должен быть уникальным в Azure.
  • <YOUR_DATABASE_NAME>: имя базы данных База данных Azure для PostgreSQL гибкий экземпляр сервера, который должен быть уникальным в Azure.
  • <YOUR_AZURE_REGION>: регион Azure для использования. Вы можете использовать eastus по умолчанию, но мы рекомендуем настроить регион, расположенный близко к месту проживания. Полный список доступных регионов можно просмотреть, введя az account list-locations.
  • <YOUR_POSTGRESQL_AD_NON_ADMIN_USERNAME>: имя пользователя вашего База данных Azure для PostgreSQL гибкого экземпляра сервера. Убедитесь, что имя пользователя является допустимым пользователем в клиенте Microsoft Entra.
  • <YOUR_LOCAL_IP_ADDRESS>: IP-адрес локального компьютера, с которого будет запущено приложение Spring Boot. Один из удобных способов найти его — открыть whatismyip.akamai.com.

Важно!

Если задано <YOUR_POSTGRESQL_AD_NON_ADMIN_USERNAME>, имя пользователя уже должно существовать в клиенте Microsoft Entra или вы не сможете создать пользователя Microsoft Entra в базе данных.

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

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

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

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

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

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

Примечание.

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

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

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

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

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

Чтобы настроить администратора Microsoft Entra после создания сервера, выполните действия по управлению ролями Microsoft Entra в База данных Azure для PostgreSQL — гибкий сервер.

Важно!

При настройке администратора новый пользователь с полными правами администратора добавляется в базу данных Azure База данных Azure для PostgreSQL гибкого экземпляра сервера. Вы можете создать несколько администраторов Microsoft Entra на База данных Azure для PostgreSQL гибкий экземпляр сервера.

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

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

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

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

az postgres flexible-server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_SERVER_NAME \
    --rule-name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip \
    --start-ip-address $AZ_LOCAL_IP_ADDRESS \
    --end-ip-address $AZ_LOCAL_IP_ADDRESS \
    --output tsv

Если вы подключаетесь к База данных Azure для PostgreSQL гибкому экземпляру сервера из подсистема 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 postgres flexible-server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_SERVER_NAME \
    --rule-name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip \
    --start-ip-address $AZ_WSL_IP_ADDRESS \
    --end-ip-address $AZ_WSL_IP_ADDRESS \
    --output tsv

Настройка гибкой базы данных сервера База данных Azure для PostgreSQL

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

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

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

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

Примечание.

Дополнительные сведения об управлении База данных Azure для PostgreSQL гибкими пользователями сервера см. в статье "Управление пользователями Microsoft Entra" ( База данных Azure для PostgreSQL — гибкий сервер).

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

cat << EOF > create_ad_user.sql
select * from pgaadauth_create_principal('$AZ_POSTGRESQL_AD_NON_ADMIN_USERNAME', false, false);
EOF

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

psql "host=$AZ_DATABASE_SERVER_NAME.postgres.database.azure.com user=$CURRENT_USERNAME dbname=postgres port=5432 password=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken) sslmode=require" < 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>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.3.6</version>
      </dependency>
      <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-identity-extensions</artifactId>
        <version>1.0.0</version>
      </dependency>
    </dependencies>
</project>

Этот файл в формате Apache Maven настраивает в проекте использование следующих компонентов:

  • Java 8
  • Последний драйвер PostgreSQL для Java

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

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

cat << EOF > src/main/resources/application.properties
url=jdbc:postgresql://${AZ_DATABASE_SERVER_NAME}.postgres.database.azure.com:5432/${AZ_DATABASE_NAME}?sslmode=require&authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin
user=${AZ_POSTGRESQL_AD_NON_ADMIN_USERNAME}
EOF

Примечание.

Свойство конфигурации url добавило ?serverTimezone=UTC сообщить драйверу JDBC использовать TLS (transport Layer Security) при подключении к базе данных. Это обязательно для использования TLS с База данных Azure для PostgreSQL гибким сервером, и это хорошая практика безопасности.

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

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

DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id SERIAL PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BOOLEAN);

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

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

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

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

package com.example.demo;

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

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

Этот код Java будет использовать application.properties и файлы schema.sql, созданные ранее, чтобы подключиться к гибкому экземпляру сервера База данных Azure для PostgreSQL и создать схему, которая будет хранить наши данные.

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

Примечание.

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

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

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

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

[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 для PostgreSQL

В файле 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 для PostgreSQL

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

В файле 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 для PostgreSQL

Давайте изменим ранее вставленные данные.

В том же файле 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 для PostgreSQL

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

В том же файле 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 для PostgreSQL гибкого сервера.

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

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

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