Tenho que fazer uma consulta no banco (DAO), mas os campos que eu devo pesquisar (que vão no SELECT, NÃO no where) são dinâmicos.
A pessoa vai selecionar os campos (checkbox) e devo retornar para a tela os resultados apenas dos campos selecionados, não dos demais.
Dúvida:
Qual o melhor jeito de fazer isso? Retornar todos os dados (colocando todos os campos para pesquisar no banco) e tentar tratar no JSP (com JSTL?) ou fazer um alguma maneira de montar o SELECT com stringbuilder por exemplo?
Tenho que fazer uma consulta no banco (DAO), mas os campos que eu devo pesquisar (que vão no SELECT, NÃO no where) são dinâmicos.
A pessoa vai selecionar os campos (checkbox) e devo retornar para a tela os resultados apenas dos campos selecionados, não dos demais.
Dúvida:
Qual o melhor jeito de fazer isso? Retornar todos os dados (colocando todos os campos para pesquisar no banco) e tentar tratar no JSP (com JSTL?) ou fazer um alguma maneira de montar o SELECT com stringbuilder por exemplo?[/quote]
Acho que entendi o que quer. Traga tudo o que quer (no select usando asterisco *). Quando chegar no front-end, popule o que estiver checado e não popule o que estiver chacado. Pode fazer as verificações do que vai popular ou não usando javascript. Mas por que precisa fazer desta forma?
Na maioria das vezes, quando preciso fazer uma pesquisa por vários campos, eu faço select com like.
O ideal é que utilize algum ORM. JPA ou Hibernate. Se preferir fazer na mão seu SQLs, use prepared statements: http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
cada caractere de interrogação será substituido de forma transparente pra vc, evitando problemas como de sql injection.
public List listaMedGraf(List select) {
Connection conn = null;
PreparedStatement ps = null;
List listaMedGrafRelatorio = new ArrayList();
if (!select.isEmpty()) {
sql.append(" Dispositivo.CodigoTecnologia IN (");
for (Iterator it = select.iterator(); it.hasNext() {
it.next();
sql.append("?");
if (it.hasNext()) {
sql.append(",");
}
}
sql.append(")");
}
try {
conn = ConnectionManager.obterConexao();
ps = conn.prepareStatement(SQL_ATUAL + sql.toString() + GROUP + ORDER);
int indicePs = 1;
if (!select.isEmpty()) {
for (Integer i : select) {
ps.setInt(indicePs++, i);
}
}
ResultSet rs = ps.executeQuery();
while (rs.next()) {
ListaMedGraf listaRelatorio = new ListaMedGraf(
rs.getString("CodTecnologia"),
rs.getString("Operadora"), rs.getString("StatusSIMCard"),
rs.getString("Quantidade"));
listaMedGrafRelatorio.add(listaRelatorio);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ConnectionManager.fecharConexao(conn, null, ps);
}
return listaMedGrafRelatorio;
}[/code]
Era passado uma lista de inteiro (códigos que deveriam ser pesquisados)…
Eu estava pensando em fazer algo similar… mas na hora de montar o result set, daria trabalho para montar o retorno…
Outro problema no meu caso é que estou mexendo com iframe… então a tela que abre de resultado não é a que estão os checkbox, então acho que com javascript não rola…
Se o problema for por causa do retorno, por que não devolve uma string em JSON pra este caso?
Pensando bem, eu não entendi o problema. To vendo que quer trabalhar com estatística.
Não sei se faria da mesma forma porque não sei como está estruturado seus dados e aparentemente que utilizar o mesmo fonte para várias tabelas.
Este tipo de ajuda não sei se pode ser dada em um forum. Acho que vai precisar de um analista ai pra fazer uma análise mais profunda.
vc pode dar 3 exemplos de como ficariam os selects? (String exemplo do qu quer). Talvez desta forma eu entenda um pouco como estão estruturados seus dados e exatamente o que quer.
Pelo que entendi, vc não pode retornar simplesmente uma lista de classes, pois seus conteúdos seriam muito dinâmicos. Por isso sugeri o JSON como retorno pois evitaria a necessidade de ter de escrever um Value Object para cada tipo de retorno. Neste caso, DAO, retornaria um ResultSet mesmo. E na classe final, antes de enviar ao cliente, converteria para JSON.
Como disse, só uma análise mais profunda para saber qual a melhor solução. Possivelmente, pro seu caso, terá até subselects. Não? Quem for sugerir a melhor opção pra vc vai precisar entender bem o que quer e a forma como foram estruturados seus dados. Acho que o que está querendo é muito genérico.
Não… eu tenho que mostrar na tela apenas o resultado que ele escolheu, pois o que ele vai escolher é praticamente o título da tabela que trarei de resultado…
Então se ele não selecionou, então não posso mostrar a coluna com dado que ele não selecionou.
[quote=Pacato]Não… eu tenho que mostrar na tela apenas o resultado que ele escolheu, pois o que ele vai escolher é praticamente o título da tabela que trarei de resultado…
Então se ele não selecionou, então não posso mostrar a coluna com dado que ele não selecionou.[/quote]
Ok. Entendi.
Então, neste caso, sugeriria utilizar uma modal (que no momento de retorno verificaria o que está checado) ou passar esses valores via querystring (url) no momento de abrir seu iframe.
Se o dado está sendo checado pelo usuário, então ele teria a opção de ver o resultado. Se não tem, de forma nenhuma, porque ele não tem por seu perfil de acesso a opção de visualizar tal resultado, teria que ter um select diferente.
O melhor é mesmo trazer todos os campos (*) e de acordo com o checkbox (se modal) selecionado (ou variável da sua querystring na url se iframe) para criar ou não a coluna.
mais uma perguntinha… quantos campos teriam estas tabelas? mais de 40? Se vc paginar o resultado, não me preocuparia com o tamanho dos dados que estão trafegando para o cliente. mandaria tudo mesmo e lá no cliente o checkboxe selecionado determinaria se a coluna apareceria ou não. Na cláusula where, usaria like.
UÈ cada check possui um identificador é só ver quais estão checados e montar o select, por favor não faça select * … se sua aplicação crescer, logo log vai ficar um sistema lendo e gerar manutencao
o problema maior está em montar a lista depois disso… consegui montar um select de acordo com a seleção (coloco os campos em um array e verifico quais foram selecionados e envio para montar o SELECT) mas o problema está no retorno para formar a lista:
Aqui monto o select:
private static final String SQL_SELECT_MED_GRAF = " SELECT ";
private static final String SQL_WHERE_MED_GRAF = " FROM tb_telemetria WHERE cod_usuario = 1 ";
public List<ListaMedGraf> listaMedGraf(List<String> select) {
....
if (!select.isEmpty()) {
Iterator<String> it = select.iterator();
while (it.hasNext()) {
String valor = it.next();
sql.append(valor);
if (it.hasNext()) {
sql.append(", ");
}
}
}
try {
conn = ConnectionManager.obterConexao();
ps = conn.prepareStatement(SQL_SELECT_MED_GRAF + sql.toString() + SQL_WHERE_MED_GRAF);
[code]while (rs.next()) {
// MAS AQUI QUE TRAVA… COMO VOU MONTAR A LISTA? SE O SELECT É DINÂMICO?
User ResultSetMetaData aqui vc tem todas as informacoes do retorno da consulta, inclusive as coluna retornadas, da vc cria os objetos por reflexao e seta por reflexao e vai adicionando na lista assim fica dinamico
Se vc nunca trabalhou com reflexao, estude por que vai resolver sua vida em muitos fatores.
Não tenho nenhum exemplo agora, mas estude ResultSetMetaData que provem do ResultSet da consulta em jdbc e tb estude a reflexão, do seu caso para chamar métodos set e get por reflexão.
Vc iria fazer um for varrendo as colunas retornadas, dentro do for vc vai ter acesso a tudo que precisa é só olhar os metodoss de retorno do Result. dai vc ia criando o objeto , faria um for nos metodos do objeto, iri chamar os set do objeto por reflexao de acordo com as colunas retornadas, injetava os dados e adicionaria o objeto na lista, pronto :). Mais igual te falei tem que estudar reflexao. Se vc nao conseguir faz uma gambiarra qualquer e depois estuda e concerta rrss