Como usar a StringBuilder?

33 respostas
douglasmorais

Como posso utilizar a classe StringBuilder para criar um Select com parametros vinda da CheckBox ?
Por exemplo

Select * from produtos WHERE PARAMETRO_UM = VALOR_UM AND PARAMETRO_DOIS = VALOR_DOIS

Eu sei como pegar os valores da request. Eu nao sei como construir a string do Select . Andei pesquisando a classe StringBuilder mas nao to conseguindo resolver.

33 Respostas

F

Boa Noite

acho que você pode usar o método append() de StringBuilder.

Seria mais ou menos assim

StringBuilder query = new StringBuilder();
query.append("Select * from produtos WHERE PARAMETRO_UM = ");
query.append(VALOR_UM);
query.append("AND PARAMETRO_DOIS = ");
query.append(VALOR_DOIS);

e depois é só usar query.toString().
Não sei se era bem isso que você pensava mais o uso de StringBuilder é assim.

douglasmorais

entao, valeu pela dica.

Mas eu acho que o meu problema eh mais de logica tambem ( tambem, rs ).

Um cara aqui do Guj me deu a seguinte sugestao:

StringBuilder sql = new StringBuilder("select * from lentes where ");   
	Set<String> parameterNames = request.getParameterMap().keySet();   
	for (String nameParameter : parameterNames) {   
	     sql.append(request.getParameter(nameParameter)).append(","); 
	    
	}  
	PrintWriter out = response.getWriter();


	out.println("<html> "+sql.toString().substring(0, (sql.toString().length()-1)) +" </html>");

So que nao resolveu meu problema pq eu preciso pegar nas checkboxes o nome do Parametro e o Valor. Sao de 0 a 5 Opcoes possiveis la no checkbox. Como eu faco pra colocar os ANDs da Select ?

Markus_Alemao
<form action="Servlet" method="POST">
            <input type="checkbox" name="c_um" value="um"/>
            <input type="checkbox" name="c_dois" value="dois"/>
            <input type="checkbox" name="c_tres" value="tres"/>
             <input type="submit" value="ok"/> 
 </form>
protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        StringBuilder sql = new StringBuilder("select * from tabela where ( ");
        Set<String> set = request.getParameterMap().keySet();
        for (String nameParameter : set) {
             sql.append(nameParameter).append("=").append(request.getParameter(nameParameter).concat(" and "));
        }
        System.out.println(sql.toString().substring(0, (sql.toString().length()-5)).concat(" )"));
        
        processRequest(request, response);
    }

Na primeira vez voce tinha pedido (ou deixado intender) que queria os trazer determinados campos ...não filtrar por determinados campos ...mas de qualquer forma com uma pequena alteração é possivel fazer isso.

(me deve uma cerveja :) )

douglasmorais

valeu Markao !!! Uma caixa de Serra Malte pra vc me velho !!! valeu mesmo…

douglasmorais

Markao, eu testei mas ainda nao deu certo nao… A string do select ta sendo gerada apenas com um unico Parametro/Valor mesmo quando marcado mais de 1 checkbox

Markus_Alemao

Cara aqui esta funcionando:

todos os campos marcados:
select * from tabela where ( c_um=um and c_dois=dois and c_tres=tres )

somente dois:
select * from tabela where ( c_um=um and c_tres=tres )

Envia seu form para dar uma olhada.

douglasmorais

Markus, nem sei como te agradecer a atencao que vc tem dado cara…

segue ae a aberracao…

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form  method="post" action="teste">
<label>Esferico   :</label><input type="text" name="esferico" size="5"></input>
<label>Cilindrico :</label><input type="text" name="cilindrico" size="5"></input><br></br>
<label>Produto :</label> <br></br>
<input type="text" name="produto" size="30" /><br></br>
<label> Material</label><br></br>
<input type="checkbox" name="material" value="Acrilico"> Acrilico <br/>
<input type="checkbox" name="material" value="Cristal"> Cristal <br/>
<input type="checkbox" name="material" value="Transistions"> Transistions <br/>
<input type="checkbox" name="material" value="High Lite"> High Lite <br/>
<input type="checkbox" name="material" value="Trivex"> Trivex <br/>
<input type="checkbox" name="material" value="Policarbonato"> Policarbonato <br/>
<input type="checkbox" name="material" value="Stylis"> Stylis<br/>
<br/>
<br/>
Tratamento<br/>
<input type="checkbox" name="tratamento" value="Anti-Reflexo"> Anti-Reflexo<br/>
<input type="checkbox" name="tratamento" value="Incolor"> Incolor<br/>
<br/>
<br/>
Indice de Refracao<br/>

<input type="checkbox" name="ir" value="1.49">1.49<br/>
<input type="checkbox" name="ir" value="1.56">1.56<br/>
<input type="checkbox" name="ir" value="1.61">1.61<br/>
<input type="checkbox" name="ir" value="1.67">1.67<br/>
<input type="checkbox" name="ir" value="1.80">1.80<br/>
<input type="checkbox" name="ir" value="1.90">1.90<br/>
<input type="submit" value="Gravar" />
</form>
</body>
</html>
Markus_Alemao

