[RESOLVIDO]Criar uma lista (List) com informações do banco de dados

Boa noite galera, acredito estar no lugar certo, estou com um pequeno contra tempo, e preciso da ajuda, tenho uma tabela no banco de dados MySQL de USUARIO, nela vai conter no máximo 10 usuários, com as seguintes informações: (o número é referente as colunas)

1-ID | 2-LOGIN | 3-SENHA | 4-NOME | 5-PERFIL | 6-EMAIL | 7-DIGITAL | 8-CONSUMO PERMITIDO

Então preciso armazenas todos os usuários que tiver na tabela em uma String Array, por exemplo, Array[0] contem as informações do usuário 1, Array[1] informações do usuário 2 e assim por diante, por estou implementando um leitor biométrico e preciso da lista de usuários para identificar o usuário.

Fiz esse pequeno exemplo para verificar qual o retorno:

public void buscarUsuario(){
        String resultado = null;
        String sql = "SELECT * FROM USUARIO";
        try {
            pst = conexao.prepareStatement(sql);
            rs = pst.executeQuery();
            if (rs.next()) {
                //1-ID | 2-LOGIN | 3-SENHA | 4-NOME | 5-PERFIL | 6-EMAIL | 7-DIGITAL | 8-CONSUMO PERMITIDO
                resultado = (rs.getString(1)+";"+rs.getString(2)+";"+rs.getString(3)+";"+rs.getString(4)+";"+rs.getString(5)+";"+rs.getString(6)+";"+rs.getString(7)+";"+rs.getString(8));
            }
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, e);
        }
        System.out.println(resultado);
    }

E retornou como esperava, retornou o seguinte:

1;admin;123;Administrador;admin;admin@admin.com;1234;10

Porém não consegui pensar em algo onde recupere todos usuários, esse é apenas o usuário 1 (Admin)

Não sei se fui claro o suficiente galera, qualquer sugestão é muito bem vinda, muito agradecido!

Primeiro vamos lá orientação a objetos
Cria um objeto usuário com os atributos que vc precisa, mais os métodos de acesso.
Em vez de ficar dando get passando um número no result set, existe uma sobrecarga com o nome da coluna, que fica bem mais visível, se não ficou claro, olha na documentação do prepared statement .
E se vão ser vários registros, logo vc precisa de uma estrutura de repetição certo ?

Sim amiguinho igomes, muito agradecido pela atenção…

Sim, terei que usar uma estrutura de repetição, isso é claro já que preciso obter vários registros, trabalhar com métodos específicos e classes, tbm irei fazer isso, mas a grande questão é o como trabalhar com uma List, cheguei criar um ArrayList porém deu alguns erros.
Outra dúvida é se o rs.next() serve apenas para ler os dados de todas as colunas em uma mesma linha, ou se acabar a linha ele vai começar a próxima linha, como não estou conseguindo usar a List, não consegui fazer esse teste.

Não sei se estou sendo claro o suficiente, ou se estou sendo muito amador, fazendo perguntas “bestas”, qualquer ajuda é bem vinda, agradecido.

Vamos lá, ler a documentação é o ponto chave.
next()
Moves the cursor froward one row from its current position.
https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html
Logo ele vai retornar true enquanto houver registros.

Coloca como você está criando uma lista pra gente ver qual o erro.

Criei esse código, agora esta retornando o que “preciso”, porém agora preciso pensar em um método onde não precise informar campo por campo que quero, e tbm informar o tipo dos dados, por exemplo a digital no banco é armazenado como blob, preciso dar um getByte na coluna 7, caso tiver alguma sugestão, segue o código

public void buscarUsuario(){
        List<String> dados = new ArrayList<>();
        String sql = "SELECT * FROM USUARIO";
        int coluna = 1;
        try {
            pst = conexao.prepareStatement(sql);
            rs = pst.executeQuery();
            while (rs.next())
            {            
                dados.add(rs.getString(1)+";"+rs.getString(2)+";"+rs.getString(3)+";"+rs.getString(4)+";"+rs.getString(5)+";"+rs.getString(6)+";"+rs.getString(7)+";"+rs.getString(8));                
            }
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, e);
        }
        for(String str : dados){
            System.out.println(str);
        }
}

Estou incluindo o “;” para depois usar o split e utilizar os dados separadamente

dei mais uma lida aqui, vou criar uma classe dos usuários, para depois instanciar e criar uma List de objetos, dessa forma acredito que consigo os dados com seus respectivos tipos.

Como está querendo uma lista, deve declarar o método como List. Exemplo

public List<Usuario> buscarUsuario(){
    List<Usuario> usuarios = new ArrayList<>();
    /* a regra de negocio da consulta */
    return usuarios;
}

Uma dica é ao invés de utilizar o * (asterisco), utilize o nome das colunas mesmo que queira trazer tudo, além de ser uma boa prática, deixa o script organizado e fácil de entender e quando for passar no result.getString();, ao invés de passar o numero da coluna, passe o nome, ou seja, os invés de: result.getString(2); utilize result.getString("nome");
NOTA: Usei getString apenas pra nível de exemplo, mas fique atento ao tipo do atributo e coloque o tipo certo. Por exemplo, se fosse id, ficaria result.getInt("id");. E assim por diante.

1 curtida

Opa
O lance de orientação á objetos vai ajudar bastante mas por hora, tente fazer algo do tipo:

Adicione esse import:

import java.util.List

public void buscarUsuario(){
    List<String> usuarios = new ArrayList<String>(); //Lista que vai receber todos os registros da sua query
    String resultado = null;
    String sql = "SELECT * FROM USUARIO";
    try {
	pst = conexao.prepareStatement(sql);
	rs = pst.executeQuery();
	while(rs.next()) { //use o while ao invés de if.. "enquanto" tiver proximo registro..
		resultado = (rs.getString(1)+";" + 
						rs.getString(2)+";" + 
						rs.getString(3)+";" + 
						rs.getString(4)+";" + 
						rs.getString(5)+";" + 
						rs.getString(6)+";" + 
						rs.getString(7)+";" + 
						rs.getString(8));
		usuarios.add(resultado); //adiciona o usuario encontrado na lista
        }
    } catch (SQLException e) {
	JOptionPane.showMessageDialog(null, e);
    }

    //imprime todos os resultados
    for(String r : resultados) {
	System.out.println(r);
    }
}

De fato, não faz sentido esse método ser void… talvez seja interessante alterar o retorno para List (no futuro para List) e retornar a lista ao invés de imprimir no console.

Espero ter ajudado! :slight_smile:

1 curtida

Bom dia galera, fico muito feliz com a quantidade de pessoas colaborando com sugestões construtivas, estou aprendendo muito com vocês…

Voltando ao assunto, hoje após sair do trabalho irei aplicar as sugestões aqui postada e logo darei um feedback, por enquanto fica meu muito obrigado pela ajuda!

Tive uma situação assim algumas semanas atras. Estava trabalhando com ResulSet o que não é uma boa pratica, mas funciona … Assim … criei um metodo que me retonava o ResulSet e na chama tratava com While() … mas não faça isso …

O certo é vc trabalhar com List.

Segue exemplo:

Este é o meu Model:

public class Menu {
    private String perfil;
    private String aplicacao;
    private String descricao;

    public String getPerfil()    { return perfil; }
    public String getAplicacao() { return aplicacao; }
    public String getDescricao() { return descricao; }

    public void setPerfil   (String perfil)    { this.perfil    = perfil; }
    public void setAplicacao(String aplicacao) { this.aplicacao = aplicacao; }
    public void setDescricao(String descricao) { this.descricao = descricao; }
}

Este é o metodo que retorna a Lista:

public static List<Menu> MenuLista() throws Exception{
    List <Menu> lista = new ArrayList();
    Menu obj;
    try {
        Connection conn = Conn.getConnection();
        PreparedStatement ps = conn.prepareStatement("select * from menu order by descricao");
        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
            obj = new Menu();
            obj.setPerfil   (rs.getString("perfil"));
            obj.setAplicacao(rs.getString("aplicacao"));
            obj.setDescricao(rs.getString("descricao"));
            lista.add(obj);
        }            
    } catch (Exception e) {
        return null;
    } finally {
        Conn.desconecta();
    }                
    return lista;
}  

