Dao

Olá pessoal,

Já vi várias implementações de DAO, porém acho que nunca cheguei a uma conslusão de qual seria a melhor.
Algumas inplementações de exemplo:

  • O DAO recebe no seu construtor um connection
  • as SQL´s são criadas em atributos da classe (constantes), para posteriormente serem usados com um preparedStatement
  • existe um BO na classe que é setado antes de chamar cada método

outro exemplo seria:

  • Um DAO é criado e ele se vira para achar uma connection (herança)
  • as SQL´s são criadas dentro de cada método dinamicamente, conforme os atributos do BO que estivere preenchidos, ai então usa-se statement mesmo ou PprdStmt.
  • o BO é passado a cada chamada de método

outro exemplo seria:

  • combinando estes dois primeiros, com as SQL guardadas em arquivos de properties ou em arquivos xml

ahhh e por ai vai…

Bom, com a experiência que vcs já tem, qual seria uma boa definição de um DAO!

ps: please, não me venha com hibernate…

é mais a título de curiosidade mesmo! Como costumam usar?

abraços!

cara,
depende muito, cada um vai te dar uma opinião…
eu particularmente quando preciso usar DAO, faço ele pegar a conexão de uma classe que é um singleton, que pode retornar uma unica conexão ou retornar uma conexão de um pool, dependendo do tamanho do projeto.

[]'s

Aqui tem um exemplo:
http://java.sun.com/blueprints/patterns/DAO.html

[]'s

Dá uma olhada neste material também
http://www-106.ibm.com/developerworks/java/library/j-dao/

[]s, Welington B. Souza

Sem Hibernate eu já fiz de duas maneiras.

1- Com Factory pra pegar o tipo de banco, conexoes, etc e gerando as consultas dinamicamente.

2- Usando DI pra setar, conexao, transacao, etc e nesse caso buscava as consultas em arquivos xml.

