Ajuda com query no JSF

4 respostas
A

Pessoal, estou tentando fazer uma query avançada onde eu tenho alguns filtros para busca.
Tenho 5 campos para isso:

  • NumOS;
  • Data;
  • Funcionario;
  • Status;
  • TipoServico;

O NumOS é um campo primário, então ele será uma query já existente que encontrará direto, porém os outros campos, Data, Funcionario, Status e TipoServico são campos que vão se refinando, e eu terei que fazer a verificação e montar a query de acordo com a seleção.
Se eu selecionar Data = 27/03/2011 e Status = Finalizado, então ele me trará somente os desta data com status finalizado. Se eu adicionar o tipoServico = bombeiro, ele terá que me trazer essa mesma query com o tipoServico que seja bombeiro.

Tentei isso, funciona mas não é refinado:

@NamedQuery(name = “OsRegistros.findFiltroGeral”, query = “SELECT o FROM OsRegistros o where (o.data like ?1) or (o.funFuncionario.matricula like ?2) or (o.status like ?3) or (o.tipoServico like ?4)”),

Alguém pode me ajudar com essa query?

4 Respostas

zoren

Para usar os comandos para substituição nas NamedQueries, vc usa o :chave e não ?1…

A

Esse ?1 é a sequencia de parametros que eu passo, criei um método onde eu passo 1 list para a minha classe de controle, e a ordem dos itens na lista determina a ordem a ser pesquisada. Funciona normalmente ela, o problema é realmente conseguir consolidar um slq com o JSF que funcione nessa forma de busca.

Takeshi91

Não entendi essa anotação.

Geralmente passo os parâmetros obtidos na View para a Controller, executo a query, retorno uma nova Lista e atualizo um componente que receba a mesma

A

Oi pessoal, já resolvi o problema aqui, não foi pelo sql, mas funcionou do jeito esperado. Vou explicar a anotação ?1 ,?2, ?etc
Supondo que eu tenho uma namedQuery gerada automaticamente pelo netbeans:

@NamedQuery(name = "OsRegistros.findByNumOsData", query = "SELECT o FROM OsRegistros o WHERE o.numOs = :numOs and o.data = :data")

vou transformá-la assim:

@NamedQuery(name = "OsRegistros.findByNumOsData", query = "SELECT o FROM OsRegistros o WHERE o.numOs = ?1 and o.data = ?2")

dessa forma eu tenho a sequência de parâmetros que eu terei de passar.
A minha classe terá esse cabeçalho:

public List getListaComParametros(String namedQuery, List parametros)

onde eu passarei o nome da minha query, e uma lista de parâmetros para ela. Como no exemplo, vou passar assim:

List<OsRegistros> reg = new ArrayList<OsRegistros>();
List minhaLista = new ArrayList();
lista.add(numDaOsASerFiltrado);
lista.add(dataASerFiltrada);

reg = meuDAO.getListaComParametros("OsRegistros.findByNumOsData", lista);

assim ele vai pegar o primeiro item da lista, o parametro 1 (?1) e colocar la, e o segundo (?2) no seu devido lugar também.
Agora para colocar o parâmetro correto, eu lanço apenas um laço for para ser atribuido os valores, sendo que a query ja foi feita.

q.setParameter(i + 1, parametros.get(i));

podem ser N parâmetros, mas ele vai listando de acordo com a ordem ?x.

— A resolução do meu problema foi da maneira tosca, mas a que funcionou pra pressa do momento —

public void consultarOS() {
        ArrayList list = new ArrayList();
        String qData = "", qMatricula = "", qStatus = "", qServico = "", qNumOs = "";
        String query=" where";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (txNumOS.length() != 0){qNumOs = " o.numOs=" + txNumOS ;list.add(qNumOs);}
        if (data != null){qData = " o.data='" + sdf.format(data) + "'";list.add(qData);}
        if (!matricula.equals("0")){qMatricula = " o.funFuncionario.matricula='" + matricula + "'";list.add(qMatricula);}
        if (!status.equals("0")){qStatus = " o.status='" + status + "'";list.add(qStatus);}
        if (!servico.equals("0")){qServico = " o.tipoServico='" + servico + "'";list.add(qServico);}
        if (list.isEmpty()){query = "";}
        if (list.size() == 1){query += list.get(0);}
        if (list.size() == 2){query += list.get(0) + " and " + list.get(1);}
        if (list.size() == 3){query += list.get(0) + " and " + list.get(1) + " and " + list.get(2);}
        if (list.size() == 4){query += list.get(0) + " and " + list.get(1) + " and " + list.get(2) + " and " + list.get(3);}
        if (list.size() == 5){query += list.get(0) + " and " + list.get(1) + " and " + list.get(2) + " and " + list.get(3) + " and " + list.get(4);}
        System.out.print(txNumOS.length() + "    " + data + "   " + matricula + "     "  + status + "    " + servico);
        System.out.print(query);
        listOS = cdao.getFromQuery("select o from OsRegistros o" + query, OsRegistros.class);
        
    }

como a quantidade de parâmetros é pouca e eu não tive tempo de pensar em como otimizar o código, que o tempo aqui está corrido, essa foi a forma que atendeu.

Tá aqui o dao:

public List getFromQuery(String Query, Class<?> resultClass) {
        List resultado = null;
        try {
            q = em.createQuery(Query, resultClass);
            resultado = q.getResultList();
        } catch (Exception Ex) {
            log.addLog(Calendar.getInstance().getTime() + "[Erro na classe de controle no método: ]{getFromQuery}: " + Ex.getMessage());
        }
        return resultado;
    }

vlw a atenção gente!

Criado 31 de março de 2011
Ultima resposta 31 de mar. de 2011
Respostas 4
Participantes 3