Duvida em como proceder no acesso ao banco de dados

Ola pessoal.
Estou desenvolvendo um pequeno sisteminha de CRUD para entregar na faculdade no qual estou utilizando JSF (informação irrelevante mas que pode ajudar), e tenho uma duvida séria em quanto o padrão MVC.
Primeiro vou postar o código das minhas classes Dao e Model:

Classe: ClienteModel

[code]package br.com.siscadastroweb.model;

import java.text.SimpleDateFormat;
import java.util.Calendar;

public class ClienteModel {

private int id;
private String nome;
private String sexo;
private Calendar dataNascimento;
private String data; // representação em String de dataNascimento
private String rg;
private String cpf;
private String endereco;
private String bairro;
private String cep;
private String cidade;
private String estado;
private String telefone;

public int getId() {
	return id;
}

public String getNome() {
	return nome;
}

public String getSexo() {
	return sexo;
}

public Calendar getDataNascimento() {
	return dataNascimento;
}

public String getData() {
	this.data = new SimpleDateFormat("dd/MM/yyyy").format(dataNascimento.getTime());
	return this.data; 
}

public String getRg() {
	return rg;
}

public String getCpf() {
	return cpf;
}

public String getEndereco() {
	return endereco;
}

public String getBairro() {
	return bairro;
}

public String getCep() {
	return cep;
}

public String getCidade() {
	return cidade;
}

public String getEstado() {
	return estado;
}

public String getTelefone() {
	return telefone;
}

public void setId(int id) {
	this.id = id;
}

public void setNome(String nome) {
	this.nome = nome;
}

public void setSexo(String sexo) {
	this.sexo = sexo;
}

public void setDataNascimento(Calendar dataNascimento) {
	this.dataNascimento = dataNascimento;
}

public void setRg(String rg) {
	this.rg = rg;
}

public void setCpf(String cpf) {
	this.cpf = cpf;
}

public void setEndereco(String endereco) {
	this.endereco = endereco;
}

public void setBairro(String bairro) {
	this.bairro = bairro;
}

public void setCep(String cep) {
	this.cep = cep;
}

public void setCidade(String cidade) {
	this.cidade = cidade;
}

public void setEstado(String estado) {
	this.estado = estado;
}

public void setTelefone(String telefone) {
	this.telefone = telefone;
}

}[/code]

Classe: ClienteDao

[code]package br.com.siscadastroweb.dao;

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.ResourceBundle;

import br.com.siscadastroweb.model.ClienteModel;