Das duas gostei mais da segunda implementacao.

]['s

Valeu pelo material.

Embora as opiniões variem, gostaria de saber quais soluções vcs implementam. Que tipo de DAO usaria para um certo caso…
Só gostaria de saber como é que o pessoal costuma usar, para determinados casos. Era mais ou menos isso que queria saber.

Mas valew!

Abraços!

Usar uma Factory para construir os DAOs é uma boa forma de passar os coadjuvantes necessarios.

As vezes que programei DAOs com JDBC usei um contexto, vinculado à thread corrente (ThreadLocal), que disponibilizava os partícipes necessarios (conexão, user-transaction, etc). Acho essa a melhor maneira de gerenciar esse tipo de recurso. Para mim IoC/DI resolve um problema ortogonal a esse.

Os comandos SQLs sempre em arquivos .properties. Isso eu vejo como indispensavel. Facilita em muito o desenvolvimento e a manutenção do sistema. Colocar queries de 10 linhas no código java só se justifica se você recebe por LoC produzidas.

A idéia de ter que ‘settar’ o BO anter de cada chamada é furada, cria acoplamento temporal atoa.

Eu acho que a parte mais complicada de escrever DAOs são as pesquisas, principalmente as com um número enorme de parâmentros opcionais.

Para isso tem 3 padrões que quebram um belo galho:

:arrow: Builder, para gerar o SQL dinâmicamente e passar os parametros para os prepared statements, faça uma vez só o trabalho de validar os valores, evitar sql injection e outras chatisses do tipo.

:arrow: Query by example, esse é legal para construir um mecanismo mais genérico de consulta onde todas propriedades do BO são possiveis criterios.

:arrow: Query object, esse pode ser visto de 2 formas, como um refactoring de converter uma lista de parâmetros em uma classe ou como o objeto fazendo o papel de Coordinator dentro do padrão Builder. De qualquer forma deixa mais claro consultas mais complicadas.

Uma coisa importantíssima a ser frisada é um erro super comum que eu já fiz e vi muitos projetos cometendo; um DAO não deve gerenciar transações, pois essa é uma responsabilidade que somente um layer abaixo dele pode fazer corretamente por conhecer corretamente a unidade-de-trabalho que o DAO tá participando.

Eu particularmente prefiro criar uma classe Transaction com uma variável ThreadLocal onde eu seto minha conexão.

E nos DAOs eu uso Transaction.currentConnection() pois sempre irá retornar a mesma conexão.

Ex.:

Transaction.start(); //Recupero um conexão e coloco na ThreadLocal. (Fora do DAO, geralmente em um Interceptor do WW) Transaction.currentConnection(); //Para recuperar a conexão dentro do DAO, em quantos DAOs eu precisar... Transaction.close(); //Fecho a conexão e removo da ThreadLocal. (Tambem fora do DAO, no mesmo Interceptor que iniciou a transação)

Acho que assim fica bem claro…
:wink:

[quote=louds]Usar uma Factory para construir os DAOs é uma boa forma de passar os coadjuvantes necessarios.

As vezes que programei DAOs com JDBC usei um contexto, vinculado à thread corrente (ThreadLocal), que disponibilizava os partícipes necessarios (conexão, user-transaction, etc). Acho essa a melhor maneira de gerenciar esse tipo de recurso. Para mim IoC/DI resolve um problema ortogonal a esse.

Os comandos SQLs sempre em arquivos .properties. Isso eu vejo como indispensavel. Facilita em muito o desenvolvimento e a manutenção do sistema. Colocar queries de 10 linhas no código java só se justifica se você recebe por LoC produzidas.

A idéia de ter que ‘settar’ o BO anter de cada chamada é furada, cria acoplamento temporal atoa.
[/quote]

Hey louds,

não consegui abstrair sua idéia aqui. Como ficaria essa factory?! De onde viria o BO que ela mandaria para o DAO? ou o DAO recupera sempre esse BO de algum lugar?

Quanto a Thread citada por vc e pelo VOLNEI, esta seria tipo um Singleton, ou seria mais como um pool de conexoes? Se eu tiver muita concorrência, não ficaria meio inviável essa thread?

Abradeço a ajuda!

Abraços!

[quote=jujo]
Quanto a Thread citada por vc e pelo VOLNEI, esta seria tipo um Singleton, ou seria mais como um pool de conexoes? Se eu tiver muita concorrência, não ficaria meio inviável essa thread?

Abradeço a ajuda!

Abraços![/quote]

Não jujo, não é como o singleton, apenas você garante que a uma thread vai sempre usar a mesma conexão. Quanto a concorrência, não há com que se preocupar cada request/acesso é feito por uma thread diferente.

:wink:

[quote=volnei]Eu particularmente prefiro criar uma classe Transaction com uma variável ThreadLocal onde eu seto minha conexão.

E nos DAOs eu uso Transaction.currentConnection() pois sempre irá retornar a mesma conexão.

Ex.:

Transaction.start(); //Recupero um conexão e coloco na ThreadLocal. (Fora do DAO, geralmente em um Interceptor do WW) Transaction.currentConnection(); //Para recuperar a conexão dentro do DAO, em quantos DAOs eu precisar... Transaction.close(); //Fecho a conexão e removo da ThreadLocal. (Tambem fora do DAO, no mesmo Interceptor que iniciou a transação)

Acho que assim fica bem claro…
:wink: [/quote]

Volnei,
Achei bastante interessante este código que você postou, mas confesso não ficou muito claro para mim. A solução que eu criei, que não achei que ficou muito bonita, mas pelo menos bastante prática e funcional, foi criar em cada método da interface ‘manager’ a entrada de um atributo connection, que se for o caso de uma transação, uma conexão entra como parâmetro no método, se não, a conexão vai nula. Assim: “manager.getUserByAlias(null, form.getAlias());” . Realmente funciona muito bem, com algumas outras implementaçõeszinhas, mas como eu disse, achei que não ficou muito bonito.
Gostaria que explicasse melhor este seu código e o funcionamento desta thead mencionada.
Thanks,

A grosso modo:

ThreadLocal é uma classe da API Java armazena um atributo que só pode ser acessado pela thread corrente, assim se você colocar uma conexão como atributo somente a trhead que está executando vai enchergá-la. Isso é bem característico do controle de transações.

Na minha classe Transaction eu adiciono essa TrheadLocal e coloco nela uma conexão.
Através de métodos estáticos eu recupero a conexão (armazenada na threadLocal) e trabalho com ela…
Ao final da transação eu fecho a conexão e removo da thread local…

:wink:

Como criar sempre varia com oe stilo da aplicação, mais duas dicas:

1 - Sim, use Factories (ou IoC antes que o cv leia…)
2 - Se um dao criar outro, pelo amor de Zahl, passe a conexão para ele. Já vi uma estrutura OO perfeita onde uma operação simples utilizava 3 conexões difrentes, uma para cada DAO, e nenhum processamento concorrente.

[]s

Ok, obrigado. Essa ThreadLocal eu ainda não conhecia e me pareceu ser uma grande solução. Vou dar uma pesquisada nisso.
Se alguém souber de alguma dica de site que tenha um exemplo de código desse eu agradeço.

Oi Gustavo…

Olha… um lugar onde você pode achar um exemplo do ThreadLocal é no Livro Hibernate In Action! Mas ao invés deles estarem controlando connections, eles controlam sessões e transações. Se não me engano você poderá encontrar no capítulo 8. Mas ao invés de comprar o livro, entre no site www.manning.com e abaixe o código fonte dos exercícios do livro, e veja por si próprio o ThreadLocal!

Tambpem tem um pattern que representa essa organização usando ThreadLocal, mas agora não me recordo o nome.

Com relação aos DAO’s, eu costumo passar por parametro ou retornar apenas TO (ou VO). Já que TO é apropriado para transporte de dados entre as camadas do sistema. Mas isso é pessoal, pois considero o DAO e Factorys de DAO como uma camada de integração, como apresentado no Livro Core J2EE Patterns!

Na revista Java Magazine do mês passado teve uma matéria muito boa sobre DAO, Abstract Factory e FActory Method. Valeu muito a pena mesmo!

Só isso, por enquanto!
Um Abraço!

Ok, valeu Thiago!

Vi depois que mais acima o (wbsousa) passou um link interessante sobre DAO:
http://www-106.ibm.com/developerworks/java/library/j-dao/. Achei interessante a tal de JTA connection, que faria semelhante esquema sugerido pelo volney, ou seja:

tx.begin(); // start the transaction dao.createWarehouseProfile(profile); dao.updateWarehouseStatus(id1, status1); dao.updateWarehouseStatus(id2, status2); tx.commit(); // end the transaction
Mas que, no entanto, seria necessário que o JDBCdriver utilizado implementasse javax.sql.XADataSource, javax.sql.XAConnection, and javax.sql.XAResource interfaces, o que me pareceu uma preocupação a mais. Alguém poderia fazer algum comentário a respeito da utilização do JTA para controle de transações?

Depende do caso.

DTO é um objeto sem significado no seu sistema, uma bela duma gambiarra, e deve ser usado apra passar dados entre camadas separadas (ou até na mesma camada), onde “separadas” significa que o custo de passar informações entre elas é alto, como nós diferentes em uma rede.

Não use DTOs dentro de uma mesma JVM.

Mais uma vez, uma boa leitura é este artigo.

Não acredite 100% nesse livro. Muito EJB hype.

[]s

[quote=Gustavo Tavares Seixas]
tx.commit(); // end the transaction[/code]
Mas que, no entanto, seria necessário que o JDBCdriver utilizado implementasse javax.sql.XADataSource, javax.sql.XAConnection, and javax.sql.XAResource interfaces, o que me pareceu uma preocupação a mais. Alguém poderia fazer algum comentário a respeito da utilização do JTA para controle de transações?[/quote]

Use JTA somente se você tem transações distribudas e precisa de 2PC. Caso contrario evite.