Múltiplas conexões e bases - raialmeida/mindqa-db-commons GitHub Wiki

Múltiplas conexões e bases

É possível manter PostgreSQL, SQL Server, MySQL e Oracle no mesmo arquivo de configuração e consultar todos no mesmo teste. Cada conexão possui seu próprio tipo, servidor, credencial e base.

Ao configurar dois ou mais prefixos, como POSTGRESQL_* e SQLSERVER_*, defina DB_DEFAULT_CONNECTION se alguma operação usar a conexão padrão e não houver configuração simples DB_*. Esse seletor não é necessário quando todas as operações usam DatabaseService.connection("nome").

Antes de executar os exemplos, configure as conexões conforme a página Configuração por ambiente. Este documento mostra somente como selecionar os destinos pelos métodos da biblioteca; não repete credenciais nem propriedades de conexão.

Quatro conexões diferentes no mesmo teste

Neste cenário, cada nome seleciona um servidor diferente:

import io.mindqa.database.DatabaseService;

import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;

String id = "cliente-1";
String sql = "SELECT email FROM clientes WHERE id = ?";

List<Map<String, Object>> postgres = DatabaseService.connection("postgresql")
        .select(sql, id);
List<Map<String, Object>> sqlServer = DatabaseService.connection("sqlserver")
        .select(sql, id);
List<Map<String, Object>> mysql = DatabaseService.connection("mysql")
        .select(sql, id);
List<Map<String, Object>> oracle = DatabaseService.connection("oracle")
        .select(sql, id);

assertEquals(1, postgres.size());
assertEquals(1, sqlServer.size());
assertEquals(1, mysql.size());
assertEquals(1, oracle.size());
assertEquals("[email protected]", postgres.get(0).get("email"));
assertEquals("[email protected]", sqlServer.get(0).get("email"));
assertEquals("[email protected]", mysql.get(0).get("email"));
assertEquals("[email protected]", oracle.get(0).get("email"));

O teste pode comparar os valores retornados pelos quatro destinos. As consultas são independentes e não existe transação compartilhada entre os servidores.

Bases diferentes na mesma conexão

Use database(nome) quando o servidor e as credenciais forem os mesmos, mas a base de destino mudar:

import io.mindqa.database.DatabaseClient;
import io.mindqa.database.DatabaseService;

import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;

String id = "cliente-1";
String sql = "SELECT email FROM clientes WHERE id = ?";

DatabaseClient postgres = DatabaseService.connection("postgresql");

List<Map<String, Object>> clientes = postgres.database("qa_clientes")
        .select(sql, id);
List<Map<String, Object>> auditoria = postgres.database("qa_auditoria")
        .select(sql, id);

assertEquals(1, clientes.size());
assertEquals(1, auditoria.size());
assertEquals("[email protected]", clientes.get(0).get("email"));
assertEquals("[email protected]", auditoria.get(0).get("email"));

int atualizados = postgres.database("qa_clientes").execute(
        "UPDATE clientes SET email = ? WHERE id = ?",
        "[email protected]", id);
assertEquals(1, atualizados);

List<Map<String, Object>> clienteAtualizado = postgres.database("qa_clientes")
        .select("SELECT email FROM clientes WHERE id = ?", id);
assertEquals(1, clienteAtualizado.size());
assertEquals("[email protected]", clienteAtualizado.get(0).get("email"));

No Oracle, o nome informado em database() representa o service name da conexão Easy Connect e não altera o schema. No PostgreSQL e no MySQL, representa o nome do database usado na URL JDBC. No SQL Server, representa o database informado na propriedade databaseName.

Conexões e bases diferentes combinadas

O mesmo teste pode trocar conexão e base em cada chamada:

import io.mindqa.database.DatabaseService;

import java.util.List;
import java.util.Map;

String id = "cliente-1";
String sql = "SELECT email FROM clientes WHERE id = ?";

List<Map<String, Object>> principal = DatabaseService.connection("postgresql")
        .database("qa_clientes").select(sql, id);
List<Map<String, Object>> replica = DatabaseService.connection("sqlserver")
        .database("qa_replica").select(sql, id);
List<Map<String, Object>> loja = DatabaseService.connection("mysql")
        .database("qa_loja").select(sql, id);
List<Map<String, Object>> erp = DatabaseService.connection("oracle")
        .database("FREEPDB1").select(sql, id);

Essa abordagem permite validar replicação, consistência entre sistemas e integrações com ERP no mesmo fluxo de automação. Os registros e as tabelas precisam existir em cada destino, e o SQL deve respeitar o banco selecionado.

Métodos disponíveis

Use os métodos estáticos quando quiser trabalhar com a conexão padrão. Com várias conexões nomeadas e sem configuração simples, defina DB_DEFAULT_CONNECTION:

import io.mindqa.database.DatabaseService;

String id = "cliente-1";
String nome = "Cliente atualizado";
String sql = "SELECT email FROM clientes WHERE id = ?";
String sqlUpdate = "UPDATE clientes SET nome = ? WHERE id = ?";

DatabaseService.select(sql, id);
DatabaseService.execute(sqlUpdate, nome, id);
DatabaseService.database("qa_auditoria").select(sql, id);
DatabaseService.database("qa_auditoria").execute(sqlUpdate, nome, id);

DatabaseService.database(nome) troca somente a base da conexão padrão.

Use connection("nome") quando o teste precisar escolher explicitamente um destino. Reutilizando as variáveis do bloco anterior, o DatabaseClient retornado oferece os mesmos métodos:

import io.mindqa.database.DatabaseClient;
import io.mindqa.database.DatabaseService;

DatabaseClient banco = DatabaseService.connection("mysql");
banco.select(sql, id);
banco.execute(sqlUpdate, nome, id);
banco.database("qa_loja").select(sql, id);
banco.database("qa_loja").execute(sqlUpdate, nome, id);

select retorna uma lista de mapas, uma entrada por linha. execute retorna a quantidade de linhas afetadas; valide esse valor para confirmar que o registro esperado foi alterado ou removido. Falhas JDBC lançam DatabaseException e preservam a SQLException original como causa.