Qual seria a forma correta de percorrer a lista e retornar os dados?
41 respostas
javaprogramação
P
PRXGRVMVDXR
boa tarde. por estar iniciando, não consegui compreender como irei setar a “Pessoa” e retornar ela na lista “Pedido” …
publicList<Pedido>findById(LongidCliente)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido WHERE idCliente = ?")){psmt.setLong(1,idCliente);// parâmetro da queryPessoapessoa=newPessoa();pessoa.setId(1);try(ResultSetrs=psmt.executeQuery()){finalList<Pedido>pedidos=newArrayList<>();while(rs.next()){finalPedidopedido=newPedido().setId(rs.getLong("id")).setPessoa(pessoa);pedidos.add(pedido);}returnpedidos;}}}
desta forma não esta retornando os dados da Pessoa.
Da mesma forma que você tem esse findById() para busca os dados do pedido, eu imagino que você tenha um método pra chamar o cliente, certo? Seria o caso de usá-lo da mesma forma:
publicList<Pedido>findById(LongidCliente)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido WHERE idCliente = ?")){psmt.setLong(1,idCliente);// parâmetro da queryPessoapessoa=ClienteRepository.findById(idCliente);// retorna o cliente pelo id
ou mesmo passar o cliente já preenchido para esse método que busca os pedidos. Algo como:
// O parâmetro é alterado para uma instância de Pessoa/ClientepublicList<Pedido>findById(Pessoapessoa)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido WHERE idCliente = ?")){psmt.setLong(1,pessoa.getId());// parâmetro da query// o Pessoa pessoa = new Pessoa(); é totalmente removido, já que já está preenchido.
Abraço.
P
PRXGRVMVDXR
Obrigado pela resposta;
Neste exemplo em questão, não utilizo Repository, é utilizado DAO.
E no caso, eu tenho a entidade Pedido e Pessoa.
Na classe pedido, tenho minha classe pessoa desta forma: private Pessoa pessoa;
ao retornar a lista, teria que entender que tal pedido seria de tal pessoa… não sei se consegui ser mt claro.
staroski
Então você vai ter que primeiro fazer um select na tabela de Pessoa para encontrar a pessoa com o mesmo id do idPessoa no pedido.
Depois seta a pessoa encontrada no objeto Pedido que você está montando.
P
PRXGRVMVDXR
montei a query em PessoaDAO:
publicPessoafindById(Longid)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pessoa WHERE id = ?")){try(ResultSetrs=psmt.executeQuery()){psmt.setLong(1,id);// parâmetro da queryPessoapessoa=newPessoa().setId(rs.getLong("id")).setNome(rs.getString("nome")).setCpf(rs.getString("cpf"));returnpessoa;}}}
porém não estou sabendo como implementar corretamente na classe PedidoDAO, para montar a lista
staroski
Pessoapessoa=pessoaDao.findById(idCliente);
P
PRXGRVMVDXR
fiz desta forma,
PedidoDAO:
publicclassPedidoDAOextendsDAO{PessoaDAOpessoaDao;publicPedidoDAO(finalConnectionconnection){super(connection);}publicList<Pedido>findById(LongidCliente)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido WHERE idCliente = ?")){psmt.setLong(1,idCliente);// parâmetro da queryPessoapessoa=pessoaDao.findById(idCliente);try(ResultSetrs=psmt.executeQuery()){finalList<Pedido>pedidos=newArrayList<>();while(rs.next()){finalPedidopedido=newPedido().setId(rs.getLong("id")).setPessoa(pessoa);//.setItens(pedidosItem);pedidos.add(pedido);}returnpedidos;}}}}
PessoaDAO:
publicclassPessoaDAOextendsDAO{publicPessoaDAO(finalConnectionconnection){super(connection);}publicPessoafindById(Longid)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pessoa WHERE id = ?")){try(ResultSetrs=psmt.executeQuery()){psmt.setLong(1,id);// parâmetro da queryfinalPessoapessoa=newPessoa().setId(rs.getLong("id")).setNome(rs.getString("nome")).setCpf(rs.getString("cpf"));returnpessoa;}}}}
porém me retorna o erro: Cannot invoke "br.com.desafio.desafio.dao.PessoaDAO.findById(java.lang.Long)" because "this.pessoaDao" is null
staroski
A mensagem está bem clara, você não inicializou o atributo pessoaDao.
P
PRXGRVMVDXR
entendo… é que no caso tentei: PessoaDAO pessoaDao = new PessoaDAO();
porém como a classe pede os argumentos de conexão, não sei como seria a forma correta de implementar… comecei a mexer agora com este padrão DAO, e ainda estou um pouco confuso
staroski
Como é que você instância o PedidoDao?
Vai ser da mesma forma.
que mancada, não me atentei nisso… vou fazer os testes assim que possível.
P
PRXGRVMVDXR
bom dia!
gostaria de agradecer sua ajuda!! consegui retornar a lista de clientes deste pedido.
porém agora preciso retornar uma lista com os itens deste pedido. Pelo que entendi, terei que retornar uma lista de PedidoItem, exemplo:
SELECT * FROM pedidoItem WHERE idPedido = ?
em PedidoItem estão as classes:
privateProdutoproduto;privatePedidopedido;
porém não vejo uma forma de fazer isto pois são parâmetros diferentes, e é enviado apenas 1 na URL.
P
PRXGRVMVDXR
Em PedidoItemDAO fiz o seguinte:
publicList<PedidoItem>findByPedido()throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedidoItem pe LEFT JOIN pedido p ON pe.id = p.id")){try(ResultSetrs=psmt.executeQuery()){finalList<PedidoItem>itensPedido=newArrayList<>();while(rs.next()){finalPedidoItemitem=newPedidoItem().setId(rs.getLong("id"))//.setProduto(null).setQuantidade(rs.getInt("qntd"));//.setPedido(null); itensPedido.add(item);}returnitensPedido;}}}
aparentemente esta retornando correto, oq resta é setar o Produto e Pedido de acordo
TerraSkilll1 like
Se a tabela de PedidoItem tem uma coluna para o id do pedido, você não precisa desse left join, pode fazer o select direto na tabela de pedidoItem. Também está faltando um parâmetro para definir de qual pedido você quer carregar. Da forma como está, está carregando todos os itens de todos os pedidos.
Se a ideia desse método é carregar os itens de um pedido que você já tem carregado, eu somente passaria a instância dele para o método, em vez de ter o trabalho de carregar de novo. E, para os dados do produto, você precisa de um DAO pra carregá-lo, da mesma forma que já vem fazendo. Algo como:
publicList<PedidoItem>findByPedido(Pedidopedido)throwsSQLException{List<PedidoItem>itensPedido=newArrayList<>();ProdutoDAOprodutoDao=newProdutoDAO(getConnection());// dao de consulta a produtos, similar aos demaisPreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedidoItem pe WHERE pe.id = ?");psmt.setLong(1,pedido.getId());try(ResultSetrs=psmt.executeQuery()){while(rs.next()){finalPedidoItemitem=newPedidoItem().setId(rs.getLong("id")).setProduto(produtoDao.findById(rs.getLong("id_produto")))// usa o dao de produto pra buscar o produto pelo id_produto da tabela pedido_item.setQuantidade(rs.getInt("qntd"));.setPedido(pedido);// usa o pedidoitensPedido.add(item);}}returnitensPedido;}
Abraço.
P
PRXGRVMVDXR
muito obrigado!
acho que consegui compreender oq disse… porém não estou sabendo ao certo, como vou instanciar o Pedido corretamente
P
PRXGRVMVDXR
no caso, esta lista que fiz, é para retornar todos os itens do pedido, pois nesta consulta tenho o idProduto… e a cada vez que passar no while, cria um novo produto, para setar ele na lista.
publicList<PedidoItem>findByPedido()throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedidoItem pi LEFT JOIN pedido p ON pi.id = p.id")){try(ResultSetrs=psmt.executeQuery()){finalList<PedidoItem>itensPedido=newArrayList<>();while(rs.next()){Produtoproduto=produtoDao.findById(rs.getLong("idProduto"));finalPedidoItemitem=newPedidoItem().setId(rs.getLong("id")).setProduto(produto).setQuantidade(rs.getInt("qntd"));//.setPedido(null); itensPedido.add(item);}returnitensPedido;}}}
staroski
Não é o seu PedidoDAO quem carrega os pedidos do banco?
É só você usar seu PesidoDAO para obter o pedido e passar ele como parâmetro como o @TerraSkilll ensinou.
P
PRXGRVMVDXR
Em PedidoDAO, carrego uma lista com todos os pedidos e todos os pedidos por idCliente, terei que criar um que retorne somente o pedido específico?
PedidoDAO até o momento:
publicList<Pedido>findAll()throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido")){try(ResultSetrs=psmt.executeQuery()){finalList<Pedido>pedidos=newArrayList<>();while(rs.next()){finalPedidopedido=newPedido().setId(rs.getLong("id"));pedidos.add(pedido);}returnpedidos;}}}publicList<Pedido>findByIdCliente(LongidCliente)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido WHERE idCliente = ?")){psmt.clearParameters();psmt.setLong(1,idCliente);// parâmetro da queryPessoapessoa=pessoaDao.findById(idCliente);List<PedidoItem>itensPedido=pedidoItemDao.findByPedido();try(ResultSetrs=psmt.executeQuery()){finalList<Pedido>pedidos=newArrayList<>();while(rs.next()){finalPedidopedido=newPedido().setId(rs.getLong("id")).setPessoa(pessoa).setItens(itensPedido);pedidos.add(pedido);}returnpedidos;}}}
P
PRXGRVMVDXR
Em PedidoDAO preciso do seguinte:
publicList<Pedido>findByIdCliente(LongidCliente)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido WHERE idCliente = ?")){psmt.clearParameters();psmt.setLong(1,idCliente);// parâmetro da queryPessoapessoa=pessoaDao.findById(idCliente);List<PedidoItem>itensPedido=pedidoItemDao.findByPedido();// consulta do PedidoItemDAOtry(ResultSetrs=psmt.executeQuery()){finalList<Pedido>pedidos=newArrayList<>();while(rs.next()){finalPedidopedido=newPedido().setId(rs.getLong("id")).setPessoa(pessoa).setItens(itensPedido);pedidos.add(pedido);}returnpedidos;}}}
devido a eu precisar de uma lista dos itens do Pedido, montei a consulta citada acima.
staroski
Essa consulta me parece errada!
Se o método se chama findByPedido, você deveria passar o pedido como parâmetro para ele trazer os itens daquele pedido, como o @TerraSkilll já explicou lá em cima, pôxa, tem que prestar atenção no que os coleguinhas te passam no fórum.
Depois que você arrumar o método pra receber o pedido como parâmetro, provavelmente seu código vai ficar mais ou menos assim:
publicList<Pedido>findByIdCliente(LongidCliente)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido WHERE idCliente = ?")){psmt.clearParameters();psmt.setLong(1,idCliente);// parâmetro da queryPessoapessoa=pessoaDao.findById(idCliente);try(ResultSetrs=psmt.executeQuery()){finalList<Pedido>pedidos=newArrayList<>();while(rs.next()){finalPedidopedido=newPedido().setId(rs.getLong("id")).setPessoa(pessoa);finalList<PedidoItem>itensPedido=pedidoItemDao.findByPedido(pedido);// consulta do PedidoItemDAOpedido.setItens(itensPedido);pedidos.add(pedido);}returnpedidos;}}}
P
PRXGRVMVDXR
sim, concordo, estou prestando bem atenção, porém como migrei do Delphi para o Java, muitas coisas ainda são confusas, e vou aprendendo no dia a dia… e oq realmente não estou conseguindo é fazer o método receber o pedido como parâmetro… mas irei tentar fazer as alterações.
P
PRXGRVMVDXR
Foi necessário passar o Pedido como parâmetro no Service e Controller;
E meu PedidoDAO fiz desta forma:
publicList<Pedido>findByIdCliente(LongidCliente,Pedidopedido)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido WHERE idCliente = ?")){psmt.clearParameters();psmt.setLong(1,idCliente);// parâmetro da queryPessoapessoa=pessoaDao.findById(idCliente);//List<PedidoItem> itensPedido = pedidoItemDao.findByPedido();try(ResultSetrs=psmt.executeQuery()){finalList<Pedido>pedidos=newArrayList<>();while(rs.next()){//final Pedido pedido = new Pedido()pedido.setId(rs.getLong("id"));pedido.setPessoa(pessoa);finalList<PedidoItem>itensPedido=pedidoItemDao.findByPedido(pedido);// consulta do PedidoItemDAOpedido.setItens(itensPedido);pedidos.add(pedido);}returnpedidos;}}}
porém tenho um retorno estranho, at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
pesquisei sobre este erro, mas até o momento não consegui localizar o motivo.
Lucas_Camara
Não acho que vc precisaria passar o Pedido como parâmetro da forma como vc fez. Se a ideia é recuperar todos os pedidos de um determinado cliente, apenas o ID do cliente é necessário.
Tentei refazer esse método de uma forma que faz mais sentido pra mim, de acordo com o que to entendendo do seu código:
publicList<Pedido>findPedidosByIdCliente(LongidCliente)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido WHERE idCliente = ?");ResultSetrs=psmt.executeQuery()){// Recupera o cliente pelo IDpsmt.setLong(1,idCliente);Pessoapessoa=pessoaDao.findById(idCliente);// Lista de pedidos do clienteList<Pedido>pedidos=newArrayList<>();while(rs.next()){Pedidopedido=newPedido();pedido.setId(rs.getLong("id"));pedido.setPessoa(pessoa);// Recupera os itens do pedidoList<PedidoItem>itensPedido=pedidoItemDao.findByPedido(pedido);pedido.setItens(itensPedido);pedidos.add(pedido);}returnpedidos;}}
Posta como que está o método findByPedido da classe PedidoItemDao pra gente ver.
P
PRXGRVMVDXR
opa, boa noite!
publicList<PedidoItem>findByPedido(Pedidopedido)throwsSQLException{List<PedidoItem>itensPedido=newArrayList<>();ProdutoDAOprodutoDao=newProdutoDAO(getConnection());PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedidoItem WHERE id = ?");psmt.setLong(1,pedido.getId());try(ResultSetrs=psmt.executeQuery()){while(rs.next()){finalPedidoItemitem=newPedidoItem().setId(rs.getLong("id")).setProduto(produtoDao.findById(rs.getLong("idProduto")))// usa o dao de produto pra buscar o produto pelo idProduto da tabela PedidoItem.setQuantidade(rs.getInt("qntd")).setPedido(pedido);// usa o pedidoitensPedido.add(item);}}returnitensPedido;}
P
PRXGRVMVDXR
qndo eu estava testando sem parâmetros:
PedidoItemDAO:
publicList<PedidoItem>findByPedido()throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedidoItem pi LEFT JOIN pedido p ON pi.id = p.id")){try(ResultSetrs=psmt.executeQuery()){finalList<PedidoItem>itensPedido=newArrayList<>();while(rs.next()){Produtoproduto=produtoDao.findById(rs.getLong("idProduto"));finalPedidoItemitem=newPedidoItem().setId(rs.getLong("id")).setProduto(produto).setQuantidade(rs.getInt("qntd"));//.setPedido(pedido); itensPedido.add(item);}returnitensPedido;}}}
PedidoDAO:
publicList<Pedido>findByIdCliente(LongidCliente)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido WHERE idCliente = ?")){psmt.clearParameters();psmt.setLong(1,idCliente);// parâmetro da queryPessoapessoa=pessoaDao.findById(idCliente);List<PedidoItem>itensPedido=pedidoItemDao.findByPedido();try(ResultSetrs=psmt.executeQuery()){finalList<Pedido>pedidos=newArrayList<>();while(rs.next()){finalPedidopedido=newPedido().setId(rs.getLong("id")).setPessoa(pessoa).setItens(itensPedido);pedidos.add(pedido);}returnpedidos;}}}
Lucas_Camara
E do jeito que tá agora, tah funcionando?
P
PRXGRVMVDXR
é que no caso, como o colega explicou acima, em PedidoItemDAO, eu tenho uma consulta por pedido e teria que ficar assim:
publicList<PedidoItem>findByPedido(Pedidopedido)throwsSQLException{List<PedidoItem>itensPedido=newArrayList<>();ProdutoDAOprodutoDao=newProdutoDAO(getConnection());// dao de consulta a produtos, similar aos demaisPreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedidoItem pe WHERE pe.id = ?");psmt.setLong(1,pedido.getId());try(ResultSetrs=psmt.executeQuery()){while(rs.next()){finalPedidoItemitem=newPedidoItem().setId(rs.getLong("id")).setProduto(produtoDao.findById(rs.getLong("id_produto")))// usa o dao de produto pra buscar o produto pelo id_produto da tabela pedido_item.setQuantidade(rs.getInt("qntd"));.setPedido(pedido);// usa o pedidoitensPedido.add(item);}}returnitensPedido;}
porém eu nao estou sabendo instanciar o pedido, para receber a ID e setar ela como parâmetro na query
Lucas_Camara
Mas vc já está fazendo isso aqui. Nessa parte vc recupera os pedidos do banco e cria o Pedido com o ID setado. Depois disso, só chamar o método que recupera os itens. Não é isso?
P
PRXGRVMVDXR
posso estar me perdendo em alguma parte… vou analisar melhor e tentar implementar
P
PRXGRVMVDXR
Tentei desta forma:
PedidoDAO:
publicList<Pedido>findPedidosByIdCliente(LongidCliente)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido WHERE idCliente = ?")){// Recupera o cliente pelo IDpsmt.setLong(1,idCliente);try(ResultSetrs=psmt.executeQuery()){Pessoapessoa=pessoaDao.findById(idCliente);// Lista de pedidos do clienteList<Pedido>pedidos=newArrayList<>();while(rs.next()){Pedidopedido=newPedido();pedido.setId(rs.getLong("id"));pedido.setPessoa(pessoa);// Recupera os itens do pedidoList<PedidoItem>itensPedido=pedidoItemDao.findByPedido(pedido);pedido.setItens(itensPedido);pedidos.add(pedido);}returnpedidos;}}}
PedidoItemDAO:
publicList<PedidoItem>findByPedido(Pedidopedido)throwsSQLException{List<PedidoItem>itensPedido=newArrayList<>();ProdutoDAOprodutoDao=newProdutoDAO(getConnection());PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedidoItem WHERE id = ?");psmt.setLong(1,pedido.getId());try(ResultSetrs=psmt.executeQuery()){while(rs.next()){finalPedidoItemitem=newPedidoItem().setId(rs.getLong("id")).setProduto(produtoDao.findById(rs.getLong("idProduto"))).setQuantidade(rs.getInt("qntd")).setPedido(pedido);// usa o pedidoitensPedido.add(item);}}returnitensPedido;}
publicList<Pedido>findByIdCliente(LongidCliente)throwsSQLException{try(PreparedStatementpsmt=getConnection().prepareStatement("SELECT * FROM pedido WHERE idCliente = ?")){psmt.clearParameters();psmt.setLong(1,idCliente);// parâmetro da queryPessoapessoa=pessoaDao.findById(idCliente);try(ResultSetrs=psmt.executeQuery()){finalList<Pedido>pedidos=newArrayList<>();while(rs.next()){// instanciando o pedidofinalPedidopedido=newPedido().setId(rs.getLong("id")).setPessoa(pessoa);// carregando os itens do pedidofinalList<PedidoItem>itensPedido=pedidoItemDao.findByPedido(pedido);// consulta do PedidoItemDAO// setando os itens no pedidopedido.setItens(itensPedido);// adicionando o pedido na listapedidos.add(pedido);}returnpedidos;}}}
staroski
Tá, mas esse erro aí não é nas suas consultas, em que momento que acontece esse erro?
P
PRXGRVMVDXR
esse retorno é quando bate no endpoint para listar por cliente. estou trabalhando só no backend e testando via localhost:8080…
Lucas_Camara1 like
Pode ser erro de referência circular, pois há um Pedido no PedidoItem e uma lista de PedidoItem no Pedido. Com isso, ao serializar pra json, dá problema. Faça um teste deixando o Pedido de cada PedidoItem como null e veja o que acontece.
P
PRXGRVMVDXR
limpei a tabela PedidoItem, e realmente, o erro não ocorreu.
Lucas_Camara
Repare que não é deixar null no banco, mas sim na hora de criar as instâncias no código da aplicação.
P
PRXGRVMVDXR
dsclp o engano…
alterei para: pedido.setItens(null);
e o erro não ocorreu tbm;
wallacecampanha1 like
Saudações meu querido!
Você precisa abrir o Objeto PEDIDO antes ou depois de iniciar o WHILE, se nao vc estará abrindo um novo objeto pedido enquanto estiver rodando o WHILE.
Dentro do while, armazene os dados recebidos do banco em variáveis declaradas anteriormente.
Depois insira as variáveis no Objeto PEDIDO.
P
PRXGRVMVDXR1 like
mt obrigado pela ajuda!!
tentei pensar em algo para implementar desta forma, mas ainda não surgiu a ideia… seguirei tentando
wallacecampanha1 like
Meu amigo, esse vídeo explica de uma forma melhor, utilizando o for.
De uma olhada e nos responda se deu certo.