Pessoal,
Criei 3 tabelas (USUARIOS, DISCIPLINAS e NOTAS) c/ seus relacionamentos (chave primaria, estrangeira etc).
Em uma classe NotasDAO, por ex., há 1 método listarNotas que traz: o nome (do usuário que deu a nota), a nota e a disciplina.
Para obter esses dados montei a query com join entre as tabelas (vide abaixo).
Como eu faço para incluir resultSets em uma List proveniente de 2 ou mais tabelas atravé de DAO ?
Segue o trecho do código:
public List<Notas> listaNotas() {
List<Notas> nota = new ArrayList<Notas>();
if (abreConexao()) {
try {
st = cn.prepareStatement("SELECT USUARIO, DISCIPLINA, NOTA "
+ "FROM atividade01.notas y inner join atividade01.usuarios "
+ "on id_usuario=id_aluno inner join atividade01.disciplinas x "
+ "on x.id_disciplina=y.id_disciplina where y.id_aluno=?");
rs = st.executeQuery();
while (rs.next()) {
Notas nt = new Notas();
nt.setUsuario(rs.getString("USUARIO")); //setUsuario e setDisciplina nao existem no bean Notas. O que posso fazer aqui ? Crio 1 bean e
nt.setDisciplina(rs.getString("DISCIPLINA"));//uso o setter dele, por ex. 1 bean que relaciona os atributos das tables envolvidas ?
nt.setNota(rs.getDouble("NOTA"));
nota.add(nt);
}
} catch (Exception ex) {
erro = ex.getMessage();
} finally {
fechaConexao();
}
}
return nota;
}
Se alguém tiver algum exemplo de código seria ótimo.
Agradeço pela atenção.
Não entendi bem a pergunta, afinal, você já faz o add ali não? Bastaria ir adicionando os elementos na lista usando o add da mesma forma que você faz.
Mas eu recomendaria você usar o union all do SQL para diminuir a quantidade de consultas no servidor (isso torna a aplicação mais rápida), e se for uma quantidade muito grande de registros, melhor trabalhar com eles direto no resultSet ao invés de mover a uma List, pois a List está na memória, o resultSet na verdade é um cursor no banco de dados e traz as informações sob demanda.
[quote=evefuji]Não entendi bem a pergunta, afinal, você já faz o add ali não? Bastaria ir adicionando os elementos na lista usando o add da mesma forma que você faz.
Mas eu recomendaria você usar o union all do SQL para diminuir a quantidade de consultas no servidor (isso torna a aplicação mais rápida), e se for uma quantidade muito grande de registros, melhor trabalhar com eles direto no resultSet ao invés de mover a uma List, pois a List está na memória, o resultSet na verdade é um cursor no banco de dados e traz as informações sob demanda.[/quote]
Pensei um pouco mais e fiz o seguinte:
criei um POJO apenas com os atributos alvo (usuario, disciplina e nota).
Depoi criei um Dao de forma que fosse possível usar o set deles e incluí-los na List.
(Inclusive esse ‘mecanismo’ é usado pelo Hibernate).
[code]public class DaoPojoJoin extends Dao {
public List<PojoJoin> listaNotas() {
List<PojoJoin> nota = new ArrayList<PojoJoin>();
if (abreConexao()) {
try {
st = cn.prepareStatement("SELECT USUARIO, DISCIPLINA, NOTA FROM atividade01.notas x "
+ "right outer join atividade01.usuarios y on x.id_aluno=y.id_usuario "
+ "right outer join atividade01.disciplinas z on x.id_disciplina=z.id_disciplina "
+ "where id_aluno=?"); // como fazer p/ filtrar pelo usuário que está logado ? servlet ?
rs = st.executeQuery();
while (rs.next()) {
PojoJoin pj = new PojoJoin();
rs.getString("USUARIO");
rs.getString("DISCIPLINA");
rs.getDouble("NOTA");
pj.setUsuario(rs.getString("USUARIO"));
pj.setDisciplina(rs.getString("DISCIPLINA"));
pj.setNota(rs.getDouble("NOTA"));
nota.add(pj);
}
} catch (Exception ex) {
erro = ex.getMessage();
} finally {
fechaConexao();
}
}
return nota;
}
}
[/code]
Mas agora surgiu outra dúvida: a consulta quando executada no banco está correta, ou seja, obtenho os dados apenas de um determinado aluno (…where id_aluno=?).
Mas quando a consulta é efetuada pela aplicação, a tabela retorna vazia. Creio que o parâmetro (? --> id_aluno que logou) não está sendo passado para fazer a consulta. Como faço pra isso acontecer ? Salvo o atributo da sessão em uma variável ?
a List está vazia porque a consulta não está sendo executada (pelo código que vc postou aí). Provavelmente está dando erro de parâmetro não enviado.
Antes do executeQuery, você tem que passar o parâmetro que deseja, algo assim:
st = cn.prepareStatement("SELECT USUARIO, DISCIPLINA, NOTA FROM atividade01.notas x "
+ "right outer join atividade01.usuarios y on x.id_aluno=y.id_usuario "
+ "right outer join atividade01.disciplinas z on x.id_disciplina=z.id_disciplina "
+ "where id_aluno=?"); // como fazer p/ filtrar pelo usuário que está logado ? servlet ?
st.setInteger(1, idUsuario); // o "1" é o índice que deseja inserir o parâmetro, nesse caso, é o primeiro "?"
rs = st.executeQuery();
Tem vários métodos para inserção de dados nos parâmetros, dá uma olhada aqui na documentação: http://docs.oracle.com/javase/1.4.2/docs/api/java/sql/PreparedStatement.html (documentação antiga, mas não muda essa classe para as versões atuais)
[quote=evefuji]a List está vazia porque a consulta não está sendo executada (pelo código que vc postou aí). Provavelmente está dando erro de parâmetro não enviado.
Antes do executeQuery, você tem que passar o parâmetro que deseja, algo assim:
st = cn.prepareStatement("SELECT USUARIO, DISCIPLINA, NOTA FROM atividade01.notas x "
+ "right outer join atividade01.usuarios y on x.id_aluno=y.id_usuario "
+ "right outer join atividade01.disciplinas z on x.id_disciplina=z.id_disciplina "
+ "where id_aluno=?"); // como fazer p/ filtrar pelo usuário que está logado ? servlet ?
st.setInteger(1, idUsuario); // o "1" é o índice que deseja inserir o parâmetro, nesse caso, é o primeiro "?" --> é setInt(...), só pra te lembrar
rs = st.executeQuery();
Tem vários métodos para inserção de dados nos parâmetros, dá uma olhada aqui na documentação: http://docs.oracle.com/javase/1.4.2/docs/api/java/sql/PreparedStatement.html (documentação antiga, mas não muda essa classe para as versões atuais)[/quote]
É verdade. Li ontem mesmo sobre isso em http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html. Mesmo assim foi bom você me confirmar isso.
Mas agora eu quero settar no prepareStatement o usuário que foi validado pelo servlet.
Como faço para atribuir esse usuário da sessão ? O que posso usar ? st.setString(1,session.getAttribute(nome));
ou st.setString(1,request.getParameter("nome"));
? Ou o que ?
Resumindo, como recupero o nome do usuário da sessão e o transfiro para o preparedStatement no dao ?
Obrigado pela ajuda.
[quote=jMarcel][quote=evefuji]a List está vazia porque a consulta não está sendo executada (pelo código que vc postou aí). Provavelmente está dando erro de parâmetro não enviado.
Antes do executeQuery, você tem que passar o parâmetro que deseja, algo assim:
st = cn.prepareStatement("SELECT USUARIO, DISCIPLINA, NOTA FROM atividade01.notas x "
+ "right outer join atividade01.usuarios y on x.id_aluno=y.id_usuario "
+ "right outer join atividade01.disciplinas z on x.id_disciplina=z.id_disciplina "
+ "where id_aluno=?"); // como fazer p/ filtrar pelo usuário que está logado ? servlet ?
st.setInteger(1, idUsuario); // o "1" é o índice que deseja inserir o parâmetro, nesse caso, é o primeiro "?" --> é setInt(...), só pra te lembrar
rs = st.executeQuery();
Tem vários métodos para inserção de dados nos parâmetros, dá uma olhada aqui na documentação: http://docs.oracle.com/javase/1.4.2/docs/api/java/sql/PreparedStatement.html (documentação antiga, mas não muda essa classe para as versões atuais)[/quote]
É verdade. Li ontem mesmo sobre isso em http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html. Mesmo assim foi bom você me confirmar isso.
Mas agora eu quero settar no prepareStatement o usuário que foi validado pelo servlet.
Como faço para atribuir esse usuário da sessão ? O que posso usar ? st.setString(1,session.getAttribute(nome));
ou st.setString(1,request.getParameter("nome"));
? Ou o que ?
Resumindo, como recupero o nome do usuário da sessão e o transfiro para o preparedStatement no dao ?
Obrigado pela ajuda.[/quote]
Pesquisei e encontrei que através de getRequestDispatcher() é possível passar o controle para um outro recurso ou p/ incluir o conteúdo de um outro recurso no chamador. Estou no caminho certo ? Mas como fazer na prática ?
como vc está colocando o usuário na sessão? Está colocando um objeto de classe, por exemplo, usuário? Se for esse o caso, você precisaria fazer algo como:
st.setInteger(1, ((Usuario)session.getAttribute("usuario logado")).getId()); // Precisa pegar o id do usuário
[quote=evefuji]como vc está colocando o usuário na sessão? Está colocando um objeto de classe, por exemplo, usuário? Se for esse o caso, você precisaria fazer algo como:
st.setInteger(1, ((Usuario)session.getAttribute("usuario logado")).getId()); // Precisa pegar o id do usuário
[/quote]
Estou colocando o usuário na sessão através de um ServletLogin.
O valor de session (=javax.servlet.http.HttpSession) é um request da sessão no parâmetro do método doPost.
Só pra confirmar: o DAO consegue recuperar esse atributo da session se ‘comunicando’ com o webserver, que cria e gerencia a webapp, correto ?
No BD o usuário é uniqueKey, então não tem problema pegar pelo nome do usuário - também.
Eu usei:
Porém não está funcionado. O netbeans não encontra a variável session e sugere criar uma classe session no pacote.
O que posso fazer ?
Pode colocar o trecho que está colocando o usuário na sessão?
Está usando que framework mvc? Se estiver direto no servlet, você pode buscar o session assim: