Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este artigo demonstra como criar uma aplicação de exemplo que utiliza Java e JDBC para armazenar e recuperar informação em Azure HorizonDB (Preview).
JDBC é a API padrão Java para ligação a bases de dados relacionais tradicionais.
Os passos deste artigo incluem autenticação PostgreSQL.
A autenticação PostgreSQL usa contas armazenadas no PostgreSQL, e tens de gerir tu próprio a rotação das palavras-passe.
Pré-requisitos
- Uma conta no Azure. Se não tiver uma, obtenha uma avaliação gratuita.
- Azure Cloud Shell ou CLI do Azure. Use o Azure Cloud Shell para ser autenticado automaticamente e ter acesso a todas as ferramentas de que precisa.
- Um Kit de Desenvolvimento Java suportado, versão 8 (incluído no Cloud Shell).
- A ferramenta de construção 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_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>
Substitua os placeholders pelos seguintes valores, que são usados ao longo deste artigo.
-
<YOUR_DATABASE_CLUSTER_NAME>: O nome do seu cluster do Azure HorizonDB, que deve ser único na sua subscrição e no seu grupo de recursos do Azure. -
<YOUR_DATABASE_NAME>: O nome da base de dados que está a usar dentro do seu cluster Azure HorizonDB. -
<YOUR_AZURE_REGION>: A região do Azure a ser usada. Podes usaraustraliaeastpor defeito, mas configura uma região mais próxima de onde vives. Você pode ver a lista completa de regiões disponíveis digitandoaz account list-locations. -
<YOUR_POSTGRESQL_ADMIN_PASSWORD>e<YOUR_POSTGRESQL_NON_ADMIN_PASSWORD>: A palavra-passe do seu cluster Azure HorizonDB. Essa palavra-passe deve ter pelo menos oito carateres. Os caracteres devem ser de três das seguintes categorias: letras maiúsculas inglesas, letras minúsculas inglesas, números (0-9) e caracteres não alfanuméricos (!, $, #, % e assim por diante). -
<YOUR_LOCAL_IP_ADDRESS>: O endereço IP do seu computador local, a partir do qual executa a sua aplicação Spring Boot. Uma forma conveniente de a encontrar é abrir whatismyip.akamai.com.
Em seguida, crie um grupo de recursos usando o seguinte comando:
az group create \
--name $AZ_RESOURCE_GROUP \
--location $AZ_LOCATION \
--output tsv
Criar um cluster Azure HorizonDB
Note
Não inclua qualquer informação pessoal, sensível ou confidencial nos nomes dos recursos (por exemplo, nome da tabela, nome da base de dados) e nas etiquetas de recursos. Os dados que insere nestes campos não são considerados dados do cliente.
As secções seguintes descrevem como criar e configurar o seu cluster de base de dados.
Criar um cluster Azure HorizonDB
Configurar utilizador de administrador
Primeiro, crie uma instância Azure HorizonDB gerida.
Note
Para informações mais detalhadas sobre a criação de Azure HorizonDB, veja Criar um 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
Este comando cria um pequeno cluster Azure HorizonDB.
Tem algum problema? Deixe-nos saber.
Configure uma regra de firewall para a sua instância do Azure HorizonDB
As instâncias do Azure HorizonDB são seguras por defeito. Eles têm um firewall que bloqueia todas as ligações de entrada. Para usar a sua base de dados, adicione uma regra de firewall que conceda ao seu endereço IP local acesso ao servidor da base de dados.
Como você configurou seu endereço IP local no início deste artigo, você pode abrir o firewall do servidor executando o seguinte 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
Se estiver a ligar-se ao seu cluster Azure HorizonDB a partir do Subsistema Windows para Linux (WSL) num computador Windows, precisa de adicionar o ID do host WSL ao seu firewall.
Obtenha o endereço IP da sua máquina anfitriã executando o seguinte comando em WSL:
cat /etc/resolv.conf
Copie o endereço IP que se segue ao termo nameserver, e depois 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 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
Criar uma base de dados Azure HorizonDB
Cria um script SQL chamado create_database.sql para criar uma nova base de dados no teu cluster. Adicione o seguinte conteúdo e guarde o ficheiro localmente:
cat << EOF > create_database.sql
CREATE DATABASE "$AZ_DATABASE_NAME";
EOF
Execute este comando para obter o seu domínio totalmente qualificado do HorizonDB Azure e copie o valor clusterName:
az horizondb show \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_CLUSTER_NAME \
--query "{clusterName:properties.fullyQualifiedDomainName, adminUser:properties.administratorLogin}" \
--output table
Copie o clusterName valor e use-o no seguinte comando:
AZ_HORIZONDB_FQDN=<the-copied-clusterName-value>
Depois, execute o seguinte comando para executar o script SQL e criar a sua base de dados:
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
Agora, execute o seguinte comando para eliminar o ficheiro de script SQL temporário:
rm create_database.sql
Crie um utilizador não administrador do Azure HorizonDB e conceda permissões
De seguida, cria um utilizador não administrador e concede todas as permissões à base de dados.
Cria um script SQL chamado create_user.sql para criar um utilizador não administrador. Adicione o seguinte conteúdo e guarde o ficheiro 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
Depois, execute o seguinte comando para executar o script SQL e criar o utilizador não administrador do 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
Agora, execute o seguinte comando para eliminar o ficheiro de script SQL temporário:
rm create_user.sql
Criar um novo projeto Java
Usando o seu IDE favorito, crie um novo projeto Java usando Java 8 ou posterior. Adicione um ficheiropom.xml na pasta 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>
</dependencies>
</project>
Este arquivo é um arquivo Apache Maven que configura seu projeto para usar:
- Java 8
- Um driver PostgreSQL recente para Java
Preparar um ficheiro de configuração para ligar ao Azure HorizonDB
Crie um ficheiro src/main/resources/application.properties e adicione o seguinte conteúdo:
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
A propriedade de configuração url inclui ?sslmode=require para garantir que o driver JDBC use TLS (Transport Layer Security) ao conectar-se à base de dados. O Azure HorizonDB requer TLS, e é uma prática de segurança recomendada.
Criar um arquivo SQL para gerar o esquema de banco de dados
Usa um ficheiro src/main/resources/schema.sql para criar um esquema de base de dados. Crie esse ficheiro com o seguinte conteúdo:
DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id SERIAL PRIMARY KEY, description text, details text, done BOOLEAN);
Codificar a aplicação
Conectar-se ao banco de dados
De seguida, adicione o código Java que usa JDBC para armazenar e recuperar dados da sua instância do Azure HorizonDB.
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();
}
}
Tem algum problema? Deixe-nos saber.
Este código Java utiliza os ficheiros application.properties e os ficheiros schema.sql que criámos anteriormente, para se ligar à instância Azure HorizonDB e criar um esquema que armazena os nossos dados.
Neste ficheiro, pode ver que comentámos métodos para inserir, ler, atualizar e eliminar dados: vamos codificar esses métodos no resto deste artigo, e poderá retirá-los dos comentários um após o outro.
Note
As credenciais do banco de dados são armazenadas nas propriedades de usuário e senha do arquivo application.properties . Essas credenciais são usadas quando DriverManager.getConnection(properties.getProperty("url"), properties); é executado, pois o ficheiro de propriedades é passado como um argumento.
Agora você pode executar esta classe principal com sua ferramenta favorita:
- Usando seu IDE, você deve ser capaz de clicar com o botão direito do mouse na classe DemoApplication e executá-la.
- Usando o Maven, você pode executar o aplicativo executando:
mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication".
A aplicação deve ligar-se à instância do Azure HorizonDB, criar um esquema de base de dados e depois fechar a ligação, como deve ver nos registos da consola:
[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 nova Todo classe Java, ao lado da DemoApplication classe, 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 todo na tabela que você criou ao executar o script schema.sql .
Inserir dados no Azure HorizonDB
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 pode descomentar as duas linhas seguintes 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 agora 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 Azure HorizonDB
Vamos ler os dados inseridos anteriormente, para validar que o nosso código funciona corretamente.
No arquivo src/main/java/DemoApplication.java, após o insertData método, 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 descomentar a seguinte linha no main método:
todo = readData(connection);
A execução da classe principal agora 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 os dados em Azure HorizonDB
Vamos atualizar os dados que inserimos anteriormente.
Ainda no arquivo src/main/java/DemoApplication.java , após o readData método, adicione o seguinte método para atualizar dados dentro do 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 pode descomentar as duas linhas seguintes no método main.
todo.setDetails("congratulations, you have updated data!");
updateData(todo, connection);
A execução da classe principal agora 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
Eliminar dados no Azure HorizonDB
Por fim, vamos apagar os dados que inserimos anteriormente.
Ainda no arquivo src/main/java/DemoApplication.java , após o updateData método, adicione o seguinte método para excluir dados dentro do 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 descomentar a seguinte linha no main método:
deleteData(todo, connection);
A execução da classe principal agora 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
Limpeza de recursos
Parabéns! Criou uma aplicação Java que usa JDBC para armazenar e recuperar dados de uma instância do Azure HorizonDB.
Para limpar todos os recursos usados durante este início rápido, exclua o grupo de recursos usando o seguinte comando:
az group delete \
--name $AZ_RESOURCE_GROUP \
--yes