Inicio rápido: Uso de Java y JDBC con Azure Database for PostgreSQL

Se aplica a: Azure Database for PostgreSQL: servidor único

Importante

El servicio de servidor único de Azure Database for PostgreSQL está en proceso de retirada. Es muy recomendable actualizar al servidor flexible de Azure Database for PostgreSQL. Para obtener más información sobre la migración al servidor flexible de Azure Database for PostgreSQL, consulte ¿Qué sucederá con el servicio de servidor único de Azure Database for PostgreSQL?.

En este artículo se muestra cómo crear una aplicación de ejemplo que utiliza Java y JDBC para almacenar y recuperar información en Azure Database for PostgreSQL.

JDBC es la API de Java estándar para conectarse a bases de datos relacionales tradicionales.

En este artículo, incluiremos dos métodos de autenticación: autenticación de Microsoft Entra y autenticación de PostgreSQL. La pestaña Sin contraseña muestra la autenticación de Microsoft Entra y la pestaña Contraseña muestra la autenticación de PostgreSQL.

La autenticación de Microsoft Entra es un mecanismo de conexión a Azure Database for PostgreSQL mediante identidades definidas en Microsoft Entra ID. Con la autenticación de Microsoft Entra, puede administrar las identidades de los usuarios de la base de datos y otros servicios de Microsoft en una ubicación central, lo que simplifica la administración de permisos.

La autenticación de PostgreSQL usa cuentas almacenadas en PostgreSQL. Si decide usar contraseñas como credenciales para las cuentas, estas credenciales se almacenarán en la tabla user. Dado que estas contraseñas se almacenan en PostgreSQL, deberá administrar la rotación de las contraseñas por su cuenta.

Requisitos previos

Preparación del entorno de trabajo

Primero, configure algunas variables de entorno. En Azure Cloud Shell, ejecute los comandos siguientes:

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)

Reemplace los marcadores de posición por los valores siguientes, que se usan a lo largo de este artículo:

  • <YOUR_DATABASE_SERVER_NAME>: el nombre del servidor de PostgreSQL, que debe ser único en Azure.
  • <YOUR_AZURE_REGION>: región de Azure que va a usar. Puede usar eastus de forma predeterminada, pero se recomienda que configure una región más cercana a la ubicación en la que vive. Puede ver la lista completa de las regiones disponibles; para ello, escriba az account list-locations.
  • <YOUR_POSTGRESQL_AD_NON_ADMIN_USERNAME>: nombre de usuario del servidor de bases de datos de PostgreSQL. Asegúrese de que el nombre de usuario es un usuario válido en el inquilino de Microsoft Entra.
  • <YOUR_LOCAL_IP_ADDRESS>: dirección IP del equipo local, desde el que se ejecutará la aplicación de Spring Boot. Una manera cómoda de encontrarla es abrir whatismyip.akamai.com.

Importante

Al establecer <YOUR_POSTGRESQL_AD_NON_ADMIN_USERNAME>, el nombre de usuario ya debe existir en el inquilino de Microsoft Entra o no podrá crear un usuario de Microsoft Entra en la base de datos.

A continuación, cree un grupo de recursos con el siguiente comando:

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

Creación de una instancia de Azure Database for PostgreSQL

En las secciones siguientes se describe cómo crear y configurar una instancia de base de datos.

Creación de un servidor de PostgreSQL y configuración de un usuario administrador

Lo primero que va a crear es un servidor de PostgreSQL administrado con un usuario administrador.

Nota

Puede leer información más detallada sobre la creación de servidores de PostgreSQL en Creación de un servidor de Azure Database for PostgreSQL mediante Azure Portal.

Si usa la CLI de Azure, ejecute el siguiente comando para asegurarse de que tiene permisos suficientes:

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

A continuación, ejecute el siguiente comando para crear el servidor:

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

Ahora ejecute el siguiente comando para establecer el usuario administrador de 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

Importante

Al establecer el administrador, se agrega un nuevo usuario al servidor de Azure Database for PostgreSQL con permisos de administrador totales. Solo se puede crear un administrador de Microsoft Entra por servidor PostgreSQL y la selección de otro sobrescribirá al administrador de Microsoft Entra existente configurado para el servidor.

Este comando crea un servidor de PostgreSQL pequeño y establece el administrador de Active Directory en el usuario que ha iniciado sesión.

Configuración de una regla de firewall para el servidor de PostgreSQL

De forma predeterminada, las instancias de Azure Database for PostgreSQL están protegidas. Tienen un firewall que no permite ninguna conexión entrante. Para poder usar la base de datos, es necesario agregar una regla de firewall que permita a la dirección IP local acceder al servidor de base de datos.

Como hemos configurado nuestra dirección IP local al principio de este artículo, puede abrir el firewall del servidor con el siguiente comando:

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

Si se conecta al servidor de PostgreSQL desde Subsistema de Windows para Linux (WSL) en un equipo Windows, deberá agregar el identificador de host de WSL al firewall.

Para obtener la dirección IP de la máquina host, ejecute el siguiente comando en WSL:

cat /etc/resolv.conf

Copie la dirección IP que sigue al término nameserver y, a continuación, use el siguiente comando para establecer una variable de entorno para la dirección IP de WSL:

AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

A continuación, use el siguiente comando para abrir el firewall del servidor en la aplicación basada en 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

