ArrayList, Classe de objetos ou whiles do resultset

Galera, me deparei com uma situação meio estranha, pois não consigo achar a melhor solução para meu problema, é simples:

Tenho 3 tabelas:

usuario
empresa
permissao

Funciona assim:

empresa {cod_empresa, nome}
permissao {cod_permissao, descricao}
usuario {cod_usuario, login, senha, cod_empresa, cod_permissao}

Um usuario tem um login, uma senha, uma empresa vinculada e uma permissão.

Estou fazendo uma tela de login para o meu sistema, nesta tela, tenho os seguintes campos, bem simples:

Empresa: (combo que lista as empresas da tabela empresa)
Usuário: (combo que teria que mostrar os usuários vinculados na tabela empresa)
Senha: (campo de senha)

O que eu não consigo achar a melhor solução, é para o seguinte fato:

Quando eu abro a tela de login, automaticamente lista no combobox as empresas da tabela empresa, para que o usuário selecione a sua respectiva empresa cadastrada.
Eu gostaria de listar no combo Usuarios, todos os usuários referentes a empresa que a pessoa selecionou.
Mas para isso eu tenho que pegar o código da empresa que o cara selecionou (no combo tem apenas o nome) e comparar com os códigos da tabela usuário, para listar os usuários que tem vinculado com a empresa selecionada.
Eu pensei em criar uma classe Empresa com get e set para armazenar as empresas, e depois comparar pelo codigo de cada objeto, mas também posso criar um ArrayList com os nomes e códigos, ou uma gambiarra de selects armazenando os códigos em variáveis, simplismente não sei o que fazer…

Se alguém entendeu e tiver uma solução acessível, espero que comentem… hehe, abraço

postando minha solução, peguei o object selecionado no combo (no meu caso o nome), fui até a tabela que contem os dados, dei um select where nome=nomeselecionado e rotorno o código deste nome.

Ué, e se você tiver 2 nomes iguais?

Sempre faça buscas por ID. É mais eficiente e evita problemas desse tipo.

Vini, primeiro que na aplicação que não deixo gravar dois nomes
e segundo, se eu mostrar os códigos no combo, o cara não vai saber do que se trata, precisa mostrar o nome junto, foi aí que criei este tópico.

eu mostrava no combobox o id + nome

assim:

combobox.addItem(“Id:”+id+ "Nome: "+nome);

no combo ficava assim:

01 Claro
02 Vivo
03 Tim

porém, quando eu selecionava a opção desejada, o combo no getSelectedItem() me retorna um Object, contendo ID e Nome.
eu precisava pegar esse id do object retornado, mas não achei uma forma de “quebra-lo” pegando apena so id ou apena so nome, me entendeu?
A única forma que eu consegui fazer isso foi peloes selects, claro, se houver redundância, estou ferrado, e outra que para uma situação simples, ao meu ver ficar fazendo selects não é o correto, mas foi a minha saída, se vc sabe algum jeito de “quebrar” o Object para mim pegar o id, ou algo mais fácil, espero que me ajude. Abraço.

E qual é o problema de exibir o nome, mas procurar pelo código?

Se sua aplicação for desktop, basta que o toString() da classe que vai dentro da combo retorne o nome. Mas nada impede você de pegar o objeto de lá e perguntar o id dele.
Se sua aplicação for web, também é possível associar a cada texto do combo um valor, que pode ser o id.

É muito mais eficiente fazer buscas pela chave primária.

Ah, entendi. No seu combo você está colocando Strings. Mas a Combo do java não é limitada a Strings.

Vamos supor que a combo seja de empresas. Você pode fazer:

combo.addItem(new Empresa(id, nome));

E depois, no getSelectedItem:

Empresa selecionada = (Empresa)combo.getSelectedItem();

O que o combo exibe? O resultado do método toString() da clase empresa. Portanto, é só faze-lo assim:

[code]public class Empresa {
//resto da classe aqui

@Override
public void toString() {
return getNome();
}
}[/code]

Isso é até mais prático, pois você deve ter um DAO que retorna uma lista de empresas, não?

Vini, eu estou populando o combo direto do banco, ou seja, pelo resultset rs.getInt(“cod_empresa”); e rs.getString(“nome”);

