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");