Configuración de una base de datos PostgreSQL

El servidor de PostgreSQL que creó anteriormente está vacío. Use el siguiente comando para crear una nueva base de datos.

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

Cree un usuario que no es administrador de PostgreSQL y conceda permisos

A continuación, cree un usuario que no sea administrador y concédale todos los permisos para la base de datos.

Nota

Puede leer información más detallada sobre cómo crear usuarios de PostgreSQL en Creación de usuarios en Azure Database for PostgreSQL.

Cree un script SQL denominado create_ad_user.sql para crear un usuario que no sea administrador. Agregue el siguiente contenido y guárdelo de forma local:

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

A continuación, use el siguiente comando para ejecutar el script SQL para crear el usuario que no es administrador de 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

Ahora use el siguiente comando para quitar el archivo de script SQL temporal:

rm create_ad_user.sql

Creación de un nuevo proyecto de Java

Con su IDE favorito, cree un proyecto Java con Java 8 o superior y agregue un archivo pom.xml en su directorio raíz con el siguiente contenido:

<?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>

Este archivo es un archivo de Apache Maven que configura el proyecto para que use Java 8 y un controlador de PostgreSQL reciente para Java.

Preparación de un archivo de configuración para conectarse a Azure Database for PostgreSQL

Cree un archivo src/main/resources/application.properties y agregue el siguiente contenido:

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

Nota

La propiedad de configuración url ha anexado ?sslmode=require para indicar al controlador de JDBC que use TLS (Seguridad de la capa de transporte) al conectarse a la base de datos. Con Azure Database for PostgreSQL es obligatorio usar TLS, pero además es aconsejable hacerlo por seguridad.

Creación de un archivo SQL para generar el esquema de la base de datos

Usará un archivo src/main/resources/schema.sql para crear un esquema de base de datos. Cree ese archivo y añada el siguiente contenido:

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

Incorporación del código de la aplicación

Conectarse a la base de datos

A continuación, agregue el código Java que usará JDBC para almacenar y recuperar datos del servidor de PostgreSQL.

Cree un archivo src/main/java/DemoApplication.java y agregue el contenido siguiente:

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

Este código Java usará los archivos application.properties y schema.sql que se crearon antes para conectarse al servidor de PostgreSQL y crear un esquema que almacenará los datos.

En este archivo, puede ver que hemos comentado métodos para insertar, leer, actualizar y eliminar datos. Codificará esos métodos en el resto de este artículo y podrá quitar la marca de comentario una después de otra.

Nota

Las credenciales de la base de datos se almacenan en las propiedades user (usuario) y password (contraseña) del archivo application.properties. Estas credenciales se usan al ejecutar DriverManager.getConnection(properties.getProperty("url"), properties);, ya que el archivo de propiedades se pasa como argumento.

Ahora puede ejecutar esta clase principal con su herramienta favorita:

  • Con el IDE, debería poder hacer clic con el botón derecho en la clase DemoApplication y ejecutarla.
  • Con Maven, puede ejecutar la aplicación mediante el siguiente comando: mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication".

La aplicación debería conectarse a Azure Database for PostgreSQL, crear un esquema de base de datos y cerrar la conexión, como debería ver en los registros de la consola:

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

Creación de una clase de dominio

Cree la nueva clase de Java Todo, junto a la clase DemoApplication y agregue el siguiente código:

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

Esta clase es un modelo de dominio asignado a la tabla todo que creó al ejecutar el script schema.sql.

Inserción de datos en Azure Database for PostgreSQL

En el archivo src/main/java/DemoApplication.java, después del método main, agregue el método siguiente para insertar los datos en la base de datos:

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

Ahora puede quitar la marca de comentario de las dos líneas siguientes en el método main:

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

La ejecución de la clase main debería generar ahora la siguiente salida:

[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

Lectura de datos de Azure Database for PostgreSQL

Lea los datos que se insertaron previamente para validar que el código funciona correctamente.

En el archivo src/main/java/DemoApplication.java, después del método insertData, agregue el método siguiente para leer los datos de la base de datos:

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

Ahora puede quitar la marca de comentario de la línea siguiente en el método main:

todo = readData(connection);

La ejecución de la clase main debería generar ahora la siguiente salida:

[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 

Actualización de datos en Azure Database for PostgreSQL

A continuación, actualice los datos que se insertaron anteriormente.

En el archivo src/main/java/DemoApplication.java, después del método readData, agregue el método siguiente para actualizar los datos de la base de datos:

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

Ahora puede quitar la marca de comentario de las dos líneas siguientes en el método main:

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

La ejecución de la clase main debería generar ahora la siguiente salida:

[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 

Eliminación de datos en Azure Database for PostgreSQL

Por último, elimine los datos que se insertaron anteriormente.

En el archivo src/main/java/DemoApplication.java, después del método updateData, agregue el método siguiente para eliminar los datos de la base de datos:

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

Ahora puede quitar la marca de comentario de la línea siguiente en el método main:

deleteData(todo, connection);

La ejecución de la clase main debería generar ahora la siguiente salida:

[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 

Limpieza de recursos

Felicidades. Ha creado una aplicación de Java que usa JDBC para almacenar y recuperar datos de Azure Database for PostgreSQL.

Para limpiar todos los recursos utilizados durante esta guía de inicio rápido, elimine el grupo de recursos con el siguiente comando:

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

Pasos siguientes