public class ClienteDao {

private ResourceBundle rb;

private Connection connection;
private PreparedStatement stmt;
private ResultSet rs;

private static final String COMANDO_DE_INSERT = "insert into clientes (nome, sexo, dataNascimento, rg, cpf, endereco, bairro, cep, cidade, estado, telefone)"
	+ " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static final String COMANDO_DE_UPDATE = "update clientes set nome = ?, sexo = ?, dataNascimento = ?, rg = ?, cpf = ?, endereco = ?, bairro = ?, cep = ?, "
	+ "cidade = ?, estado = ?, telefone = ?" + "where id = ?";
private static final String COMANDO_DE_DELETE = "delete from clientes where id = ?";
private static final String COMANDO_DE_SELECT_BUSCA_POR_ID = "select * from clientes where id = ?";
private static final String COMANDO_DE_SELECT_BUSCA_TODOS = "select * from clientes";
private static final String COMANDO_DE_SELECT_BUSCA_POR_NOME = "select * from clientes where nome = ?";

public ClienteDao() throws ClassNotFoundException, SQLException {
	this.conectar();
}

private void conectar() throws ClassNotFoundException, SQLException {
	this.rb = ResourceBundle.getBundle("br.com.siscadastroweb.propriedades.bancodedados");
	Class.forName(this.rb.getString("driver"));
	this.connection = DriverManager.getConnection(this.rb.getString("url"),
			this.rb.getString("usuario"), 
			this.rb.getString("senha"));
}

private void desconectar() throws SQLException {
	if (!this.connection.isClosed())
		this.connection.close();
}

public void incluirCliente(ClienteModel clienteModel) throws SQLException, ClassNotFoundException {
	if(this.connection.isClosed())
		this.conectar();
	this.stmt = this.connection.prepareStatement(COMANDO_DE_INSERT);
	this.carregarParametrosInclusao(clienteModel, this.stmt);
	this.stmt.execute();
	this.desconectar();
}

public void editarCliente(ClienteModel clienteModel) throws SQLException, ClassNotFoundException {
	if(this.connection.isClosed())
		this.conectar();
	this.stmt = this.connection.prepareStatement(COMANDO_DE_UPDATE);
	this.carregarParametrosEdicao(clienteModel, this.stmt);
	this.stmt.execute();
	this.stmt.close();
	this.desconectar();
}

public void deletarCliente(ClienteModel cliente) throws SQLException, ClassNotFoundException {
	if(this.connection.isClosed())
		this.conectar();
	this.stmt = this.connection.prepareStatement(COMANDO_DE_DELETE);
	this.stmt.setInt(1, cliente.getId());
	this.stmt.execute();
	this.stmt.close();
	this.desconectar();
}

public ClienteModel consultarCliente(ClienteModel clienteModel) throws SQLException, ClassNotFoundException {
	if(this.connection.isClosed())
		this.conectar();
	this.stmt = this.connection.prepareStatement(COMANDO_DE_SELECT_BUSCA_POR_ID);
	this.stmt.setInt(1, clienteModel.getId());
	this.rs = this.stmt.executeQuery();
	if (!(this.rs == null)) {
		while (this.rs.next()) {
			clienteModel = this.retornarCliente(this.rs);
		}
		this.rs.close();
		this.stmt.close();
		this.desconectar();
		return clienteModel;
	} else
		this.rs.close();
	this.stmt.close();
	this.desconectar();
	return null;
}

public ClienteModel consultarCliente(String campo, ClienteModel clienteModel) throws SQLException, ClassNotFoundException {
	if(this.connection.isClosed())
		this.conectar();
	if (campo.equals("id")) {
		this.stmt = this.connection.prepareStatement(COMANDO_DE_SELECT_BUSCA_POR_ID);
		this.stmt.setInt(1, clienteModel.getId());
	} else {
		this.stmt = this.connection.prepareStatement(COMANDO_DE_SELECT_BUSCA_POR_NOME);
		this.stmt.setString(1, clienteModel.getNome());
	}
	this.rs = this.stmt.executeQuery();
	if (!(this.rs == null)) {
		while (this.rs.next()) {
			clienteModel = this.retornarCliente(this.rs);
		}
		this.rs.close();
		this.stmt.close();
		this.desconectar();
		return clienteModel;
	} else
		this.rs.close();
	this.stmt.close();
	this.desconectar();
	return null;
}

public List<ClienteModel> getLista() throws SQLException, ClassNotFoundException {
	List<ClienteModel> listaClientes = new ArrayList<ClienteModel>();
	if(this.connection.isClosed())
		this.conectar();
	this.stmt = this.connection.prepareStatement(COMANDO_DE_SELECT_BUSCA_TODOS);
	this.rs = this.stmt.executeQuery();
	if (!(this.rs == null)) {
		while (this.rs.next()) {
			listaClientes.add(this.retornarCliente(this.rs));
		}
		this.rs.close();
		this.stmt.close();
		this.desconectar();
		return listaClientes;
	} else {
		this.rs.close();
		this.stmt.close();
		this.desconectar();
		return null;
	}
}

private ClienteModel retornarCliente(ResultSet rs) throws SQLException {
	ClienteModel cliente = new ClienteModel();
	cliente.setId(rs.getInt("id"));
	cliente.setNome(rs.getString("nome"));
	cliente.setSexo(rs.getString("sexo"));
	Calendar dataNascimento = Calendar.getInstance();
	dataNascimento.setTime(rs.getDate("dataNascimento"));
	cliente.setDataNascimento(dataNascimento);
	cliente.setRg(rs.getString("rg"));
	cliente.setCpf(rs.getString("cpf"));
	cliente.setEndereco(rs.getString("Endereco"));
	cliente.setBairro(rs.getString("bairro"));
	cliente.setCep(rs.getString("cep"));
	cliente.setCidade(rs.getString("cidade"));
	cliente.setEstado(rs.getString("estado"));
	cliente.setTelefone(rs.getString("telefone"));
	return cliente;
}

private void carregarParametrosInclusao(ClienteModel cliente,
		PreparedStatement stmt) throws SQLException {
	stmt.setString(1, cliente.getNome());
	stmt.setString(2, cliente.getSexo());
	stmt.setDate(3, new Date(cliente.getDataNascimento().getTimeInMillis()));
	stmt.setString(4, cliente.getRg());
	stmt.setString(5, cliente.getCpf());
	stmt.setString(6, cliente.getEndereco());
	stmt.setString(7, cliente.getBairro());
	stmt.setString(8, cliente.getCep());
	stmt.setString(9, cliente.getCidade());
	stmt.setString(10, cliente.getEstado());
	stmt.setString(11, cliente.getTelefone());
} 

private void carregarParametrosEdicao(ClienteModel cliente,
		PreparedStatement stmt) throws SQLException {
	stmt.setString(1, cliente.getNome());
	stmt.setString(2, cliente.getSexo());
	stmt.setDate(3, new Date(cliente.getDataNascimento().getTimeInMillis()));
	stmt.setString(4, cliente.getRg());
	stmt.setString(5, cliente.getCpf());
	stmt.setString(6, cliente.getEndereco());
	stmt.setString(7, cliente.getBairro());
	stmt.setString(8, cliente.getCep());
	stmt.setString(9, cliente.getCidade());
	stmt.setString(10, cliente.getEstado());
	stmt.setString(11, cliente.getTelefone());
	stmt.setInt(12, cliente.getId());
}

}[/code]

