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)
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:
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.
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.
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.
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.
@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
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!