Boa tarde pessoal, tudo bem?
Estou praticando em um projetinho pessoal com JDBC e MySql onde tenho uma tabela Pessoa e outra tabela Telefone, e o id de Pessoa é chave estrangeira em Telefone…
É uma relação de 0 para N pois uma pessoa pode ter 0 ou varios telefones…
Quando eu for criar as entidades, na classe Pessoa eu terei uma lista de telefones correto!? Agora vem a dúvida, na classe Telefone eu preciso criar uma relação (composição) com a classe Pessoa ou posso simplesmente criar um váriavel Integer para pegar o id da Pessoa?
Não precisa criar nada adicional na tabela Telefone.
Com o SELECT você vai consegur saber quem eh o dono do telefone, usando a chave primária do mesmo e fazendo um INNER JOIN até a tabela Pessoa.
Minha dúvida é sobre as entidades no Java, pq eu posso fazer a classe Telefone receber somente uma váriavel Integer/Int recebendo o Id ou posso fazer ela receber um objeto Pessoa.
Basicamente assim: Um Pessoa tem uma Lista de Telefone e um Telefone tem uma Pessoa
A tabela basicamente seria assim:
As Classes em Java:
package db;
import java.util.List;
public class Cliente {
private Integer codigo;
private String nome;
private List<Telefone> telefone;
public Integer getCodigo() {
return codigo;
}
public void setCodigo(Integer codigo) {
this.codigo = codigo;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public List<Telefone> getTelefone() {
return telefone;
}
public void setTelefone(List<Telefone> telefone) {
this.telefone = telefone;
}
}
package db;
public class Telefone {
private Integer codigo;
private String ddd;
private String numero;
private Cliente cliente;
public Integer getCodigo() {
return codigo;
}
public void setCodigo(Integer codigo) {
this.codigo = codigo;
}
public String getDdd() {
return ddd;
}
public void setDdd(String ddd) {
this.ddd = ddd;
}
public String getNumero() {
return numero;
}
public void setNumero(String numero) {
this.numero = numero;
}
public Cliente getCliente() {
return cliente;
}
public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
}
Isso é um exemplo mediante a suas duvidas, talvez tenha maiores duvidas.
Foi assim mesmo que eu fiz!
Agora estou tendo problema pra montar os objetos, está dando um erro de “StackOverflowError”. Estou fazendo assim:
@Override
public List<Pessoa> findAll() {
PreparedStatement st = null;
ResultSet rs = null;
try {
st = connection.prepareStatement("SELECT P.*, T.id as idTelefone, T.idPessoa "
+ "FROM pessoa P "
+ "INNER JOIN telefone T "
+ "ON P.id = T.idPessoa "
+ "GROUP BY T.idPessoa;");
rs = st.executeQuery();
List<Pessoa> list = new ArrayList<>();
Map<Integer, Categoria> mapCategoria = new HashMap<>();
Map<Integer, Endereco> mapEndereco= new HashMap<>();
while (rs.next()) {
Categoria categoria = mapCategoria.get(rs.getInt("idCategoria"));
Endereco endereco = mapEndereco.get(rs.getInt("idEndereco"));
if(categoria == null) {
categoria = DaoFactory.createCategoriaDAO().findById(rs.getInt("idCategoria"));
mapCategoria.put(rs.getInt("idCategoria"), categoria);
}
if (endereco == null) {
endereco = DaoFactory.createEnderecoDAO().findById(rs.getInt("idEndereco"));
mapEndereco.put(rs.getInt("idCategoria"), endereco);
}
Pessoa pessoa = instanciaPessoa(rs, endereco, categoria);
list.add(pessoa);
}
return list;
} catch (SQLException e) {
throw new DbException(e.getMessage());
} finally {
DB.closeStatement(st);
DB.closeResultSet(rs);
}
}
public Pessoa instanciaPessoa(ResultSet rs, Endereco end, Categoria cat) throws SQLException {
Pessoa obj = new Pessoa();
obj.setId(rs.getInt("id"));
obj.setNome(rs.getString("nome"));
obj.setApelido(rs.getString("apelido"));
obj.setEmail(rs.getString("email"));
obj.setCpf(rs.getString("cpf"));
obj.setSexo(rs.getString("sexo"));
obj.setData_cadastro(rs.getDate("data_cadastro"));
obj.setCategoria(cat);
obj.setEndereco(end);
List<Telefone> listTelefone = new ArrayList<>();
listTelefone = DaoFactory.createTelefoneDao().findByPessoa(obj);
listTelefone.stream().forEach(System.out::println);
for (Telefone telefone : listTelefone) {
if (telefone != null) {
obj.addTelefone(telefone);
}
}
return obj;
}
@Override
public List<Telefone> findByPessoa(Pessoa pessoa) {
PreparedStatement st = null;
ResultSet rs = null;
try {
st = connection.prepareStatement("SELECT * from Telefone WHERE idPessoa = ?");
st.setInt(1, pessoa.getId());
rs = st.executeQuery();
List<Telefone> list = new ArrayList<>();
while (rs.next()) {
list.add(instanciaTelefone(rs,pessoa));
}
return list;
} catch (SQLException e) {
throw new DbException(e.getMessage());
} finally {
DB.closeStatement(st);
DB.closeResultSet(rs);
}
}
public Telefone instanciaTelefone(ResultSet rs, Pessoa pessoa) throws SQLException {
Telefone obj = new Telefone();
obj.setId(rs.getInt("id"));
obj.setDdd(rs.getString("ddd"));
obj.setNumero(rs.getString("numero"));
obj.setTipo(rs.getString("tipo"));
obj.setPessoa(pessoa);
pessoa.addTelefone(obj);
return obj;
}
Olha tem código misturado, chamando System.out::println
no meio do método totalmente estranho neh!
É outro situação, o que foi perguntado foi explicado para você agora se precisa trazer os dados da base e relacionador, agrupar também, porque faz úm INNER JOIN
…
Tem várias formas de fazer isso, dependo do seu entendimento, mas, o seu código tem erros que eu já precitei!
O println ali é pq eu tava testando para ver o que tava ocasionando o erro e por incrivel que parece era o toString que estava causando o erro, alterei ele e agora aparentemente está funcionando.
Sobre o Inner Join tb irei remove e fazer um select simples na tabela Pessoa, acontece que antes eu estava usando metodos para instanciar os objetos de Endereco e Categoria.
Entendi, eu faria um SQL para buscar as pessoas e depois um outra SQL com o operador In com todos os Pessoas trazidas na primeira SQL e trocaria mensagem entre as classes.
amigo me ajude também
[Trazer dados de 2 tabelas (Usuario e Telefone) JAVA E SQL - #3 por Ian_Santos]