クイックスタート: Azure Database for PostgreSQL で Java と JDBC を使用する

適用対象: Azure Database for PostgreSQL - 単一サーバー

重要

Azure Database for PostgreSQL - シングル サーバーは廃止パスにあります。 Azure Database for PostgreSQL - フレキシブル サーバーにアップグレードすることを強くお勧めします。 Azure Database for PostgreSQL - フレキシブル サーバーへの移行の詳細については、Azure Database for PostgreSQL 単一サーバーの現状に関するページを参照してください。

この記事では、Java と JDBC を使用して Azure Database for PostgreSQL に情報を格納および取得するサンプル アプリケーションを作成する方法を示します。

JDBC は、従来のリレーショナル データベースに接続するための標準の Java API です。

この記事には、Microsoft Entra 認証と PostgreSQL 認証の 2 つの認証方法が含まれています。 [パスワードレス] タブには Microsoft Entra 認証が表示され、[パスワード] タブには PostgreSQL 認証が表示されます。

Microsoft Entra 認証は、Microsoft Entra ID で定義された ID を使用して Azure Database for PostgreSQL に接続するための仕組みです。 Microsoft Entra 認証を使用すると、データベース ユーザーの ID や他の Microsoft サービスを一元管理でき、アクセス許可の管理が容易になります。

PostgreSQL 認証では、PostgreSQL に格納されているアカウントが使用されます。 アカウントの資格情報としてパスワードを使用することを選択した場合、これらの資格情報は user テーブルに格納されます。 これらのパスワードは PostgreSQL に格納されるため、パスワードのローテーションを自分で管理する必要があります。

前提条件

  • Azure アカウント。 所有していない場合は、無料試用版を入手してください。
  • Azure Cloud Shell または Azure CLI 2.37.0 以上が必要です。 Azure Cloud Shell をお勧めします。これにより、自動的にログインし、必要なすべてのツールにアクセスできるようになります。
  • サポートされている Java 開発キット、バージョン 8 (Azure Cloud Shell に含まれます)。
  • Apache Maven ビルド ツール。

作業環境を準備する

まず、環境変数をいくつか設定します。 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_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)
export CURRENT_USER_OBJECTID=$(az ad signed-in-user show --query id -o tsv)

プレースホルダーは、この記事全体で使用される次の値に置き換えてください。

  • <YOUR_DATABASE_SERVER_NAME>: PostgreSQL サーバーの名前。Azure 全体で一意である必要があります。
  • <YOUR_AZURE_REGION>:使用する Azure リージョン。 既定で eastus を使用できますが、居住地に近いリージョンを構成することをお勧めします。 az account list-locations と入力すると、使用可能なリージョンの一覧全体を表示できます。
  • <YOUR_POSTGRESQL_AD_NON_ADMIN_USERNAME>: 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 Database for PostgreSQL インスタンスを作成する

次のセクションでは、データベース インスタンスを作成および構成する方法について説明します。

PostgreSQL サーバーを作成し、管理者ユーザーを設定する

最初に作成するのは、管理ユーザーを持つマネージド PostgreSQL サーバーです。

注意

PostgreSQL サーバーの作成に関する詳細については、Azure portal を使用した Azure Database for PostgreSQL サーバーの作成に関するページを参照してください。

Azure CLI を使用する場合は、次のコマンドを実行して、十分なアクセス許可があることを確認します。

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

次に、次のコマンドを実行してサーバーを作成します。

az postgres 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 postgres 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 Database for PostgreSQL サーバーに追加されます。 作成できる Microsoft Entra 管理者は、PostgreSQL サーバーあたり 1 人だけです。別の管理者を選択すると、そのサーバーに構成されている既存の Microsoft Entra 管理者が上書きされます。

このコマンドにより、小さな PostgreSQL サーバーが作成され、Active Directory 管理者がサインインしているユーザーに設定されます。

PostgreSQL サーバーのファイアウォール規則を構成する

Azure Database for PostgreSQL インスタンスは、既定でセキュリティ保護されています。 受信接続を一切許可しないファイアウォールがあります。 データベースを使用できるようにするには、データベース サーバーにアクセスするためのローカル IP アドレスを許可するファイアウォール規則を追加する必要があります。

この記事の冒頭でローカル IP アドレスを構成したので、次のコマンドを実行してサーバーのファイアウォールを開くことができます。

az postgres 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

Windows コンピューター上の Linux 用 Windows サブシステム (WSL) から PostgreSQL サーバーに接続する場合、WSL のホスト ID をファイアウォールに追加する必要があります。

WSL で以下のコマンドを実行して、ホスト マシンの IP アドレスを取得します。

cat /etc/resolv.conf

nameserver の後に続く IP アドレスをコピーし、次のコマンドで WSL の IP アドレスを環境変数に設定します。

AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

次に、以下のコマンドを使って、サーバーのファイアウォールを WSL ベースのアプリに開放します。

az postgres 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_WSL_IP_ADDRESS \
    --end-ip-address $AZ_WSL_IP_ADDRESS \
    --output tsv

PostgreSQL データベースを構成する

先ほど作成した PostgreSQL サーバーは空です。 次のコマンドを使用して、新しいデータベースを作成します。

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

PostgreSQL の非管理者ユーザーを作成し、アクセス許可を付与する

次に、非管理者ユーザーを作成し、データベースに対するすべてのアクセス許可を付与します。

Note

PostgreSQL ユーザーの作成の詳細については、Azure Database for PostgreSQL でのユーザーの作成に関するページを参照してください。

非管理者ユーザーを作成するための create_ad_user.sql という名前の SQL スクリプトを作成します。 次の内容を追加し、ローカルに保存します。

cat << EOF > create_ad_user.sql
SET aad_validate_oids_in_tenant = off;
CREATE ROLE "$AZ_POSTGRESQL_AD_NON_ADMIN_USERNAME" WITH LOGIN IN ROLE azure_ad_user;
GRANT ALL PRIVILEGES ON DATABASE $AZ_DATABASE_NAME TO "$AZ_POSTGRESQL_AD_NON_ADMIN_USERNAME";
EOF

次に、次のコマンドを使用して SQL スクリプトを実行し、Microsoft Entra の非管理者ユーザーを作成します。

psql "host=$AZ_DATABASE_SERVER_NAME.postgres.database.azure.com user=$CURRENT_USERNAME@$AZ_DATABASE_SERVER_NAME dbname=$AZ_DATABASE_NAME 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 プロジェクトを作成する

お気に入りの IDE を使用して、Java 8 以上を使用する新しい 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>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>

このファイルは、Java 8 と Java 用の最近の PostgreSQL ドライバーを使用するようにプロジェクトを構成する Apache Maven ファイルです。

Azure Database for 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}@${AZ_DATABASE_SERVER_NAME}
EOF

Note

構成プロパティ url?sslmode=require が追加されて、データベースへの接続時に TLS (Transport Layer Security) を使用するように JDBC ドライバーに指示されます。 Azure Database for PostgreSQL で TLS を使用することは必須であり、優れたセキュリティ慣行です。

データベース スキーマを生成するための SQL ファイルを作成する

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

アプリケーションをコーディングする

データベースに接続する

次に、JDBC を使用して PostgreSQL サーバーにデータを格納および取得する Java コードを追加します。

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

        /* Prepare for data processing in the PostgreSQL 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();
    }
}

この Java コードは、PostgreSQL サーバーに接続して、データを格納するスキーマを作成するために、先ほど作成した application.propertiesschema.sql の各ファイルを使用します。

このファイルでは、データの挿入、読み取り、更新、削除を行うメソッドがコメント化されていることがわかります。 この記事の残りの部分では、これらのメソッドをコーディングし、次々にコメントを解除することができます。

注意

データベースの資格情報は、application.properties ファイルの user プロパティと password プロパティに格納されます。 プロパティ ファイルは引数として渡されるため、これらの資格情報は DriverManager.getConnection(properties.getProperty("url"), properties); を実行するときに使用されます。

以後、このメイン クラスは、次の任意のツールを使用して実行することができます。

  • IDE を使用する場合: DemoApplication クラスを右クリックして実行します。
  • Maven を使用する場合、コマンド mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication" を使用してアプリケーションを実行できます。

次のコンソール ログが示すように、このアプリケーションは、Azure Database for PostgreSQL に接続してデータベース スキーマを作成した後、接続を閉じます。

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

ドメイン クラスを作成する

DemoApplication クラスの横に新しい Todo Java クラスを作成し、以下のコードを追加します。

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

このクラスは、schema.sql スクリプトを実行する際に作成した todo テーブルにマップされるドメイン モデルです。

Azure Database for 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 メソッドの次の 2 つの行のコメントを解除できます。

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

メイン クラスを実行すると、次の出力が生成されるはずです。

[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 Database for 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);

メイン クラスを実行すると、次の出力が生成されるはずです。

[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 Database for 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 メソッドの次の 2 つの行のコメントを解除できます。

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

メイン クラスを実行すると、次の出力が生成されるはずです。

[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 Database for 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);

メイン クラスを実行すると、次の出力が生成されるはずです。

[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 

リソースをクリーンアップする

お疲れさまでした。 JDBC を使用して Azure Database for PostgreSQL にデータを格納および取得する Java アプリケーションを作成しました。

このクイックスタートで使用したすべてのリソースをクリーンアップするには、次のコマンドを使用してリソース グループを削除します。

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

次のステップ