Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se muestra cómo crear una aplicación de ejemplo que usa Java y JDBC para almacenar y recuperar información en Azure HorizonDB (versión preliminar).
JDBC es la API Java estándar para conectarse a bases de datos relacionales tradicionales.
Los pasos de este artículo incluyen la autenticación de PostgreSQL.
La autenticación de PostgreSQL usa cuentas almacenadas en PostgreSQL y debe administrar la rotación de las contraseñas usted mismo.
Prerequisites
- Una cuenta de Azure. Si no tiene una, obtenga la versión de evaluación gratuita.
- Azure Cloud Shell o la CLI de Azure. Use Azure Cloud Shell para que se autentique automáticamente y tenga acceso a todas las herramientas que necesita.
- Un kit de desarrollo de Java compatible, versión 8 (incluido en Cloud Shell).
- La herramienta de compilación Apache Maven.
Preparación del entorno de trabajo
En primer lugar, use el siguiente comando para configurar algunas variables de entorno.
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>
Reemplace los marcadores de posición por los siguientes valores, que se usan en este artículo:
-
<YOUR_DATABASE_CLUSTER_NAME>: El nombre de su clúster de Azure HorizonDB, que debe ser único dentro de su suscripción y grupo de recursos de Azure. -
<YOUR_DATABASE_NAME>: el nombre de la base de datos que usa en el clúster de Azure HorizonDB. -
<YOUR_AZURE_REGION>: región de Azure que se va a usar. Puede usaraustraliaeastde forma predeterminada, pero configurar 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, escribaaz account list-locations. -
<YOUR_POSTGRESQL_ADMIN_PASSWORD>y<YOUR_POSTGRESQL_NON_ADMIN_PASSWORD>: la contraseña del clúster de HorizonDB de Azure. Esa contraseña debe tener un mínimo de ocho caracteres. Los caracteres deben ser de tres de las siguientes categorías: letras en mayúsculas en inglés, letras minúsculas en inglés, números (0 al 9) y caracteres sinfánfano (!, $, #, %, etc.). -
<YOUR_LOCAL_IP_ADDRESS>: la dirección IP del equipo local, desde la que se ejecuta la aplicación de Spring Boot. Una forma sencilla de averiguarlo es abrir whatismyip.akamai.com.
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 un clúster de Azure HorizonDB
Note
No incluyas información personal, sensible o confidencial en nombres de recursos (por ejemplo, nombre de tabla, nombre de base de datos) ni en etiquetas de recursos. Los datos que introduces en estos campos no se consideran datos de clientes.
En las secciones siguientes se describe cómo crear y configurar el clúster de base de datos.
Creación de un clúster de Azure HorizonDB
Configuración del usuario administrador
En primer lugar, cree una instancia administrada de Azure HorizonDB.
Note
Para obtener información más detallada sobre cómo crear Azure HorizonDB, consulte Create an Azure horizonDB cluster.
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
Este comando crea un pequeño clúster de Azure HorizonDB.
¿Tiene algún problema? Cuéntenoslo.
Configuración de una regla de firewall para la instancia de Azure HorizonDB
Azure las instancias de HorizonDB son seguras de forma predeterminada. Tienen un firewall que bloquea todas las conexiones entrantes. Para usar la base de datos, agregue una regla de firewall que conceda acceso a la dirección IP local al servidor de bases de datos.
Dado que configuró la dirección IP local al principio de este artículo, puede abrir el firewall del servidor ejecutando el siguiente comando:
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 se conecta al clúster de Azure HorizonDB desde Subsistema de Windows para Linux (WSL) en un equipo de Windows, debe 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 nameservery, 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 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
Creación de una base de datos Azure HorizonDB
Cree un script SQL denominado create_database.sql para crear una nueva base de datos en el clúster. Agregue el siguiente contenido y guarde el archivo localmente:
cat << EOF > create_database.sql
CREATE DATABASE "$AZ_DATABASE_NAME";
EOF
Ejecute este comando para obtener el nombre de dominio completo de Azure HorizonDB y copie el valor de clusterName:
az horizondb show \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_CLUSTER_NAME \
--query "{clusterName:properties.fullyQualifiedDomainName, adminUser:properties.administratorLogin}" \
--output table
Copie el clusterName valor y úselo en el siguiente comando:
AZ_HORIZONDB_FQDN=<the-copied-clusterName-value>
A continuación, ejecute el siguiente comando para ejecutar el script SQL y crear la base de datos:
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
Ahora, ejecute el siguiente comando para eliminar el archivo de script SQL temporal:
rm create_database.sql
Creación de un usuario que no es administrador de HorizonDB Azure y concesión de permisos
A continuación, cree un usuario que no sea de administrador y conceda todos los permisos a la base de datos.
Cree un script SQL denominado create_user.sql para crear un usuario que no sea administrador. Agregue el siguiente contenido y guarde el archivo localmente:
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
A continuación, ejecute el siguiente comando para ejecutar el script SQL y crear el usuario que no sea administrador 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
Ahora, ejecute el siguiente comando para eliminar el archivo de script SQL temporal:
rm create_user.sql
Creación de un nuevo proyecto de Java
Con su IDE favorito, cree un nuevo proyecto de Java mediante Java 8 o posterior. Agregue un archivo pom.xml en el 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>
</dependencies>
</project>
Este archivo es un archivo de Apache Maven que configura el proyecto para usar:
- Java 8
- Un reciente controlador de PostgreSQL para Java
Preparación de un archivo de configuración para conectarse a Azure HorizonDB
Cree un archivo src/main/resources/application.properties y agregue el siguiente contenido:
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 propiedad de configuración url incluye ?sslmode=require para asegurarse de que el controlador JDBC use TLS (Seguridad de la Capa de Transporte) al conectarse a la base de datos. Azure HorizonDB requiere TLS y es una práctica de seguridad recomendada.
Creación de un archivo SQL para generar el esquema de la base de datos
Use un archivo src/main/resources/schema.sql para crear un esquema de base de datos. Cree ese archivo con el siguiente contenido:
DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id SERIAL PRIMARY KEY, description text, details text, done BOOLEAN);
Programa la aplicación
Conectarse a la base de datos
A continuación, agregue el código de Java que usa JDBC para almacenar y recuperar datos de la instancia de Azure HorizonDB.
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());
}
/*
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();
}
}
¿Tiene algún problema? Cuéntenoslo.
Este código Java usa los archivos application.properties y el schema.sql que creamos anteriormente, para conectarse a la instancia de Azure HorizonDB y crear un esquema que almacene los datos.
En este archivo, puedes ver que hemos comentado los métodos para insertar, leer, actualizar y eliminar datos: implementaremos esos métodos en el resto de este artículo, y podrás ir descomentándolos uno tras otro.
Note
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 la ejecución de:
mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication".
La aplicación debe conectarse a la instancia de Azure HorizonDB, crear un esquema de base de datos y, a continuación, 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.
Insertar datos en Azure HorizonDB
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 descomentar 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
Leer datos de Azure HorizonDB
Vamos a leer 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 descomentar 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 HorizonDB
Vamos a actualizar 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 descomentar 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
Eliminar datos en Azure HorizonDB
Por último, vamos a eliminar 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 descomentar 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 una instancia de Azure HorizonDB.
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