Início rápido: Usar o Java e o JDBC com o Banco de Dados do Azure para PostgreSQL – Servidor Flexível
APLICA-SE A: Banco de dados do Azure para PostgreSQL — Servidor Flexível
Este artigo demonstra como criar um aplicativo de exemplo que usa o Java e o JDBC para armazenar e recuperar informações no Servidor flexível do Banco de Dados do Azure para PostgreSQL.
O JDBC é a API Java padrão para se conectar a bancos de dados relacionais tradicionais.
Neste artigo, vamos incluir dois métodos de autenticação: autenticação do Microsoft Entra e autenticação do PostgreSQL. A guia Sem senha mostra a autenticação do Microsoft Entra e a guia Senha mostra a autenticação do PostgreSQL.
A autenticação do Microsoft Entra é um mecanismo de conexão do Banco de Dados do Azure para PostgreSQL que usa as identidades definidas no Microsoft Entra ID. Com a autenticação do Microsoft Entra, você pode gerenciar as identidades de usuários do banco de dados e outros serviços da Microsoft em uma só localização central, o que simplifica o gerenciamento de permissões.
A autenticação PostgreSQL usa contas armazenadas no PostgreSQL. Se você optar por usar senhas como credenciais para as contas, essas credenciais serão armazenadas na tabela user
. Como essas senhas são armazenadas no PostgreSQL, você precisará gerenciar a rotação das senhas por conta própria.
Pré-requisitos
- Uma conta do Azure. Se você não tiver uma, obtenha uma avaliação gratuita.
- Azure Cloud Shell ou CLI do Azure. É recomendável usar o Azure Cloud Shell para que o logon seja feito automaticamente e você tenha acesso a todas as ferramentas necessárias.
- Um Java Development Kit compatível, versão 8 (incluído no Azure Cloud Shell).
- A ferramenta de build Apache Maven.
Preparar o ambiente de trabalho
Primeiro, use o seguinte comando para configurar algumas variáveis de ambiente.
export AZ_RESOURCE_GROUP=database-workshop
export AZ_DATABASE_SERVER_NAME=<YOUR_DATABASE_SERVER_NAME>
export AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
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)
Substitua os espaços reservados pelos seguintes valores, que são usados em todo este artigo:
<YOUR_DATABASE_SERVER_NAME>
: o nome da sua instância de servidor flexível do Banco de Dados do Azure para PostgreSQL, que deve ser exclusivo no Azure.<YOUR_DATABASE_NAME>
: o nome do banco de dados da instância de servidor flexível do Banco de Dados do Azure para PostgreSQL, que deve ser exclusivo no Azure.<YOUR_AZURE_REGION>
: a região do Azure a ser usada. Você pode usareastus
por padrão, mas é recomendável configurar uma região mais próxima de onde você mora. Você pode ver a lista completa de regiões disponíveis ao digitaraz account list-locations
.<YOUR_POSTGRESQL_AD_NON_ADMIN_USERNAME>
: o nome de usuário da instância de servidor flexível do Banco de Dados do Azure para PostgreSQL. Verifique se o nome de usuário é válido no locatário do Microsoft Entra.<YOUR_LOCAL_IP_ADDRESS>
: O endereço IP do computador local, do qual você executará o aplicativo Spring Boot. Uma forma conveniente de encontrá-lo é abrir whatismyip.akamai.com.
Importante
Ao definir <YOUR_POSTGRESQL_AD_NON_ADMIN_USERNAME>
, o nome de usuário já precisa existir no seu locatário do Microsoft Entra ou você não poderá criar um usuário do Microsoft Entra no banco de dados.
Em seguida, crie um grupo de recursos usando o seguinte comando:
az group create \
--name $AZ_RESOURCE_GROUP \
--location $AZ_LOCATION \
--output tsv
Criar uma instância de servidor flexível do Banco de Dados do Azure para PostgreSQL
As seções a seguir descrevem como criar e configurar a instância do banco de dados.
Criar uma instância de servidor flexível do Banco de Dados do Azure para PostgreSQL e configurar um usuário administrador
A primeira coisa que você cria é uma instância gerenciada de servidor flexível do Banco de Dados do Azure para PostgreSQL.
Observação
Você pode ler informações mais detalhadas sobre como criar instâncias de servidor flexível do Banco de Dados do Azure para PostgreSQL em Criar uma instância de servidor flexível do Banco de Dados do Azure para PostgreSQL usando o portal do Azure.
Se você estiver usando a CLI do Azure, execute o seguinte comando para garantir que ele tenha permissão suficiente:
az login --scope https://graph.microsoft.com/.default
Execute o comando a seguir para criar o servidor:
az postgres flexible-server create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_SERVER_NAME \
--location $AZ_LOCATION \
--yes \
--output tsv
Para configurar um administrador do Microsoft Entra depois de criar o servidor, siga as etapas em Gerenciar funções do Microsoft Entra no Banco de Dados do Azure para PostgreSQL – Servidor Flexível.
Importante
Ao configurar um administrador, um novo usuário com privilégios de administrador completo é adicionado ao banco de dados do Azure da instância de servidor flexível do Banco de Dados do Azure para PostgreSQL. Você pode criar vários administradores do Microsoft Entra por instância de servidor flexível do Banco de Dados do Azure para PostgreSQL.
Está tendo algum problema? Queremos saber.
Configure uma regra de firewall para a sua instância de servidor flexível do Banco de Dados do Azure para PostgreSQL
As instâncias de servidor flexível do Banco de Dados do Azure para PostgreSQL são protegidas por padrão. Elas têm um firewall que não permite nenhuma conexão de entrada. Para usar o banco de dados, você precisa adicionar uma regra de firewall que permitirá que o endereço IP local acesse o servidor de banco de dados.
Como você configurou seu endereço IP local no início deste artigo, abra o firewall do servidor executando o seguinte comando:
az postgres flexible-server firewall-rule create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_SERVER_NAME \
--rule-name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip \
--start-ip-address $AZ_LOCAL_IP_ADDRESS \
--end-ip-address $AZ_LOCAL_IP_ADDRESS \
--output tsv
Se você estiver se conectando à instância de servidor flexível do Banco de Dados do Azure para PostgreSQL do Subsistema do Windows para Linux (WSL) em um computador Windows, precisará adicionar a ID do host WSL ao firewall.
Obtenha o endereço IP do computador host executando o seguinte comando no WSL:
cat /etc/resolv.conf
Copie o endereço IP após o termo nameserver
e use o seguinte comando para definir uma variável de ambiente para o endereço IP WSL:
AZ_WSL_IP_ADDRESS=<the-copied-IP-address>
Em seguida, use o seguinte comando para abrir o firewall do servidor para seu aplicativo baseado em WSL:
az postgres flexible-server firewall-rule create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_SERVER_NAME \
--rule-name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip \
--start-ip-address $AZ_WSL_IP_ADDRESS \
--end-ip-address $AZ_WSL_IP_ADDRESS \
--output tsv
Configurar um banco de dados de servidor flexível do Banco de Dados do Azure para PostgreSQL
Crie um novo banco de dados usando o seguinte comando:
az postgres flexible-server db create \
--resource-group $AZ_RESOURCE_GROUP \
--database-name $AZ_DATABASE_NAME \
--server-name $AZ_DATABASE_SERVER_NAME \
--output tsv
Criar um usuário não administrador de servidor flexível do Banco de Dados do Azure para PostgreSQL e conceder permissão
Em seguida, crie um usuário não administrador e conceda a ele todas as permissões para o banco de dados.
Observação
Você pode ler informações mais detalhadas sobre como gerenciar os usuários do servidor flexível do Banco de Dados do Azure para PostgreSQL em Gerenciar usuários do Microsoft Entra – Banco de Dados do Azure para PostgreSQL – Servidor Flexível.
Crie um script SQL chamado create_ad_user.sql para criar um usuário não administrador. Adicione o seguinte conteúdo e salve-o localmente:
cat << EOF > create_ad_user.sql
select * from pgaadauth_create_principal('$AZ_POSTGRESQL_AD_NON_ADMIN_USERNAME', false, false);
EOF
Em seguida, use o seguinte comando para executar o script SQL, a fim de criar o usuário não administrador do Microsoft Entra:
psql "host=$AZ_DATABASE_SERVER_NAME.postgres.database.azure.com user=$CURRENT_USERNAME dbname=postgres port=5432 password=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken) sslmode=require" < create_ad_user.sql
Agora, use o seguinte comando para remover o arquivo de script SQL temporário:
rm create_ad_user.sql
Criar um projeto Java
Usando seu IDE favorito, crie um projeto Java usando Java 8 ou superior e adicione um arquivo pom.xml em seu diretório raiz com o seguinte conteúdo:
<?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>
Esse arquivo é um Apache Maven que configura o projeto a ser usado:
- Java 8
- Um driver PostgreSQL recente para Java
Preparar um arquivo de configuração para se conectar ao servidor flexível do Banco de Dados do Azure para PostgreSQL
Crie um arquivo src/main/resources/application.properties e adicione o seguinte conteúdo:
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}
EOF
Observação
A propriedade de configuração url
tem ?serverTimezone=UTC
acrescentado para instruir o driver JDBC a usar o protocolo TLS ao se conectar ao banco de dados. É obrigatório usar o TLS com o servidor flexível do Banco de Dados do Azure para PostgreSQL e é uma boa prática de segurança.
Criar um arquivo SQL para gerar o esquema de banco de dados
Você usará um arquivo src/main/resources/schema.sql
para criar um esquema de banco de dados. Crie esse arquivo com o seguinte conteúdo:
DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id SERIAL PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BOOLEAN);
Codificar o aplicativo
Conectar-se ao banco de dados
Em seguida, adicione o código Java que usará o JDBC para armazenar e recuperar os dados da instância de servidor flexível do Banco de Dados do Azure para PostgreSQL.
Crie um arquivo src/main/java/DemoApplication.java e adicione o seguinte conteúdo:
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();
}
}
Está tendo algum problema? Queremos saber.
Esse código Java usará o application.properties e os arquivos schema.sql que criamos anteriormente, a fim de se conectar à instância de servidor flexível do Banco de Dados do Azure para PostgreSQL e criar um esquema que armazenará nossos dados.
Nesse arquivo, você pode ver que comentamos os métodos para inserir, ler, atualizar e excluir dados: codificaremos esses métodos no restante deste artigo e você poderá remover as marcas de comentários uma após a outra.
Observação
As credenciais de banco de dados são armazenadas nas propriedades user e password no arquivo application.properties. Essas credenciais são usadas durante a execução de DriverManager.getConnection(properties.getProperty("url"), properties);
, pois o arquivo de propriedades é passado como um argumento.
Agora, você pode executar esta classe principal com a sua ferramenta favorita:
- Usando o IDE, você deve clicar com o botão direito do mouse na classe DemoApplication e executá-la.
- Usando o Maven, você pode executar o aplicativo por meio do:
mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication"
.
O aplicativo deve se conectar à instância de servidor flexível do Banco de Dados do Azure para PostgreSQL, criar um esquema de banco de dados e fechar a conexão, como você vê nos logs do console:
[INFO ] Loading application properties
[INFO ] Connecting to the database
[INFO ] Database connection test: demo
[INFO ] Create database schema
[INFO ] Closing database connection
Criar uma classe de domínio
Crie uma classe Java Todo
, ao lado da classe DemoApplication
e adicione o seguinte 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 +
'}';
}
}
Essa classe é um modelo de domínio mapeado na tabela todo
que você criou ao executar o script schema.sql.
Inserir dados no servidor flexível do Banco de Dados do Azure para PostgreSQL
No arquivo src/main/java/DemoApplication.java, após o método principal, adicione o seguinte método para inserir dados no banco de dados:
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();
}
Agora você pode remover a marca de comentário das seguintes duas linhas no método main
:
Todo todo = new Todo(1L, "configuration", "congratulations, you have set up JDBC correctly!", true);
insertData(todo, connection);
A execução da classe principal deve produzir a seguinte saída:
[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
Ler dados do servidor flexível do Banco de Dados do Azure para PostgreSQL
Vamos ler os dados inseridos anteriormente para validar se o nosso código funciona corretamente.
No arquivo src/main/java/DemoApplication.java, após o método insertData
, adicione o seguinte método para ler dados do banco de dados:
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;
}
Agora você pode remover a marca de comentário da seguinte linha no método main
:
todo = readData(connection);
A execução da classe principal deve produzir a seguinte saída:
[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
Atualizar dados no servidor flexível do Banco de Dados do Azure para PostgreSQL
Vamos atualizar os dados que inserimos anteriormente.
Ainda no arquivo src/main/java/DemoApplication.java, após o método readData
, adicione o seguinte método para atualizar os dados no banco de dados:
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);
}
Agora você pode remover a marca de comentário das seguintes duas linhas no método main
:
todo.setDetails("congratulations, you have updated data!");
updateData(todo, connection);
A execução da classe principal deve produzir a seguinte saída:
[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
Excluir dados no servidor flexível do Banco de Dados do Azure para PostgreSQL
Por fim, vamos excluir os dados que inserimos anteriormente.
Ainda no arquivo src/main/java/DemoApplication.java, após o método updateData
, adicione o seguinte método para excluir os dados no banco de dados:
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);
}
Agora você pode remover a marca de comentário da seguinte linha no método main
:
deleteData(todo, connection);
A execução da classe principal deve produzir a seguinte saída:
[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
Limpar os recursos
Parabéns! Você criou um aplicativo Java que usa o JDBC para armazenar e recuperar dados do servidor flexível do Banco de Dados do Azure para PostgreSQL.
Para limpar todos os recursos usados durante este guia de início rápido, exclua o grupo de recursos usando o seguinte comando:
az group delete \
--name $AZ_RESOURCE_GROUP \
--yes