Qual a diferença entre JDBC e JDBI?

Recentemente um colega meu me indicou o usou de JDBI para substituir um ORM. ORM é bom para quem trabalha com múltiplos banco de dados e necessita colocar a mesma aplicação para consumir diferentes bancos de dados. Essa facilidade tem um custo, o custo de performance, pois as ferramentas de ORM precisam converter as chamadas SQL do framework para chamadas que o banco compreende, ou semelhante a nativa.

Então, porque ao invés de não se realizar direto a chamada de JDBC e não tivesse um framework que agilize meu desenvolvimento, mas não comprometa a performance?

Pensando nisso, a galera criou o JDBI, não é nova, tem desde 2004, mas eu só vim descobrir recentemente.

jDBI é uma biblioteca construída em cima de JDBC. JDBC funciona muito bem, mas geralmente parece otimizar para os fornecedores de banco de dados (escritores drivers). jDBI tenta expor a mesma funcionalidade, mas em uma API otimizada para os desenvolvedores.

É nível muito mais baixo do que um ORM como Hibernate ou JPA. A biblioteca é semelhante ao MyBatis (sucessora bifurcada para iBATIS).

jDBI suporta duas APIs estilo, um estilo velho, que se parece com:

List<AlgumaClasse> r = h.createQuery("select * from algo where id = :id and nome = :nome")
.bind("nome", "andre")
.bind("id", 1)
.map(AlgumaClasse.class)
.list();

E o estilo novo da API SQL objeto, que trabalha de uma forma reflexiva  e realmente abstraindo o JDBC:

interface NovoAPISQL
{
@SqlUpdate("insert into algo (id, nome) values (:id, :nome)")
int insert(@Bind("id") int id, @Bind("nome") String nome);

@SqlQuery("select id, nome from algo where id = :id")
AlgumaClasse findById(@Bind("id") long id);
}

A biblioteca tem uma boa referência (javadoc) e documentação estilo tutorial em http://jdbi.org/.

Concluindo

Outro lado interessante é que a comunidade trabalha bastante em melhorias e correções nela, por ser open source.
Vale a pena pensar se seu time ou seu projeto não merece ganhar uma produtividade no trabalho com tarefas de DAO.

Meu github: https://github.com/andremrezende

Anúncios

Utilizar datasource no log4j

Passei por um perrengue para descobrir como fazer o log ser persistido no banco de um jndi configurado.
Após passar por esse trabalho todo, do qual tive que ler várias documentações, pretendo descrever passo a passo esse processo que não é nada complicado.

Não quero descrever o uso do LOG4J ou sua finalidade, e sim ser compartilhar o uso de um novo appender do qual obtém uma conexão de banco de dados que foi configurado em seu servidor de aplicação.

Crie sua classe appender, pode ser conforme abaixo:

package br.com.rezende.log4j.appender;

import java.sql.Connection;
import java.sql.SQLException;
import javax.faces.context.FacesContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.apache.log4j.jdbc.JDBCAppender;
import org.apache.log4j.spi.LoggingEvent;

public class MeuJDBCAppender extends JDBCAppender {

private static Logger LOGGER = Logger.getLogger(NGSAppender.class);
private DataSource dataSource;
private static String dataSourceJNDIName;
private static Context context;

/**
* Inicializa o contexto e o datasource.
*/
static {
   try {
    context = new InitialContext();
    dataSourceJNDIName = "jdbc/DS";
   }catch (NamingException e) {
    LOGGER.error(e.getMessage(), e);
   }
}

/**
* Obtém o nome do datasource configurado no Servidor de aplicações.
*
* @return Connection
*/
public Connection getConnection() throws SQLException {
 if (this.dataSource == null) {
  if (this.getDataSourceJNDIName() == null) {
  LOGGER.error("Nome do datasource está vazio.");
  return null;
 }
 try {
  this.dataSource = (DataSource) context.lookup(this
  .getDataSourceJNDIName());
 } catch (NamingException e) {
  LOGGER.error("Problema em obter o datasource");
  throw new SQLException(e);
 }
}
  try {
    return this.dataSource.getConnection();
  } catch (SQLException e) {
    LOGGER.error("Existe problema em obter um nome de datasource.");
    throw e;
  }
}

  public String getDataSourceJNDIName() {
    return dataSourceJNDIName;
  }

}

Mapeie na sua propriedade seu novo appender dentro do log4j.properties:


log4j.rootCategory=ERROR, JDBC, Console

# Console appender
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n
# JDBC Database
log4j.appender.JDBC = br.com.rezende.log4j.appender.MeuJDBCAppender
log4j.appender.JDBC.layout=org.apache.log4j.PatternLayout

Para inserir os valores em seu banco, visualize o próximo post, pois é necessário criar a tabela de log e formatar o seu INSERT para persistir a respectiva informação de stacktrace.

Abraços,
André Rezende