então, no while(rs.next) já vai populando o combo, mas nada empede de criar uma classe empresa, com um arraylist e fazer desta forma, porém creio que também posso fazer da forma atual populando direto do banco no cambo, só que no getSelectedItem ele vem um Object, entende…

eu jogo nele um Id e Nome e ele me retorna um Object, e eu queria pegar somente o id…

Sim, popular direto do banco tem essa desvantagem.
Aí você só vai conseguir jogar uma String lá dentro (o object retornado será do tipo String).

Nesse caso, não resta muita escolha a não ser procurar mesmo pelo nome… mesmo isso sendo um tanto ineficiente.

Agora, é bom você saber que é possível usar o combo com objetos, pois nem sempre você poderá limitar o usuário a não colocar nomes idênticos (imagine um combo de pessoas, por exemplo).

Na prática, o ideal mesmo seria você criar a classe EmpresaDAO, e deixar que ela lesse do banco e criasse para você um List<Empresa>. O DAO é o cara que faz a ponte entre o mundo do banco de dados, e os objetos de negócio.

Sua combo poderia ser diretamente populada pela classe empresa, que conteria ID, endereço e outros dados não exibidos.

Como escrever DAOs é um tanto trabalhoso, algumas pessoas preferem delegar esse trabalho a um framework ORM, como o Hibernate.

exatamente Vini, por isso abri está tópico, creio que muitos programadores se deparam com esta situação, eu tenho uma modelagem com 72 tabelas, e quase todas serão integradas com combobox, agora imagine eu criar uma classe DAO para cada dado que eu quiser mostrar nos combos, eu iria ter mais de 100 classes DAO para população de dados por classe, por outro lado, se eu optar por usar a população diretamente do banco, o mesmo incoveniente me ocorre com as redundâncias de SQL de busca… Sinceramente, não sei qual usar, por ser mais rápido, optei pelos SQL’s diretos do banco… Espero que esse tópico ajudem mais programadores e que cada um use o que achar melhor pra si ;(

Entendo. As vezes é mais fácil usar uma abordagem próxima da estruturada mesmo, principalmente se o sistema não foi originalmente feito com muita modelagem OO.
Você então pode só criar uma classezinha auxiliar.

[code]public class ItemCombo {
private int valor;
private String texto;

public ItemCombo(int valor, String texto) {
   this.valor = valor;
   this.texto = texto;
}

public int getValor() { return valor; }
public String getTexto() { return texto; }

@Override
public String toString() {
return getTexto();
}
}[/code]

E aí preencher seu combo assim:

combo.addItem(new ItemCombo(rs.getInt("idEmpresa"), rs.getString("nomeEmpresa")));

E, depois, na hora de carregar:

ItemCombo item = combo.getSelectedItem(); int id = item.getValor();

Já fica melhor do que só jogar a String no combo. E não fica tão trabalhoso quanto montar uma classe DAO por tabela.

Sem falar, que muitas vezes isso vai evitar totalmente que você tenha que fazer uma nova consulta ao banco, só para descobrir esse id.

boa Vini, criar uma classe intermediária entre banco e combo, dessa forma vou conseguri pegar os dados separados mesmo, vou tentar implementar em todos os combos, depois posto o resultado.

Cara, ao implementar percebi que caimos no mesmo problema da implementação de classes para cada informação do banco, pois para cada combo terei que criar a classe ItemCombo, hehe, não resolve muito… Se os combos tivessem sempre os mesmos atributos recebidos, tudo bem, mas são quase sempre diferentes… ;x

No caso, você deixaria o ItemCombo somente com id e valor mesmo.
É só um quebra-galho para não usar Strings (melhor ter String e Id do que só a String).

suponhamos que eu tenha 4 combos em um JFrame, e no meu projeto existam 50 JFrame’s, será que vou conseguir usar a mesma classe para todos os combos, sabendo que uns 10 a 12 combos serão carregados simultaneamente?

cara da uma olhada, quando eu vou pegar as infos do combo com o código:

        ItemCombo item = (ItemCombo) auth_empresa.getSelectedItem();   
        int id = item.getId(); 

ele me pediu para fazer o CAST, eu fiz e ficou assim…

porém o

item.getId();

da NullPointerException…