Guida introduttiva: Usare Java e JDBC con Database di Azure per PostgreSQL
SI APPLICA A: Database di Azure per PostgreSQL - Server singolo
Importante
Database di Azure per PostgreSQL - Server singolo si trova nel percorso di ritiro. È consigliabile eseguire l'aggiornamento a Database di Azure per PostgreSQL - Server flessibile. Per altre informazioni sulla migrazione a Database di Azure per PostgreSQL - Server flessibile, vedere Che cosa accade a Database di Azure per PostgreSQL server singolo?
Questo articolo illustra come creare un'applicazione di esempio che usa Java e JDBC per archiviare e recuperare informazioni in Database di Azure per PostgreSQL.
JDBC è l'API Java standard per la connessione ai database relazionali tradizionali.
In questo articolo verranno inclusi due metodi di autenticazione: autenticazione di Microsoft Entra e autenticazione PostgreSQL. La scheda Senza password mostra l'autenticazione di Microsoft Entra e la scheda Password mostra l'autenticazione PostgreSQL.
L'autenticazione di Microsoft Entra è un meccanismo per la connessione a Database di Azure per PostgreSQL usando le identità definite in Microsoft Entra ID. Con l'autenticazione di Microsoft Entra, è possibile gestire le identità utente del database e altre servizi Microsoft in una posizione centrale, semplificando la gestione delle autorizzazioni.
L'autenticazione postgreSQL usa gli account archiviati in PostgreSQL. Se si sceglie di usare le password come credenziali per gli account, queste credenziali verranno archiviate nella user
tabella. Poiché queste password vengono archiviate in PostgreSQL, è necessario gestire manualmente la rotazione delle password.
Prerequisiti
- Un account Azure. Se non è disponibile, ottenere una versione di valutazione gratuita.
- È necessario Azure Cloud Shell o l'interfaccia della riga di comando di Azure 2.37.0 o versione successiva. È consigliabile usare Azure Cloud Shell in modo che l'accesso venga eseguito automaticamente e che sia possibile accedere a tutti gli strumenti necessari.
- Un'istanza supportata di Java Development Kit, versione 8 (inclusa in Azure Cloud Shell).
- Strumento di compilazione di Apache Maven.
Preparare l'ambiente di lavoro
Prima di tutto, configurare alcune variabili di ambiente. In Azure Cloud Shell eseguire i comandi seguenti:
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)
Sostituire i segnaposto con i valori seguenti, che vengono usati nell'intero articolo:
<YOUR_DATABASE_SERVER_NAME>
: nome del server PostgreSQL, che deve essere univoco in Azure.<YOUR_AZURE_REGION>
: l'area di Azure che verrà usata. È possibile usareeastus
per impostazione predefinita, ma è consigliabile configurare un'area più vicina a dove si risiede. È possibile visualizzare l'elenco completo delle aree disponibili immettendoaz account list-locations
.<YOUR_POSTGRESQL_AD_NON_ADMIN_USERNAME>
: nome utente del server di database PostgreSQL. Assicurarsi che il nome utente sia un utente valido nel tenant di Microsoft Entra.<YOUR_LOCAL_IP_ADDRESS>
: indirizzo IP del computer locale, da cui si eseguirà l'applicazione Spring Boot. Un modo pratico per trovare è aprire whatismyip.akamai.com.
Importante
Quando si imposta <YOUR_POSTGRESQL_AD_NON_ADMIN_Uedizione Standard RNAME>, il nome utente deve esistere già nel tenant di Microsoft Entra oppure non sarà possibile creare un utente di Microsoft Entra nel database.
Creare quindi un gruppo di risorse usando il comando seguente:
az group create \
--name $AZ_RESOURCE_GROUP \
--location $AZ_LOCATION \
--output tsv
Creare un'istanza di Database di Azure per PostgreSQL
Le sezioni seguenti descrivono come creare e configurare l'istanza del database.
Creare un server PostgreSQL e configurare l'utente amministratore
La prima cosa che si creerà è un server PostgreSQL gestito con un utente amministratore.
Nota
Per informazioni più dettagliate sulla creazione di server PostgreSQL, vedere Creare un server di Database di Azure per PostgreSQL nel portale di Azure.
Se si usa l'interfaccia della riga di comando di Azure, eseguire il comando seguente per assicurarsi che disponga di autorizzazioni sufficienti:
az login --scope https://graph.microsoft.com/.default
Eseguire quindi il comando seguente per creare il server:
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
Eseguire ora il comando seguente per impostare l'utente amministratore di 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
Quando si imposta l'amministratore, nel server di Database di Azure PostgreSQL viene aggiunto un nuovo utente con autorizzazioni di amministratore complete. È possibile creare un solo amministratore di Microsoft Entra per ogni server PostgreSQL e selezionare un altro utente sovrascriverà l'amministratore esistente di Microsoft Entra configurato per il server.
Questo comando crea un piccolo server PostgreSQL e imposta l'amministratore di Active Directory sull'utente connesso.
Configurare una regola del firewall per il server PostgreSQL
Le istanze di Database di Azure per PostgreSQL sono protette per impostazione predefinita. Includono un firewall che non consente alcuna connessione in ingresso. Per poter usare il database, è necessario aggiungere una regola del firewall che consenta all'indirizzo IP locale di accedere al server di database.
Poiché all'inizio di questo articolo è stato configurato un indirizzo IP locale, è possibile aprire il firewall del server eseguendo questo 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
Se ci si connette al server PostgreSQL da sottosistema Windows per Linux (WSL) in un computer Windows, è necessario aggiungere l'ID host WSL al firewall.
Ottenere l'indirizzo IP del computer host eseguendo il comando seguente in WSL:
cat /etc/resolv.conf
Copiare l'indirizzo IP seguendo il termine nameserver
, quindi usare il comando seguente per impostare una variabile di ambiente per l'indirizzo IP WSL:
AZ_WSL_IP_ADDRESS=<the-copied-IP-address>
Usare quindi il comando seguente per aprire il firewall del server all'app basata su 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
Configurare un database PostgreSQL
Il server PostgreSQL creato in precedenza è vuoto. Usare il comando seguente per creare un nuovo database.
az postgres db create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_NAME \
--server-name $AZ_DATABASE_SERVER_NAME \
--output tsv
Creare un utente non amministratore di PostgreSQL e concedere l'autorizzazione
Creare quindi un utente non amministratore e concedere tutte le autorizzazioni al database.
Nota
Per altre informazioni dettagliate sulla creazione di utenti PostgreSQL, vedere Creare utenti in Database di Azure per PostgreSQL.
Creare uno script SQL denominato create_ad_user.sql per la creazione di un utente non amministratore. Aggiungere il contenuto seguente e salvarlo in locale:
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
Usare quindi il comando seguente per eseguire lo script SQL per creare l'utente non amministratore di 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
Usare ora il comando seguente per rimuovere il file di script SQL temporaneo:
rm create_ad_user.sql
Creare un nuovo progetto Java
Usando l'IDE preferito, creare un nuovo progetto Java usando Java 8 o versione successiva e aggiungere un file pom.xml nella directory radice con il contenuto seguente:
<?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>
Questo file è un file Apache Maven che configura il progetto per l'uso di Java 8 e di un driver PostgreSQL recente per Java.
Preparare un file di configurazione per la connessione a Database di Azure per PostgreSQL
Creare un file src/main/resources/application.properties , quindi aggiungere il contenuto seguente:
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 proprietà url
di configurazione è ?sslmode=require
stata aggiunta per indicare al driver JDBC di usare TLS (Transport Layer Security) durante la connessione al database. L'uso di TLS è obbligatorio con Database di Azure per PostgreSQL ed è una buona procedura di sicurezza.
Creare un file SQL per generare lo schema del database
Si userà un file src/main/resources/schema.sql per creare uno schema di database. Creare il file, quindi aggiungere il contenuto seguente:
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
Codice dell'applicazione
Stabilire la connessione al database
Aggiungere quindi il codice Java che userà JDBC per archiviare e recuperare i dati dal server PostgreSQL.
Creare un file src/main/java/DemoApplication.java , quindi aggiungere il contenuto seguente:
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();
}
}
Questo codice Java userà application.properties e i file schema.sql creati in precedenza per connettersi al server PostgreSQL e creare uno schema che archivierà i dati.
In questo file è possibile notare che sono stati commentati metodi per inserire, leggere, aggiornare ed eliminare dati. Questi metodi verranno codificati nel resto di questo articolo e sarà possibile rimuovere il commento uno dopo l'altro.
Nota
Le credenziali del database vengono archiviate nelle user
proprietà e password
del file application.properties . Queste credenziali vengono usate durante l'esecuzione di DriverManager.getConnection(properties.getProperty("url"), properties);
, perché il file delle proprietà viene passato come argomento.
È ora possibile eseguire questa classe main con lo strumento preferito:
- Usando l'IDE, dovrebbe essere possibile fare clic con il pulsante destro del mouse sulla classe DemoApplication ed eseguirla.
- Usando Maven, è possibile eseguire l'applicazione usando il comando seguente:
mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication"
.
L'applicazione dovrà connettersi a Database di Azure per PostgreSQL, creare uno schema del database e quindi chiudere la connessione, come si vedrà nei log della console:
[INFO ] Loading application properties
[INFO ] Connecting to the database
[INFO ] Database connection test: demo
[INFO ] Create database schema
[INFO ] Closing database connection
Creare una classe di dominio
Creare una nuova classe Java Todo
accanto alla classe DemoApplication
e aggiungere il codice seguente:
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 +
'}';
}
}
Questa classe è un modello di dominio mappato alla tabella todo
creata durante l'esecuzione dello script schema.sql.
Inserimento di dati in Database di Azure per PostgreSQL
Nel file src/main/java/DemoApplication.java aggiungere il metodo seguente dopo il metodo main per inserire i dati nel database:
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();
}
È ora possibile rimuovere il commento dalle due righe seguenti nel metodo main
:
Todo todo = new Todo(1L, "configuration", "congratulations, you have set up JDBC correctly!", true);
insertData(todo, connection);
Se si esegue la classe main, si dovrebbe ottenere l'output seguente:
[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
Lettura dei dati da Database di Azure per PostgreSQL
Per verificare che il codice funzioni correttamente, leggere i dati inseriti in precedenza.
Nel file src/main/java/DemoApplication.java aggiungere il metodo seguente dopo il metodo insertData
per leggere i dati dal database:
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;
}
È ora possibile rimuovere il commento dalla riga seguente nel metodo main
:
todo = readData(connection);
Se si esegue la classe main, si dovrebbe ottenere l'output seguente:
[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
Aggiornamento dei dati in Database di Azure per PostgreSQL
Aggiornare quindi i dati inseriti in precedenza.
Sempre nel file src/main/java/DemoApplication.java aggiungere il metodo seguente dopo il metodo readData
per aggiornare i dati all'interno del database:
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);
}
È ora possibile rimuovere il commento dalle due righe seguenti nel metodo main
:
todo.setDetails("congratulations, you have updated data!");
updateData(todo, connection);
Se si esegue la classe main, si dovrebbe ottenere l'output seguente:
[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
Eliminazione dei dati in Database di Azure per PostgreSQL
Eliminare infine i dati inseriti in precedenza.
Sempre nel file src/main/java/DemoApplication.java aggiungere il metodo seguente dopo il metodo updateData
per eliminare i dati all'interno del database:
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);
}
È ora possibile rimuovere il commento dalla riga seguente nel metodo main
:
deleteData(todo, connection);
Se si esegue la classe main, si dovrebbe ottenere l'output seguente:
[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
Pulire le risorse
Congratulazioni. È stata creata un'applicazione Java che usa JDBC per archiviare e recuperare i dati da Database di Azure per PostgreSQL.
Per pulire tutte le risorse usate in questo argomento di avvio rapido, eliminare il gruppo di risorse con il comando seguente:
az group delete \
--name $AZ_RESOURCE_GROUP \
--yes