Repare que p método retona um objeto List onde Menu é o meu Model.
Dentro eu declaro outro Objeto List chamado “lista” e um Objeto do tipo Menu, “obj”.
Dentro do laço While instancio o “obj = new Menu()” o vou jogando os campos da tabela. Depois adiciono o resultado na lista "lista.add(obj)"
Ao final eu retorna esta lista, “return lista”

Esse é o código com “foreach”:

        List <Menu> lista = MenuPersist.MenuLista();
        for (Menu menu : lista) {
            JOptionPane.showMessageDialog(null, menu.getDescricao());
        }

"lista " recebe o resultado do “MenuPersist.MenuLista()”
“menu” é um objeto do meu model “Menu” que vai recebendo os valores da “lista” a cada passagem do laço for.

Espero ter ajudado.

1 curtida

@Vonquelbe_Cruz vc não está usando a convenção da linguagem, métodos começam com letra minúscula
E seu método ja retorna uma lista de menu, colocar menu no nome do método fica muito verboso
Sua variável obj pode tranquilamente só existir dentro do laço
E ao invés de retorna nulo, lança uma runtime que é mais elegante, com o getMessage por exemplo

Opa … vlw as dicas …

1 curtida

Opa
O lance de orientação á objetos vai ajudar bastante mas por hora, tente fazer algo do tipo:

Isso é só apenas um exemplo, depois que estiver redondo vou aplicar no meu outro código, a grande intenção disso tudo, é recuperar todos os usuários no banco, para depois fazer uma estrutura de repetição, onde vai ser comparado a DIGITAL que esta no banco banco como BLOB, vou ter que recuperar ela como Bytes, para depois gerar um template usando as classes e métodos do fabricante do leitor biométrico, então seria de muita importância recuperar de acordo com seu tipo, por isso pensei na possibilidade de criar uma lista de objetos.

Perfeito! já tinha feito parecido, porém analisando seu código consegui implementar o meu, ficou da seguinte forma:

//Classe PegaUsuarios

public class PegaUsuarios {

private Connection        conexao = null;
private PreparedStatement pst     = null;
private ResultSet         rs      = null;

public PegaUsuarios(){
conexao = ModuloConexao2.conector();
}

public static void main(String[] args) {
    PegaUsuarios pu = new PegaUsuarios();
    
    List <Usuario> lista = pu.buscarUsuario();
    for (Usuario menu : lista) {
        System.out.println(menu.getDigital());
    }
}

public List buscarUsuario(){
    List<Usuario> dados = new ArrayList<>();
    String sql = "SELECT * FROM USUARIO";
    
    try {
        pst = conexao.prepareStatement(sql);
        rs = pst.executeQuery();
        while (rs.next())
        {   
            Usuario usu = new Usuario(rs.getInt(1), rs.getString(6), rs.getInt(7), rs.getDouble(8));
            dados.add(usu);
        }
    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e);
    }
    return dados;
}

}

//Classe Usuario

public class Usuario {
//1-ID | 2-LOGIN | 3-SENHA | 4-NOME | 5-PERFIL | 6-EMAIL | 7-DIGITAL | 8-CONSUMO PERMITIDO
private int id;
private String email;
private int digital;
private Double consumo;

public Usuario(int id, String email, int digital, Double consumo){
    this.id = id;
    this.email = email;
    this.digital = digital;
    this.consumo = consumo;
}

public int getDigital(){
    return this.digital;
}

Única diferença é que ao invés dos getters e setters, estou usando o construtor da classe Usuario.
Só frisando novamente, isso é apenas um teste, agora irei fazer mais algumas alterações implementar no meu código, e tentar recuperar a informação que é do tipo Byte e fazer suas devidas comparações, muuuuuuuito obrigado a todos pelo empenho em ajudar!