Agora a minha duvida:
Como posso implementar a minha classe control?
Pois vejam só o meu drama:
Na faculdade o professor falou que o correto é:
view —> control —> model —> dao
ou seja:
view chama a classe control, control chama model e model chama dao.
OK!
Agora preciso saber se numa arquitetura para Web eu teria que tratar minhas exceções de banco (os throws que vcs vêem nas assinaturas dos métodos)
na classe DAO, na Model ou no Control.

Pois como utilizarei JSF não sei como organizar minha arquitetura, pois fico sem saber como determinar meus Managed Beans.

Por favor me ajudem nesta duvida!
Obs: Eu não tenho essa duvida esclusivamente para Web, mas também para Swing. É uma duvida que esta me matando!

Vlw!

Olha, sou iniciante, mas acho que as exeções, no seu caso, devem ser tratadas na camada de controle e ali mesmo remanejar o usuario para o caminho certo de acordo com a exceção …
Me corrijam se eu estiver errado, asssim também aprendo :slight_smile:
Abraços

[quote=BLV-DOOM JAVA]Ola pessoal.
Na faculdade o professor falou que o correto é:
view —> control —> model —> dao
[/quote]

Penso que o MVC é:
[color=white]--------[/color]v i e w<— ---> model[ —> dao ]
[color=white]--------[/color]|[color=white]----[/color] ^[color=white]-------------[/color]^
[color=white]--------[/color]|[color=white]-----[/color]|[color=white]-----
---------[/color]|
[color=white]--------[/color]|control______|

A função do control é prover a navegação entre as views e delegar para o modelo as entradas/ações do usuário, sem criar acoplamento entre os eles.

Observe que o DAO não faz parte do padrão (explicitamente). Senão seria MVCD :lol:

As exceções que seu DAO lança (SQLException, ClassNotFound…) provavelmente não são exceções do domínio do usuário do sistema e portanto, deveriam ser tratadas no modelo e se for o caso, transformadas numa exceção com mensagem adequada ao usuário e relançada para a view.

Abraços

Na verdade, a confusão aqui é : DAO faz parte do modelo? Resposta: SIM!

O modelo é tudo que será , no contexto da camada, agnóstico quanto ao método como foi invocado. Por isso existe o controlador: para enviar a requisição para o modelo , e este não se preocupará em como foi chamado.

Agora, quanto ao seu problema… eu percebí uma grande tendência de seguir Anemic Domain Model, aí. O jeito mais interessante de fazer isso seria, na verdade, você embutir alguma lógica de processamento dentro da própria entidade (segundo esta referência). Como, talvez pra você, isso não seja interessante, uma alternativa seria a criação de uma Fachada para que você possa descobrir, a partir da fachada, o que é mais interessante em cada caso, seja ele Create, Retrieve, Update ou Delete (não, isso não é tarefa do controlador).

[]´s