Retornar resultset para webclient

17 respostas
R

Galera, sou iniciante e estou levando laço pra retornar um resultset para um webclient (eclipse), estou usando os assistentes do eclipse para gerar o cliente.

A idéia é pegar um resultset e retornar um array pro cliente, estou usando o seguinte código:

public String[][] getObtemDados() throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException{
		
		Connection conn = null;
		Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
		conn = DriverManager.getConnection("jdbc:odbc:DBCLOUD", "sa", "123");
		Statement stm = conn.createStatement();
		String SQL = "select * from usuarios u ";

		ResultSet rs = stm.executeQuery(SQL);
		
        ResultSetMetaData rsmd = rs.getMetaData();   
        int cols = rsmd.getColumnCount();
        
        ArrayList<String[]> linhas = new ArrayList<String[]>(); // lista de "linhas"   
             
        while(rs.next()) {    
            for(int i = 0;i < cols; i++){    
                String[] registro = new String[cols];   
                {
                	registro[i]   = rs.getString(i+1);
                }           
                linhas.add(registro);   
            }   
        }     
        
        return linhas.toArray(new String[linhas.size()][]);         
	}

Recebo o seguinte retorno: [[Ljava.lang.String;@e85825

Eu não deveria receber os campos listados na ordem e tal ? como se fossem uma tabela ? Ou no JSP devo fazer isso no braço ?

Valeu !!!

17 Respostas

R

Mudei duas coisas pra testar:

public ArrayList<String[]> getObtemDados() throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException{

e

return linhas;

Me retornou o seguinte:
[[Ljava.lang.String;@1aa0e3b, [Ljava.lang.String;@18c4a7f, [Ljava.lang.String;@16ee3ec, [Ljava.lang.String;@135da43, [Ljava.lang.String;@8c7be5, [Ljava.lang.String;@11a0d35, [Ljava.lang.String;@1594a88, [Ljava.lang.String;@12c4c57]

Imagino que o retorno esteja correto uma vez que tenho 2 registros com 4 colunas, creio que ele está me listados os dados da tabela nesse formato ai de cima.

Como resolver essa parada ?

valeu !

B

Que tal pegar os dados dentro dos registros com getNomeDoTipo(numeroDaColunaDaTabela) ou getNomeDoTipo(nomeDaColunaDaTabela)

B

Ah, desculpe, você está trabalhando com ResultSetMetadata, não ResultSets.

mario.fts
String[] registro = null;
        while(rs.next()) {    
            registro = new String[cols];
            for(int i = 0;i < cols; i++){    
                	registro[i]   = rs.getString(i+1);
                }           
                linhas.add(registro);   
            }

EDIT: altera a parte do loop do seu código.

PS : Eu não testei… :roll:

B

Ok, perguntas:

Você tem certeza que quer retornar uma matriz de Strings? Por que não uma Lista de Objetos que representam os dados da tabela?

mario.fts

Bruno Laturner:
Ok, perguntas:

Você tem certeza que quer retornar uma matriz de Strings? Por que não uma Lista de Objetos que representam os dados da tabela?

Essa era a próxima pergunta que eu ia fazer… uhauhauhauahuah

R

Bruno Laturner e mario.fts,

Na realidade não sei como fazer e qual a diferença, entendi que essa era a maneira correta.

Tentei de outras formas, mas qd passava como retorno um resultset o eclipse “gritava” dizendo que nao era compativel e tal. Imagino que é pelo fato de eu estar trabalhando com web service.

Vocês poderiam por gentileza me indicar a forma correta de fazer isso ?

Eu instanciando essa classe a partir de uma classe de teste, e a partir dele eu criava o JSP com a ajuda do assistente do eclipse.

B

Há várias maneiras de resolver isso. A mais comum é criar uma classe-espelho da tabela do banco, isto é, cada atributo mapeia para uma coluna. Os tipos de cada coluna também são mapeados para os tipos dos atributos.

Instancie a classe, coloque os dados obtidos de cada rs.get* nos seus atributos respectivos, e adicione o objeto à lista. retorne uma List.

R

Bruno, obrigado pelo apoio.

tentei assim, o eclipse nao indicou erro mas nao consegui pegar o retorno…

ArrayList<Usuario> usu = aut.getObtemDados();
		System.out.println(usu[0]); //aqui dá pau
		System.out.println(usu[1]); //aqui dá pau
public ArrayList<Usuario> getObtemDados() throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException{
		
		Connection conn = null;
		Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
		conn = DriverManager.getConnection("jdbc:odbc:DBCLOUD", "sa", "123");
		Statement stm = conn.createStatement();
		String SQL = "select * from usuarios u ";

		ResultSet rs = stm.executeQuery(SQL);

		ArrayList<Usuario> lista = null; 
		
		while(rs.next()) {    
			//String[] registro = new String[cols];   
			String nome = rs.getString("nome");   
			String senha = rs.getString("senha");   				
		    Usuario usuario = new Usuario(nome, senha);   
		    lista.add(usuario); 
		}           
		return lista;
	}

Quando coloco return lista<Usuario>; dá pau

B
dentro da classe Usuario
public String toString() {
	return this.nome + " : " + this.senha;
}
List<Usuario> usu = aut.getObtemDados();
		System.out.println(usu.get(0)); // usu é uma classe, não um array
		System.out.println(usu.get(1)); // olhe o toString funcionando
		// ou
		System.out.println(usu); // para imprimir todos, usa o toString também.
public List<Usuario> getObtemDados() throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException{ // novo
		
		Connection conn = null;
		Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
		conn = DriverManager.getConnection("jdbc:odbc:DBCLOUD", "sa", "123");
		Statement stm = conn.createStatement();
		String SQL = "select * from usuarios u ";

		ResultSet rs = stm.executeQuery(SQL);

		List<Usuario> lista = new ArrayList<Usuario>();  // use as interfaces e não as classes concretas.
		
		while(rs.next()) {    
			String nome = rs.getString("nome");
			String senha = rs.getString("senha");
			Usuario usuario = new Usuario(nome, senha);
			lista.add(usuario);
		}           
		return lista;
	}
R

Bruno, obrigado !

Matou a pau…nao ficou exatamente igual, mas funcionou perfeitamente:

Código que retorna o array

public ArrayList<Usuario> getObtemDados() throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException{ // novo   
	       
	    Connection conn = null;   
	    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();   
	    conn = DriverManager.getConnection("jdbc:odbc:DBCLOUD", "sa", "123");   
	    Statement stm = conn.createStatement();   
	    String SQL = "select * from usuarios u ";   
	  
	    ResultSet rs = stm.executeQuery(SQL);   
	  
	    ArrayList<Usuario> lista = new ArrayList<Usuario>();  // use as interfaces e não as classes concretas.   
	       
	    while(rs.next()) {       
	        String nome = rs.getString("nome");   
	        String senha = rs.getString("senha");   
	        Usuario usuario = new Usuario(nome, senha);   
	        lista.add(usuario);   
	    }             
	    return lista;   
	}

Código de teste:

Autentica aut = new Autentica();
		
		aut.setNome("Felipe");
		aut.setSenha("123");
		ArrayList<Usuario> usu = aut.getObtemDados();
		
		System.out.println("tamanho: " + usu.size());
		
		System.out.println("Nome: " + usu.get(0).getNome());
		System.out.println("Senha: " + usu.get(0).getSenha());

		System.out.println("Nome: " + usu.get(1).getNome());
		System.out.println("Senha: " + usu.get(1).getSenha());
		
		System.out.println(usu.toString());
R

Bruno,

saberia me dizer como eu poderia deixar esse método mais genérico ? do tipo…idenpendente do número de colunas ele me retorna o objeto “Usuario” no return ?

tipo:

while(rs.next()) {
	        String nome = rs.getString("nome");   
	        String senha = rs.getString("senha");   
	        Usuario usuario = new Usuario(nome, senha);   
	        lista.add(usuario);   
	    	ResultSetMetaData rsmd = rs.getMetaData();
	    	int count = rsmd.getColumnCount();
	    	ArrayList<String> colunas = new ArrayList<String>();
	    	for(int i = 1 ; i <= count ; i++) {
	    		colunas.add(rs.getString(i));
	    	}
	    	linhas.add(colunas);
	    }
	    lista = linhas;
	    }

tentei mas deu erro pra caramba… teria de ser em cima desse método:

public ArrayList<Usuario> getObtemDados() throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException{ 
	       
	    Connection conn = null;   
	    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();   
	    conn = DriverManager.getConnection("jdbc:odbc:DBCLOUD", "sa", "123");   
	    Statement stm = conn.createStatement();   
	    String SQL = "select * from usuarios u ";   
	  
	    ResultSet rs = stm.executeQuery(SQL);   
	  
	    ArrayList<Usuario> lista = new ArrayList<Usuario>();
	    
	    while(rs.next()) {
	        String nome = rs.getString("nome");   
	        String senha = rs.getString("senha");   
	        Usuario usuario = new Usuario(nome, senha);   
	        lista.add(usuario);   
	    }
	    return lista;   
	}
mario.fts

Dúvida:

vc não sabe antecipadamente o número de colunas?

R

Exato,

Estou forçando a barra, mas a idéia é que eu possa utilizar independente do numero do colunas q tenha o select passado como parametro.

Sacou ?

B

raschefelipe:
Bruno,

saberia me dizer como eu poderia deixar esse método mais genérico ? do tipo…idenpendente do número de colunas ele me retorna o objeto “Usuario” no return ?

Olha, se for preguiça de mapear uma tabela p/ um classe, use uma IDE que tenha um gerador de entidades, ela vai ir até o banco e criar as classes, o acesso aos dados. Netbeans tem um.

Fora isso, vá até o banco, veja quais são as colunas da tabela lá, e para as colunas que você quiser buscar, coloque o nome delas no lugar do * no select.

Digo isso por que não há muita utilidade p/ buscas genéricas sem dados definidos. Só dá pra trabalhar com o conhecido.

mario.fts

é… neste caso vc vai ter que usar strings mesmo… não da pra fazer com objetos.

R

Galera,

Obrigado !

Entendi a idéia, vou criar no braço para ter mais controle.

Valeu mesmo…

Criado 14 de outubro de 2008
Ultima resposta 15 de out. de 2008
Respostas 17
Participantes 3