Duvida sobre design patern VO

11 respostas
homisinho

Olá a todos estou criando uma nova aplicação e quero fazer da forma mais simples e correta, e nisso várias dúvidas apareceram.

criei as seguintes classes:

public class ConnectionFactory extends CarArquivoBanco{
    
    private static Connection conemysql=null;    

    private ConnectionFactory(){
       super();   
    }
    
            
    public void CriaConexao() throws ClassNotFoundException, SQLException{
        Class.forName("com.mysql.jdbc.Driver");
        conemysql = DriverManager.getConnection("jdbc:mysql://"+servidor+":"+porta+"/"+banco,user,senha);        
    }    
    
    public static Connection getconemysql() throws SQLException, ClassNotFoundException {        
        if(conemysql == null ){
           ConnectionFactory rara = new ConnectionFactory();    
           rara.CriaConexao();
        }
        return conemysql;
    }
}

Como é um sistema desktop achei melhor utilizar sempre a mesma conexão, fiz de acordo com alguns exemplos.

Tenho duas tabelas no meu banco de dados, criei duas classes modelos:

public class Unidade {
    private int uni_codigo;
    private String uni_nome;
    private int uni_tipo;
    private int uni_prod; ///somente o codigo do produto
//gets e sets
}

public class Produto {
    private int prod_cod;
    private String prod_nome;
//gets e sets
}

Criei duas classes DAO:

public class UnidadeDAO implements Serializable {

    private Connection connection;
    
