MVC e DAO como utiliso filtros

Olá a todos,

Como estou comecando nessas assuntos não sei tudo ainda, mais estou estudando muitos conceitos e vantagens e estamos no meu enprego adotando esse padão.

Bom, mais chega de bla, bla, bla.
Estou com uma duvida e preciso tirar o mais rápido possivel

Sequinte tenho classes DTO assim :

class ClienteDTO {
    private int id_cliente;
    private string nome;
    private string telefone;
    // getters e setters
}
class ContaDTO {
   private int id_conta ;
   private ClienteDTO cliente;
   private string numero_conta;
   private string numero_agencia;
   private string nome_banco;
   private int codigo_banco;
   // getters e setters
}

E as classes DAO para fazer, insert, update, select, delete de cada uma.
E as classes de regra de negocio, que vou chamar de BLL, que contem as chamadas para os metodos das DAO passando como parametro as classes DTO.

Uma duvida já surgi agora, qual a melhor maneira de criar a classe ContaDAO fazer um selectALL nas contas.
É carregando um select com join, todos os dados e conta e cliente ?
ou carregar só os dados de conta, depois dar um select por ID para carregar o cliente ?
ou carregar só os dados de conta, e apenas criar uma instância de cliente contendo o seu id, mais sem dados carregados ?

Agora, preciso criar uma tela para mostrar todos os clientes e o numero e conta dele, se houver.
Como fazer isso, tentando otimizar o retorno do SGBD?

Cara, isso depende muito do seu SGBD, do tamanho do banco e da quantidade de requisicões que voce vai ter.

Se as informações do JOIN nao forem usadas com muita frequencia, acho que nao tem problema. Mas se forem feitos muitos joins, com tabelas grandes e tal, pode ser que caia a performance. Aí seria bom pensar em fazer selects separados.

O ideal seria você tentar implementar algumas dessas opções e testar, pra ver como fica melhor pro seu sistema.

Vc pode, pela hierarquia de classes, fazer com que a classe cliente tenha um set ou uma lista de contas.
Com isso, um selectAll nos clientes já traria as contas.
E sobre otimização de SGBDs, vc pode fazer um select só, fazendo um join entre conta e clientes e fazer com que o seu método leia esse retorno e preencha os objetos, caso a tecnologia usada seja JDBC.
Se vc tiver utilizando um ORM como o Hibernate, por exemplo, essa associação já estaria disponivel, claro, setando o lazy para true e deixando a sessão válida até a renderização do jsp.

A operação que você utilizará depende muito da sua necessidade. Cada uma das opções que você citou tem vantagens e desvantagens.
Eu não tenho conhecimento do seu ambiente, seu SGBD, modelagem de dados, etc., portanto somente passarei alguns conceitos que eu acho que são válidos.

Na minha opinião, o que você deve pensar é:

1 - Você vai precisar exibir os dados dos clientes quando for trazer as contas? Se a resposta for sim, você terá que levar em consideração o número de acessos que fará na base de dados. Se forem muitos (eu disse muitos) acessos, compensa mais utilizar uma consulta só, ou até uma stored procedure. Assim, você acessará somente uma vez a base de dados, diminuindo o tráfego de rede. Uma das desvantagens dessa abordagem é que uma consulta dessas é um pouco mais complexa.
Entretanto, se a resposta for não, não há necessidade de trazer os dados dos clientes.

2 - Referente a trazer todos os clientes e suas contas, eu acho que isso pode ser feito somente em uma consulta, sem maiores problemas.

Valeu pessoal, respostá muito rápida.

Pelos conselhos que li é melhor fazer uma função com um select só quando for a pagina que mostra os Clientes e Contas, em outras casos, não necessariamente.

Bom, mais agora não sei ainde é melhor criar esta função.

Na classe de negocio, aonde eu passaria um select como parametro.

Ou na classe DAO, criar uma função do tipo
retornaClienteConta(filtros) ?

Bom, o que acham melhor, prefico na classe DAO, mais e voceis?

Abraços,
Henrique

Os métodos de acesso a dados DEVEM ser feitos sempre nas classes DAO.

Se você colocar um select ou algo assim nas classes de negócio, as mesmas ficarão acopladas à camada de acesso a dados, o que não é desejável. Para passar os parâmetros para a camada de acesso a dados, você pode utilizar um DTO, um Context Object, uma classe que represente uma chave primária… há várias opções (qual é melhor, depende do contexto do seu sistema e dos próprios desenvolvedores). Mas passar um select da camada de negócios para a camada de acesso a dados não é uma boa opção.

felipealbuquerque , adorei seu comentáiro. Este assunto está ficando muito bom.

Assim, então posso passar de parametro para a classe DAO, um objeto DTO no metodo select para fazer os filtros.
Intão implemento para verificar se cada atributo não é nulo e faco o filtro correto?

Pelo que entendi isso funciona para filtro do tipo igualdade.
Mais se eu quizer por exemplo fazer algo do tipo
Retornar todas as contar que foram aberta após 01/01/2006.

Não daria para utilizar isto, pois retornaria todas as contar aberta naquele dia certo?

Intão, fica a pergunta, como implemento esse tipo de filtro.

Sobre o que vc falou, não entendi o Context Object. O que seria isso? É a mesma coisa que DTO. ou não

Abraços,
Henrique

Um material legal sobre Context Objects (os códigos não estão em Java, mas o conceito está bem explicado): http://www.cs.wustl.edu/~schmidt/PDF/Context-Object-Pattern.pdf

Ao invés de passar um DTO como parâmetro, você pode passar uma classe que mapeia chaves com valores. Segue um exemplo bem simplificado:

public class SearchCriteria() {

    private Map criterias;

    public SearchCriteria() {
        this.criterias = new HashMap();
    }

    public void addCriteria(String key, Object criteria) {
        this.criterias.put(key, criteria);
    }

    public Date getDataCompra() {
        return (Date) this.criteria.get("dataCompra");
    }

}

// Para chamar a classe de um DAO, por exemplo:

//...
    Date dataCompra = criteria.getDataCompra();

    sql += " WHERE tabela.data_compra > " + DateUtil.getInstance().dateToString(dataCompra);
//...

No caso, você evita passar um DTO inteiro como parâmetro, evitando, assim, maiores complicações na lógica. Um dos princípios que é aconselhável seguirmos é o conceito de que não devemos codificar o que não vamos utilizar. Se não vamos utilizar um DTO inteiro no método do DAO, é preferível utilizar um recurso como esse apresentado. Há outros recursos que podem ser utilizados, esse é apenas um exemplo.

Espero ter ajudado!

Sobre sua classe SearchCriteria é mais ou menos isso que estou procurando.

Dai faria algo do tipo assim.

na classe DAO.

contaDao.select(instanciaDeSearchCriteria);

dai este SQL é montado de acordo com os filtros da instancia de SearchCriteria.

Porém queria que essa classe fosse mais generica.
Do tipo, tem uma lista de objetos.
e esses objetos, com um tipo de filtro ( AND, OR, >, <, >=, etc) e uma listra de parametros, pois um filtro pode utilizar dois parametros, exemplo BETWEEN

Alguma idéia para implementar algo assim.
O problema maior na minha visão é em que coluna se aplica o filtro no SQL. já passar o nome da COLUNA não é uma boa pratica na classe de negocio. Ou estou errado?