Démarrage rapide : Utiliser Java et JDBC pour Azure HorizonDB (préversion)

Cet article montre comment créer un exemple d’application qui utilise Java et JDBC pour stocker et récupérer des informations dans Azure HorizonDB (préversion).

JDBC est l’API Java standard pour la connexion à des bases de données relationnelles traditionnelles.

Les étapes décrites dans cet article incluent l’authentification PostgreSQL.

L’authentification PostgreSQL utilise des comptes stockés dans PostgreSQL et vous devez gérer la rotation des mots de passe vous-même.

Prerequisites

Préparer l’environnement de travail

Tout d’abord, utilisez la commande suivante pour configurer certaines variables d’environnement.

export AZ_RESOURCE_GROUP=database-workshop
export AZ_DATABASE_CLUSTER_NAME=<YOUR_DATABASE_CLUSTER_NAME>
export AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
export AZ_LOCATION=<YOUR_AZURE_REGION>
export AZ_POSTGRESQL_ADMIN_USERNAME=demo
export AZ_POSTGRESQL_ADMIN_PASSWORD=<YOUR_POSTGRESQL_ADMIN_PASSWORD>
export AZ_POSTGRESQL_NON_ADMIN_USERNAME=demo-non-admin
export AZ_POSTGRESQL_NON_ADMIN_PASSWORD=<YOUR_POSTGRESQL_NON_ADMIN_PASSWORD>
export AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>