Vixe …cara veja meu exemplo …eu uso o nome do checkbox como se foce o nome do campo no banco de dados e o valor do mesmo o valor que sera atribuido na clausula where do sql.
Pensa ai mostre seus resultados que amanha eu dou uma olhada.

douglasmorais

Markao, pra fazer isso que vc ta falando vai ficar inviavel pq nesse caso eu teria que ter no banco de dados 1 campo pra cada possivel caracteristica do produto e, na verdade, eu so tenho o campo MATERIAL

douglasmorais

Ow Markao, acho que achei um metodo que faz o que eu quero ( no que diz respeito a pegar o PARAMETRO/VALOR da request).

Agora soh to precisando criar a string do Select.

Da uma olhada ae cara:

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
	      // Set response content type
	      response.setContentType("text/html");

	      PrintWriter out = response.getWriter();
		  String title = "Reading All Form Parameters";
	      String docType =
	      "<!doctype html public \"-//w3c//dtd html 4.0 " +
	      "transitional//en\">\n";
	      out.println(docType +
	        "<html>\n" +
	        "<head><title>" + title + "</title></head>\n" +
	        "<body bgcolor=\"#f0f0f0\">\n" +
	        "<h1 align=\"center\">" + title + "</h1>\n" +
	        "<table width=\"100%\" border=\"1\" align=\"center\">\n" +
	        "<tr bgcolor=\"#949494\">\n" +
	        "<th>Param Name</th><th>Param Value(s)</th>\n"+
	        "</tr>\n");

	      Enumeration paramNames = request.getParameterNames();
	      
	      while(paramNames.hasMoreElements()) {
	         String paramName = (String)paramNames.nextElement();
	         out.print("<tr><td>" + paramName + "</td>\n<td>");
	         String[] paramValues =
	                request.getParameterValues(paramName);
	         // Read single valued data
	         if (paramValues.length == 1) {
	           String paramValue = paramValues[0];
	           if (paramValue.length() == 0)
	             out.println("<i>No Value</i>");
	           else
	             out.println(paramValue);
	         } else {
	             // Read multiple valued data
	             out.println("<ul>");
	             for(int i=0; i < paramValues.length; i++) {
	                out.println("<li>" + paramValues[i]);
	             }
	             out.println("</ul>");
	         }
	      }
	      out.println("</tr>\n</table>\n</body></html>");
	  }
Markus_Alemao

Douglas faz o seguinte …me envia 3 exemplos com consultas as quais voce pretende gerar para eu analisar.

ViniGodoy

Para queries você geralmente não usa StringBuilder. É mais seguro e mais fácil usar o PreparedStatement:

PreparedStatement stmt = &quot;SELECT * FROM produtos WHERE valor &lt; ? AND categoria=?&quot;; stmt.setDouble(1, valorMaximo); stmt.setInteger(2, idCategoria);

douglasmorais

Vini, valeu por responder…

Mas essa sua dica ae soh da certo com PARAMETRO/VALOR previamente conhecidos, nao eh ? No meu caso eu nao tenho como saber quais serao os PARAMETROS/VALOR marcados na checkboxe. Dai o motivo de usar o StringBuilder para fazer a string do select. Tipo, pega no request os Name e os Value do checkbox, que podem ser mais de 1, e cria a string select. Ai que o bicho pega. Eu pego o NAME com o getParameterNames() e o VALUE com getParameterValues() mas nao sei como montar a string Select.

Markus_Alemao

Cara acho que eu lhe confundi um pouco com o StringBuilder ele praticamente indifere de uma String normal, mas tem mais eficiencia em casos em que seja necessario concatenar varias Strings(preciosismo que talvez não se justifique nesse caso …mas é sempre valido aprender algo novo :slight_smile: ).

Aproveita e manda os campos da sua tabela do banco para ilustrar melhor o problema.

douglasmorais

Ae Markao era isso que vc pediu ?

Select * from lentes WHERE material=cristal AND tratamento=anti-reflexo AND IndiceRefracao=1.56 


Select * from lentes WHERE material=policarbonato AND IndiceRefracao=1.56 AND IndiceRefracao=1.61


Select * from lentes WHERE material=acrilico AND material=policarbonato AND material=transistions AND tratamento=anti-reflexo
Markus_Alemao

Sim sim :slight_smile:

Agora faz o seguinte …entra no banco de dados e executa essas consultas e me diga qual resultado é retornado.

douglasmorais

Os campos da tabela sao:

Produto, Esferico, Cilindrico, Material, Tratamento, IndiceRefracao, Valor.

Esferico e Cilindrico vem de um input text

Markus_Alemao

Vide essa consulta :

Select * from lentes WHERE material=acrilico AND material=policarbonato AND material=transistions AND tratamento=anti-reflexo

Existe um problema logico aqui o campo material jamais ira assumir dois valores sendo ele unico.

Caso uma lente possua dois ou mais materias voce tera que fazer outra tabela ex material onde existira uma chave estrangeira que referenciara o identificador da lente.