    public UnidadeDAO(){
        try {
            this.connection = conexao.ConnectionFactory.getconemysql();
        } catch (SQLException ex) {
            Logger.getLogger(UnidadeDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(UnidadeDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public boolean deleta(Unidade unid) throws SQLException{}
    public void adiciona(Unidade unid) throws SQLException {}
    public List loadAll() throws SQLException {}
}

public class ProdutoDAO {
    
    private Connection connection;
    
    public ProdutoDAO(){
        try {
            this.connection = conexao.ConnectionFactory.getconemysql();
        } catch (SQLException ex) {
            Logger.getLogger(UnidadeDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(UnidadeDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public boolean deleta(Produto prod) throws SQLException{}
    public void adiciona(Produto prod) throws SQLException {}
    public List loadAll() throws SQLException {}
}

E ai surgiu a minha dúvida, no meu metodo Unidade.loadAll(), ira me retornar um List com o codigo do produto, mas na realidade eu quero mostrar o nome do produto. Como eu faço isso?
Li algo sobre VO, mas nada muito claro, sem nenhum exemplo simples de entender. Sei que posso criar um metodo com um select que me retorna o campo nome do produto mas em qual classe eu faço isso? E quando vou alterar o produto onde coloco o metodo pra isso?

Acredito q muitos outros iniciantes na linguagem tem essa mesma dúvida!
Desde já, obrigado.

11 Respostas

danieldestro

O legal seria seu findAll retornar um List<Unidade>, assim você terá uma lista de objetos com todos os dados das Unidades.
Dá uma olhada em JPA (Hibernate ou Toplink). Eles podem solucionar melhor o seu problema.

E para manter um padrão de nomenclatura use o Code Convention da Sun: http://java.sun.com/docs/codeconv/

homisinho

Ola danieldestro,
o meu método findAll me retorna um List com objetos do tipo Unidade, o problema é que na minha classe Unidade eu só tenho o “uni_prod” q é o código do produto, mas eu preciso do “prod_nome”. Deu pra dar uma esclarecida melhor?

danieldestro

public List<Unidade> loadAll() throws SQLException { List<Unidade> list = new ArrayList<Unidade>(); String sql = "SELECT ID, NOME FROM UNIDADE"; PreparedStatement ps = connection.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while( rs.next() ) { Unidade u = new Unidade(); u.setId( rs.getInt("ID" ); u.setNome( rs.getString("NOME") ); list.add ( u ); } rs.close(); ps.close(); return list; }

homisinho

Deixa eu explicar melhor… olha os meus metodos da classe UnidadeDAO:

public List loadAll() throws SQLException {

///poderia fazer "SELECT unidade. * , produto.prod_nome FROM unidade, produto WHERE unidade.uni_prod = produto.prod_cod"
////mas ai eu estaria criando um atributo prod_nome na minha classe Unidade.... 
          String sql = "SELECT * FROM unidade ORDER BY uni_codigo"; 
          List searchResults = listQuery(this.connection.prepareStatement(sql));
          return searchResults;
    }
    
    
    protected List listQuery(PreparedStatement stmt) throws SQLException {   
  
          ArrayList searchResults = new ArrayList();   
          ResultSet result = null;   
  
          try {   
              result = stmt.executeQuery();     
              while (result.next()) {   
                   Unidade temp = new Unidade();
                   temp.setUni_codigo(result.getInt("uni_codigo"));
                   temp.setUni_nome(result.getString("uni_nome"));                      
                   temp.setUni_tipo(result.getInt("uni_tipo"));
                   temp.setUni_prod(result.getInt("uni_prod")); /////note q eu so tenho o codigo do produto
                   searchResults.add(temp);   
              }  
          } finally {
              if (result != null)   
                  result.close();   
              if (stmt != null)   
                  stmt.close();   
          }  
          return (List)searchResults;   
    }

É uma FK entre a tabela unidade e produto, e como eu trato isso nas minhas classes???

danieldestro

Você realmente precisa fazer isso na mão (JDBC direto)???
Aconselho a usar JPA.

homisinho

Tem algum exemplo simples?
Depois de um exemplo simples vou pra documentação…

sergiotaborda

Utilizar a mesma conexão significa que ela tem que ser mantida aberta pelo tempo que aplicação a usa.
Isto pode parecer pouco, e é, mas causa outros problemas. A conexão pode cair.
Além disso o seu codigo nunca executa close da coneção o que significa que nunca ha close dos statements e nem dos resultsets
isso são objetos que ficam acumulando e isso é ruim. Crie uma conexão no inicio da transação e feche-a no fim. Isso é muito mais simples e seguro. Mesmo que aparentemente menos eficiente.

danieldestro

http://www.marcomendes.com/ArquivosBlog/AloMundoJPA.pdf

victorwss

homisinho:
Olá a todos estou criando uma nova aplicação e quero fazer da forma mais simples e correta, e nisso várias dúvidas apareceram.

criei as seguintes classes:

Tenho duas tabelas no meu banco de dados, criei duas classes modelos:


Cara, VOs são furada. VO não é um pattern, é um anti-pattern. Fuja delas enquanto você ainda pode, senão será tarde demais e você será consumido e tragado por elas de forma irreversível. Salve-se enquanto você ainda tem chance!

Já fiz isso uma vez em desktop também. Até chegar a um ponto que não tinha como fazer com uma única conexão. Isso doeu. Não cometa o mesmo erro.
Basicamente o problema foi que o usuário pode ter várias telas ao mesmo tempo fazendo operações simultâneas. Se for na mesma conexão, você perde o controle de transações e daí já era.

mduques

Primeiro vc deviria modelar suas classes O.O.
ficaria algo assim:

  1. public class Unidade {
  2. private int uni_codigo;
    
  3. private String uni_nome;
    
  4. private int uni_tipo;
    
  5. private Produto prod; ///relacionamento entre objetos
    
  6. //gets e sets
  7. }
  8. public class Produto {
  9. private int prod_cod;
    
  10. private String prod_nome;  
     List<Unidade> ou Unidade unidade;//depende do seu modelo
    
  11. //gets e sets
  12. }

ai se vc for usar JDBC, sua query mudaria e no select vc fariz o join… trabalhao no resultset

while (result.next()) {

Unidade temp = new Unidade();

temp.setUni_codigo(result.getInt(“uni_codigo”));

temp.setUni_nome(result.getString(“uni_nome”));

temp.setUni_tipo(result.getInt(“uni_tipo”));

temp.setProd(new Produto(result.getInt(“uni_prod”), result.getString(“prod_nome”)); /////crie um contrutor em produto que receba o id e a desc.

searchResults.add(temp);

}

seria melhor vc usar JPA mas primeiro veja OO senao vc vai se perder

flw

homisinho

Desculpa a demora…

sergiotaborda cada vez que eu criava um novo PreparedStantment eu fechava ele… mas depois do q o victorwss postou, fui dar uma pesquisada e vi que a maioria dos programadores estão utilizando algum outro recurso e deixando esses controles de lado.

Resolvi seguir a dica do nosso amigo danieldestro e utilizar a JPA.

Achei uma VideoAula Fabio.Kung da Caelum, estou implementando a mesma, já encontrei problemas, mas como o assunto é outro irei criar outro tópico.

Atte.

Criado 18 de julho de 2008
Ultima resposta 21 de jul. de 2008
Respostas 11
Participantes 5