Remplacez les espaces réservés par les valeurs suivantes, qui sont utilisées dans cet article :

  • <YOUR_DATABASE_CLUSTER_NAME> : nom de votre cluster Azure HorizonDB, qui doit être unique dans votre abonnement Azure et le groupe de ressources.
  • <YOUR_DATABASE_NAME> : nom de la base de données que vous utilisez dans votre cluster Azure HorizonDB.
  • <YOUR_AZURE_REGION> : région Azure à utiliser. Vous pouvez utiliser australiaeast par défaut, mais configurer une région plus proche de l’endroit où vous vivez. Vous pouvez voir la liste complète des régions disponibles en entrant az account list-locations.
  • <YOUR_POSTGRESQL_ADMIN_PASSWORD> et <YOUR_POSTGRESQL_NON_ADMIN_PASSWORD> : mot de passe de votre cluster HorizonDB Azure. Ce mot de passe doit comporter au minimum huit caractères. Les caractères doivent appartenir à trois des catégories suivantes : lettres majuscules, lettres minuscules, chiffres (0 à 9) et caractères non alphanumériques (!, $, #, %, etc.).
  • <YOUR_LOCAL_IP_ADDRESS>: adresse IP de votre ordinateur local, à partir de laquelle vous exécutez votre application Spring Boot. Un moyen pratique de trouver c’est d’ouvrir whatismyip.akamai.com.

Ensuite, créez un groupe de ressources à l’aide de la commande suivante :

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

Créer un cluster Azure HorizonDB

Les sections suivantes décrivent comment créer et configurer votre cluster de base de données.

Créer un cluster Azure HorizonDB

Configurer l’utilisateur administrateur

Tout d’abord, créez une instance Azure HorizonDB managée.

Note

Pour plus d’informations sur la création d’Azure HorizonDB, consultez Creater un cluster Azure HorizonDB.

az horizondb create \
  --resource-group $AZ_RESOURCE_GROUP \
  --name $AZ_DATABASE_CLUSTER_NAME \
  --location $AZ_LOCATION \
  --version 17 \
  --administrator-login $AZ_POSTGRESQL_ADMIN_USERNAME \
  --administrator-login-password $AZ_POSTGRESQL_ADMIN_PASSWORD \
  --v-cores 2 \
  --yes \
  --output tsv

Cette commande crée un petit cluster HorizonDB Azure.

Vous rencontrez des problèmes ? Faites-le nous savoir.

Configurer une règle de pare-feu pour votre instance Azure HorizonDB

Azure instances HorizonDB sont sécurisées par défaut. Ils ont un pare-feu qui bloque toutes les connexions entrantes. Pour utiliser votre base de données, ajoutez une règle de pare-feu qui accorde à votre adresse IP locale l’accès au serveur de base de données.

Étant donné que vous avez configuré votre adresse IP locale au début de cet article, vous pouvez ouvrir le pare-feu du serveur en exécutant la commande suivante :

az horizondb firewall-rule create \
  --resource-group $AZ_RESOURCE_GROUP \
  --cluster-name $AZ_DATABASE_CLUSTER_NAME \
  --firewall-rule-name $AZ_DATABASE_CLUSTER_NAME-database-allow-local-ip \
  --start-ip-address $AZ_LOCAL_IP_ADDRESS \
  --end-ip-address $AZ_LOCAL_IP_ADDRESS \
  --output tsv

Si vous vous connectez à votre cluster Azure HorizonDB à partir de Sous-système Windows pour Linux (WSL) sur un ordinateur Windows, vous devez ajouter l'ID d'hôte WSL à votre pare-feu.

Obtenez l’adresse IP de votre ordinateur hôte en exécutant la commande suivante dans WSL :

cat /etc/resolv.conf

Copiez l’adresse IP qui suit le terme nameserver, puis utilisez la commande suivante pour définir une variable d’environnement pour l’adresse IP WSL :

AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

Utilisez ensuite la commande suivante pour ouvrir le pare-feu du serveur sur votre application WSL :

az horizondb firewall-rule create \
  --resource-group $AZ_RESOURCE_GROUP \
  --cluster-name $AZ_DATABASE_CLUSTER_NAME \
  --firewall-rule-name $AZ_DATABASE_CLUSTER_NAME-database-allow-local-ip \
  --start-ip-address $AZ_WSL_IP_ADDRESS \
  --end-ip-address $AZ_WSL_IP_ADDRESS \
  --output tsv

Créer une base de données Azure HorizonDB

Créez un script SQL nommé create_database.sql pour créer une base de données dans votre cluster. Ajoutez le contenu suivant et enregistrez le fichier localement :

cat << EOF > create_database.sql
CREATE DATABASE "$AZ_DATABASE_NAME";
EOF

Exécutez cette commande pour obtenir votre nom de domaine complet Azure HorizonDB et copiez la valeur clusterName :

az horizondb show \
  --resource-group $AZ_RESOURCE_GROUP \
  --name $AZ_DATABASE_CLUSTER_NAME \
  --query "{clusterName:properties.fullyQualifiedDomainName, adminUser:properties.administratorLogin}" \
  --output table

Copiez la valeur et utilisez-la clusterName dans la commande suivante :

AZ_HORIZONDB_FQDN=<the-copied-clusterName-value>

Exécutez ensuite la commande suivante pour exécuter le script SQL et créer votre base de données :

psql "host=$AZ_HORIZONDB_FQDN user=$AZ_POSTGRESQL_ADMIN_USERNAME dbname=$AZ_DATABASE_NAME port=5432 password=$AZ_POSTGRESQL_ADMIN_PASSWORD sslmode=require" < create_database.sql

Exécutez maintenant la commande suivante pour supprimer le fichier de script SQL temporaire :

rm create_database.sql

Créer un utilisateur non administrateur HorizonDB Azure et accorder des autorisations

Ensuite, créez un utilisateur non administrateur et accordez toutes les autorisations à la base de données.

Créez un script SQL nommé create_user.sql pour créer un utilisateur non administrateur. Ajoutez le contenu suivant et enregistrez le fichier localement :

cat << EOF > create_user.sql
CREATE ROLE "$AZ_POSTGRESQL_NON_ADMIN_USERNAME" WITH LOGIN PASSWORD '$AZ_POSTGRESQL_NON_ADMIN_PASSWORD';
GRANT ALL PRIVILEGES ON DATABASE $AZ_DATABASE_NAME TO "$AZ_POSTGRESQL_NON_ADMIN_USERNAME";
EOF

Exécutez ensuite la commande suivante pour exécuter le script SQL et créer l’utilisateur non administrateur Microsoft Entra :

psql "host=$AZ_HORIZONDB_FQDN user=$AZ_POSTGRESQL_ADMIN_USERNAME dbname=$AZ_DATABASE_NAME port=5432 password=$AZ_POSTGRESQL_ADMIN_PASSWORD sslmode=require" < create_user.sql

Exécutez maintenant la commande suivante pour supprimer le fichier de script SQL temporaire :

rm create_user.sql

Créer un projet Java

À l’aide de votre IDE favori, créez un projet Java à l’aide de Java 8 ou version ultérieure. Ajoutez un fichier pom.xml dans le répertoire racine avec le contenu suivant :

<?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>
    </dependencies>
</project>

Il s’agit d’un fichier Apache Maven qui configure le projet pour qu’il utilise :

  • Java 8
  • Un pilote PostgreSQL récent pour Java

Préparer un fichier de configuration pour se connecter à Azure HorizonDB

Créez un fichier src/main/resources/application.properties et ajoutez le contenu suivant :

cat << EOF > src/main/resources/application.properties
url=jdbc:postgresql://${AZ_HORIZONDB_FQDN}:5432/${AZ_DATABASE_NAME}?sslmode=require
user=${AZ_POSTGRESQL_NON_ADMIN_USERNAME}
password=${AZ_POSTGRESQL_NON_ADMIN_PASSWORD}
EOF

Note

La propriété url de configuration inclut ?sslmode=require pour vous assurer que le pilote JDBC utilise TLS (Transport Layer Security) lors de la connexion à la base de données. Azure HorizonDB nécessite TLS et il est recommandé de procéder à une pratique de sécurité.

Créer un fichier SQL pour générer le schéma de base de données

Utilisez un fichier src/main/resources/schema.sql pour créer un schéma de base de données. Créez ce fichier avec le contenu suivant :

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

Coder l’application

Se connecter à la base de données

Ensuite, ajoutez le code Java qui utilise JDBC pour stocker et récupérer des données à partir de votre instance horizonDB Azure.

Créez un fichier src/main/java/DemoApplication.java, puis ajoutez le contenu suivant :

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

Vous rencontrez des problèmes ? Faites-le nous savoir.

Ce code Java utilise les fichiers application.properties et schema.sql que nous avons créés précédemment pour se connecter à l’instance Azure HorizonDB et créer un schéma qui stocke nos données.

Dans ce fichier, vous pouvez voir que nous avons commenté les méthodes d’insertion, de lecture, de mise à jour et de suppression des données : nous allons coder ces méthodes dans le reste de cet article, et vous serez en mesure de les supprimer un après l’autre.

Note

Les informations d’identification de base de données sont stockées dans les propriétés user et password du fichier application.properties. Ces informations d’identification sont utilisées lors de l’exécution de DriverManager.getConnection(properties.getProperty("url"), properties);, car le fichier de propriétés est passé comme argument.

Vous pouvez maintenant exécuter cette classe principale avec votre outil préféré.

  • Avec votre IDE, vous devez être en mesure de cliquer avec le bouton droit sur la classe DemoApplication et de l’exécuter.
  • À l’aide de Maven, vous pouvez utiliser l’application en exécutant : mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication".

L’application doit se connecter à l’instance Azure HorizonDB, créer un schéma de base de données, puis fermer la connexion, comme vous devez le voir dans les journaux de la console :

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

Créer une classe de domaine

Créez une classe Java Todo parallèlement à la classe DemoApplication, puis ajoutez le code suivant :

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

Cette classe est un modèle de domaine mappé sur la table todo que vous avez créée lors de l’exécution du script schema.sql.

Insérer des données dans Azure HorizonDB

Dans le fichier src/main/java/DemoApplication.java, après la méthode main, ajoutez la méthode suivante pour insérer des données dans la base de données :

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

Vous pouvez maintenant supprimer les marques de commentaire des deux lignes suivantes dans la méthode main :

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

L’exécution de la classe main doit maintenant produire la sortie suivante :

[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

Lire les données de Azure HorizonDB

Nous allons lire les données précédemment insérées pour valider le bon fonctionnement de notre code.

Dans le fichier src/main/java/DemoApplication.java, après la méthode insertData, ajoutez la méthode suivante pour lire des données de la base de données :

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

Vous pouvez maintenant supprimer les marques de commentaire de la ligne suivante dans la méthode main :

todo = readData(connection);

L’exécution de la classe main doit maintenant produire la sortie suivante :

[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

Mettre à jour les données dans Azure HorizonDB

Nous allons mettre à jour les données que nous avons insérées précédemment.

Toujours dans le fichier src/main/java/DemoApplication.java, après la méthode readData, ajoutez la méthode suivante pour mettre à jour des données dans la base de données :

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

Vous pouvez maintenant supprimer les marques de commentaire des deux lignes suivantes dans la méthode main :

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

L’exécution de la classe main doit maintenant produire la sortie suivante :

[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

Supprimer des données dans Azure HorizonDB

Enfin, nous allons supprimer les données que nous avons insérées précédemment.

Toujours dans le fichier src/main/java/DemoApplication.java, après la méthode updateData, ajoutez la méthode suivante pour supprimer des données dans la base de données :

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

Vous pouvez maintenant supprimer les marques de commentaire de la ligne suivante dans la méthode main :

deleteData(todo, connection);

L’exécution de la classe main doit maintenant produire la sortie suivante :

[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

Nettoyer les ressources

Félicitations! Vous avez créé une application Java qui utilise JDBC pour stocker et récupérer des données à partir d'une instance horizonDB Azure.

Pour nettoyer toutes les ressources utilisées dans le cadre de ce guide de démarrage rapide, supprimez le groupe de ressources à l’aide de la commande suivante :

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