Olá. Estou tendo uma dúvida em relação ao padrão DAO em relação a modelagem e gostaria de saber se alguém ja resolveu isso.
Por exemplo, imagine que eu tenho no banco de dados 3 tabelas: Casa, Quarto e Cama
Na tabela Cama eu tenho as colunas: id, idQuarto (FK)
Quarto: id, idCasa (FK)
Casa: id
E na minha aplicação eu tenho os seguintes POJO:
publicclassCama{privateintid;privateQuartoquarto;//gets e sets}
publicclassQuarto{privateintid;privateCasacasa;privateSet<Cama>camas;//gets e sets}
publicclassCasa{privateintid;privateSet<Quarto>quartos;//gets e sets}
Como eu teria que criar as classes DAO para poder pegar todos os dados do banco de dados?
Gostaria de fazer o menor numero de requisições possiveis (a qtde de dados é grande, e sao varias tabelas) e eu nao posso alterar nada no banco de dados. Obrigado.
DAO é apenas um objeto que encapsula como vc recupera e persiste os dados da tua camada de persistencia (banco de dados, ws, arquivo texto etc). Como vc implementa o código interno disso depende de vc.
Vai usar DAO e qual será o modelo de persistência? JDBC? ORM?
Arthur.hvt
Uso JDBC. Gostaria de usar Hibernate mas o código ja esta todo em JDBC e teria que mudar muita coisa pra portar.
Eu gostaria de saber se eu teria que fazer um DAO pra cada classe (CasaDAO, QuartoDAO e CamaDAO) ou eu pegaria isso tudo direto do DAO de casa.
drsmachado
A resposta é: depende.
Depende de como você pretende que isso seja feito.
Por exemplo, se só vai usar os dados de quarto e cama junto de casa, não tem por que ter DAOs separados…
Arthur.hvt
Na verdade eu acho que eu preciso de DAOS separados, porque vai ser feito várias outras coisascom quarto e cama... O que eu nao consigo entender é como eu posso pegar todos esses dados do banco de uma vez só com esses DAOS separados e sem que um se relacione com o outro.
Por exemplo, se eu fosse implementar assim:
publicclassCasaDao{publicList<Casa>getCasas()throwsException{ResultSetrs=null;Connectionconexao=null;PreparedStatementps=null;List<Casa>casas=null;try{conexao=connectionFactory.getConexaoExterna();ps=conexao.prepareStatement("SELECT * FROM casas");ps.execute();casas=newArrayList();while(rs.next()){//preciso pegar o id e os quartos. O id tudo bem, mas e os quartos?intid=rs.getInt("id");casas.add(newCasa(id));}returncasas;}catch(Exceptione){thrownewException("Erro ao buscar as casas",e);}finally{conexao.close();}}}
publicclassQuartoDao{publicList<Quarto>getQuartos()throwsException{ResultSetrs=null;Connectionconexao=null;PreparedStatementps=null;List<Quarto>quartos=null;try{conexao=connectionFactory.getConexaoExterna();ps=conexao.prepareStatement("SELECT * FROM quartos");ps.execute();quartos=newArrayList();while(rs.next()){//preciso pegar o id, casa e camas. Como eu pego a casa e as camas?intid=rs.getInt("id");quartos.add(newQuarto(id));}returnquartos;}catch(Exceptione){thrownewException("Erro ao buscar os quartos",e);}finally{conexao.close();}}}
publicclassCamaDao{publicList<Cama>getCamas()throwsException{ResultSetrs=null;Connectionconexao=null;PreparedStatementps=null;List<Cama>camas=null;try{conexao=connectionFactory.getConexaoExterna();ps=conexao.prepareStatement("SELECT * FROM camas");ps.execute();camas=newArrayList();while(rs.next()){//preciso pegar o id e quarto. Como pego o quarto?intid=rs.getInt("id");camas.add(newCama(id));}returncamas;}catch(Exceptione){thrownewException("Erro ao buscar as camas",e);}finally{conexao.close();}}}
Dani_Gomes
Arthur.hvt.
Só para entender, o seu banco não possui relacionamentos?
Pelo que você diz acima, idCasa, é uma chave estrangeira e para ter uma chave estrangeira tem que ter um relacionamento. Então segundo o seu dizer acima o seu banco possui relacinamento.
conexao=connectionFactory.getConexaoExterna();ps=conexao.prepareStatement("SELECT * FROM casas");ps.execute();casas=newArrayList();while(rs.next()){//preciso pegar o id e os quartos. O id tudo bem, mas e os quartos? intid=rs.getInt("id");casas.add(newCasa(id));}returncasas;
Neste caso você está dizendo pro banco selecionar os dados que estão na tabela casas.
E se nesta tabela não possui dados da tabela quarto relacionada, não irá aparecer nenhum dado de quarto de maneira alguma, ai o problema está no seu SQL.
G
gambazinho
só lembrando que se vc utiliza JPA/hibernate vc não deve utilizar DAO a não ser para casos especiais, pois o framework já faz o papel do pattern de isolar as regras de banco pra vc.
Eu enfatizo o coro de @Dani Gomes. Suas tabelas são relacionadas? Se forem, você pode, com certeza, criar uma query que obtenha todos os elementos que necessita, independente de possuir DAOs específicas.
@gambazinho, o uso do DAO, mesmo com ORM, é feito por muitos desenvolvedores para manter-se um total isolamento da estrutura, pois, de outra forma, haveria a dúvida: “persisto na camada model ou crio outra camada?”
G
gambazinho
drsmachado:
Eu enfatizo o coro de @Dani Gomes. Suas tabelas são relacionadas? Se forem, você pode, com certeza, criar uma query que obtenha todos os elementos que necessita, independente de possuir DAOs específicas.
@gambazinho, o uso do DAO, mesmo com ORM, é feito por muitos desenvolvedores para manter-se um total isolamento da estrutura, pois, de outra forma, haveria a dúvida: “persisto na camada model ou crio outra camada?”
o rponte e outros devs da lista de JSF discordam severamente desse ponto de vista e eu particularmente acho que o ideal é realmente evitar um DAO para coisas idiotas como entity.find(entity) ou entity.merge(entity) ou entity.remove(entity) pra que criar um dao pra encapsular algo que já está encapsulado? LOL agora se vc tem uma daquelas querys brutas onde é viável por N questões, entre elas performance, usar jdbc ou mesmo a nativeQuery aí é mais que justificável, é aconselhável isolar essa query num DAO.
Mas o Sr. é já é um GUJ Expert, quem sou eu para discordar.
drsmachado
gambazinho:
drsmachado:
Eu enfatizo o coro de @Dani Gomes. Suas tabelas são relacionadas? Se forem, você pode, com certeza, criar uma query que obtenha todos os elementos que necessita, independente de possuir DAOs específicas.
@gambazinho, o uso do DAO, mesmo com ORM, é feito por muitos desenvolvedores para manter-se um total isolamento da estrutura, pois, de outra forma, haveria a dúvida: “persisto na camada model ou crio outra camada?”
o rponte e outros devs da lista de JSF discordam severamente desse ponto de vista e eu particularmente acho que o ideal é realmente evitar um DAO para coisas idiotas como entity.find(entity) ou entity.merge(entity) ou entity.remove(entity) pra que criar um dao pra encapsular algo que já está encapsulado? LOL agora se vc tem uma daquelas querys brutas onde é viável por N questões, entre elas performance, usar jdbc ou mesmo a nativeQuery aí é mais que justificável, é aconselhável isolar essa query num DAO.
Mas o Sr. é já é um GUJ Expert, quem sou eu para discordar.
Eu compreendo teu ponto de vista, o que disse não é, nem nunca será verdade absoluta.
Por exemplo, eu trabalho num sistema que emprega o design pattern facade e, não há DAOs, com hibernate.
Funciona muito bem, mesmo com queries gigantescas.
G
gambazinho
drsmachado:
Eu compreendo teu ponto de vista, o que disse não é, nem nunca será verdade absoluta.
Por exemplo, eu trabalho num sistema que emprega o design pattern facade e, não há DAOs, com hibernate.
Funciona muito bem, mesmo com queries gigantescas.
é isso aí! ^^
perdoe-me se me excedi.
abs!
tveronezi
DAO é apenas um pattern. No mundo JPA ele pode ser chamado de EAO (Entity Access Object).
Arthur.hvt
Entao seria melhor mesmo eu pegar todos os dados a partir de uma unica DAO (Casa, nesse caso) e utilizando uma query gigante usando inner joins? Realmente essa é a unica forma que eu vejo que pode ser feita pra pegar todos os dados de uma vez com o menor numero de chamadas.
ErickRAR
Sim, você pode fazer assim, e nem precisa de uma query gigante. Só 2 joins, eu acho. O negócio é, isso pode ser levado em consideração se você sempre for trabalhar com o objeto Casa.
Agora imagine que você só precisa de um quarto: Terá que pegar a casa e todos os quartos, apenas para utilizar um único quarto. Isso pode dar uma queda de desempenho.