Systêxtil Connection (AppConnection)
A classe principal é AppConnection.
Por ela são feitas todas as operações envolvendo Connection, Statement, ResultSet etc.
A maior parte das operações requer que o objeto seja fechado ao fim, para liberar
Statements e ResulSets (cursores). Por isso, ele implementa AutoCloseable,
e é importante usá-lo dentro de um bloco try-with-resources - especialmente
se com ele forem executadas operações que podem
fazer retornos prematuros, como return, throw, break.
Se ocorrer erro de execução de SQL dentro do objeto AppConnection, esse objeto
é fechado automaticamente, e é lançada uma DebugException
contendo os detalhes do erro.
Existem métodos que estão documentados como não requerendo fechamento do objeto
(não precisam estar num bloco try-with-resources). São métodos
que fazem uma operação atômica em um comando SQL (só retornam após terem processado
o comando até o fim e fecham o objeto). São principalmente métodos que retornam
o resultado de um único registro, ou o método que insere um único registro sem
se importar com violação de chave única. Recomenda-se dar preferência a
esses métodos quando possível.
Histórico
Esta biblioteca foi criada há muito tempo atrás para facilitar a execução de comandos SQL usando JDBC. Por isso, ela torna possível fazer praticamente qualquer coisa com JDBC - mas também requer cuidado para fazer da forma correta e para não esquecer de fechar os cursores.
Com o tempo foram adicionadas melhorias para tornar mais fáceis algumas tarefas muito frequentes.
Agora é possível usar programação funcional (lambdas) para algumas tarefas.
Recursos usando programação funcional (lambdas)
Algumas operações usam lambdas e não requerem que o objeto AppConnection
seja fechado explicitamente (isto é garantido internamente). Recomendamos usar
essas operações quando possível, especialmente nas tarefas muito frequentes
exemplificadas a seguir:
String SQL = "select descricao from depositos where id = ?";
String nome;
// Obter a descrição, ou um texto padrão se não existir:
nome = new AppConnection(conn, SQL, id)
.map(c -> c.getString(1))
.orElse("Não encontrado.");
// Obter a descrição, ou lançar uma mensagem se não existir:
nome = new AppConnection(conn, SQL, id)
.map(c -> c.getString(1))
.orElseThrow(() -> new Exception("Depósito não encontrado"));
// Obter a descrição e usá-la imediatamente:
new AppConnection(conn, SQL, id)
.map(c -> c.getString(1))
.ifPresent(nome -> campo.setDescricao(nome));
// Lançar uma mensagem se encontrar um problema:
new AppConnection(conn, "select problema from problemas")
.ifPresentThrow(c -> new Exception("Foi encontrado um problema: "+c.getString(1)));
// Ler um objeto a partir de um registro:
Num numero = new AppConnection(conn, "select id, name from numbers where id = ?", id)
.map(c -> new Num(c.getInt(1), c.getString(2)))
.orElseThrow(() -> new Exception("Número não existe."));
// Processar vários registros, um a um:
int quantos = new AppConnection(conn, "select * from depositos where situacao <> 0")
.forEach(c -> {
int cod = c.getInt("codigo");
String desc = c.getString("descricao");
int situacao = c.getInt("situacao");
// Faça alguma coisa com tudo isso.
});
// Ler e processar registros usando stream:
// (As possibilidades são infinitas - isto é só um exemplo!)
String maiorQueUm = new AppConnection(conn, "SELECT * FROM NUMBERS")
.stream(stream -> {
return stream
.filter(cn -> cn.getInt(1) > 1)
.map(cn -> cn.getString(2))
.collect(Collectors.joining(", "));
});
assertEquals(maiorQueUm, "TWO, THREE");