douglasmorais

Pode cre Markao… tem coisa errada ae… rs

douglasmorais

desculpa ae a amolacao… eh que eu to comecando…

douglasmorais

Markao, olha soh o que eu achei aqui:

Markus_Alemao

Sim isso é uma possibilidade…porem tem muitos condicionais nesse negocio ha de existir uma solução mais elegante e robusta :).

Aproveitando me responda o seguinte :

Uma lente possui mais de um material ?
Uma lente possui mais de um indice de refracao ?

douglasmorais
douglasmorais

Nao. Uma lente pode ter um unico Material. Um unico Indice de Refracao, enfim um unico valor para cada campo.

Eh que eu queria fazer uma consulta de precos. E essa consulta me retornaria os valores das lentes, por exemplo, Cristal e Acrilico.

Markus_Alemao

Ok …porem primeiramente temos que organizar o seu banco de dados. Já que é de pouco valia uma consulta em uma base de dados incoerente.

Markus_Alemao

douglasmorais:
Nao. Uma lente pode ter um unico Material. Um unico Indice de Refracao, enfim um unico valor para cada campo.

Eh que eu queria fazer uma consulta de precos. E essa consulta me retornaria os valores das lentes, por exemplo, Cristal e Acrilico.

Hum …bingo !!

seguinte voce tem que usar or no lugar de and ex :

SELECT * FROM lentes where (material='policarbonato' OR material='acrilico')

Essa consulta vai retornar todas as lentes em que o campo material possua o valor ‘policarbonato’ ou ‘acrilico’.
concorda …? sem corda ? qual a diferença dos operadores ?

douglasmorais

Nao entendo. pq que vc acha que ta incoerente ? Vc acha que eu deveria ter uma outras tabelas ( Material, Tratamento, IndiceRefracao ) e linkar todas com a tabela produto por uma foreign key ?

douglasmorais

mas o OR nao vai limitar ? tipo, cristal ou acrilico e nao os dois… ?

Markus_Alemao

erro

douglasmorais

o OR da certo sim, acabei de testar no netbeans, naquela parte do banco de dados do netbeans

Markus_Alemao

Opa desculpa …fail aqui no forum :slight_smile:

Quanto a incoerencia que eu me referia ficou fora do contexto. Esta tudo bem com sua base :slight_smile:

Markus_Alemao
<form  method="post" action="Servlet">
                <label>Esferico   :</label><input type="text" name="esferico" size="5"></input>
                <label>Cilindrico :</label><input type="text" name="cilindrico" size="5"></input><br></br>
                <label>Produto :</label> <br></br>
                <input type="text" name="produto" size="30" /><br></br>
                <label> Material</label><br></br>
                <input type="checkbox" name="material1" value="Acrilico"> Acrilico <br/>
                <input type="checkbox" name="material2" value="Cristal"> Cristal <br/>
                <input type="checkbox" name="material3" value="Transistions"> Transistions <br/>
                <input type="checkbox" name="material4" value="High Lite"> High Lite <br/>
                <input type="checkbox" name="material5" value="Trivex"> Trivex <br/>
                <input type="checkbox" name="material6" value="Policarbonato"> Policarbonato <br/>
                <input type="checkbox" name="material7" value="Stylis"> Stylis<br/>
                <br/>
                <br/>
                Tratamento<br/>
                <input type="checkbox" name="tratamento1" value="Anti-Reflexo"> Anti-Reflexo<br/>
                <input type="checkbox" name="tratamento2" value="Incolor"> Incolor<br/>
                <br/>
                <br/>
                Indice de Refracao<br/>

                <input type="checkbox" name="ir" value="1.49">1.49<br/>
                <input type="checkbox" name="ir" value="1.56">1.56<br/>
                <input type="checkbox" name="ir" value="1.61">1.61<br/>
                <input type="checkbox" name="ir" value="1.67">1.67<br/>
                <input type="checkbox" name="ir" value="1.80">1.80<br/>
                <input type="checkbox" name="ir" value="1.90">1.90<br/>
                <input type="submit" value="Gravar" />
            </form>
        </body>
protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        StringBuilder sql = new StringBuilder("select * from lentes where ( ");
        Set<String> set = request.getParameterMap().keySet();
        for (String nameParameter : set) {
             if(nameParameter.startsWith("material")){
                 sql.append("material").append("=").append("'"+request.getParameter(nameParameter).concat("'").concat(" or  "));
             }
        }
        System.out.println(sql.toString().substring(0, (sql.toString().length()-5)).concat(" )"));
        
        processRequest(request, response);
    }

Saida:

select * from lentes where ( material='Acrilico' or  material='Cristal' or  material='Policarbonato' )

Isso resolve o problema quanto aos materias, agora só falta verificar e montar a consulta com os demais campos. Se baseia nisso e tenta fazer para os demais.

douglasmorais

Muito Obrigado !

Criado 11 de outubro de 2011
Ultima resposta 13 de out. de 2011
Respostas 33
Participantes 4