2009-09-11 12 views
5

Tengo lo que estoy seguro es un problema bastante común, y no quiero reinventar la rueda. Tengo un formulario de búsqueda donde los usuarios pueden especificar los criterios de búsqueda y el tipo de búsqueda (AND OR Ext ..).Cláusula de creación dinámica WHERE del usuario Criterios de búsqueda

El formulario devuelve el id de ese mapa a los nombres y valores de las columnas. Actualmente, estoy usando Java del lado del servidor para unir las cadenas en una cláusula where. Funciona en algunos casos, pero es torpe, propenso a errores y no se escalará bien.

¿Alguna sugerencia?

Gracias,

David

+2

¿Podría explicar por qué siente que esto es torpe y propenso a errores? Tal vez podrías publicar un código de muestra que ilustre esto. –

Respuesta

0

usted tiene que construir la cadena de búsqueda ya sea en el cliente o en el servidor. Construirlo en el cliente obviamente no es una buena solución (en lo que respecta a la seguridad), por lo que la única opción es construirlo en el servidor. Personalmente, usaría o construiría un objeto Searcher, que maneja la tarea recurrente de construir cadenas de búsqueda de manera eficiente y crea un Statement desde allí.

1

Si estaba usando un ORM (yo uso Hibernate), podría usar la API de Criteria: le permite agregar condiciones (usando un bucle por ejemplo) y crea la consulta resultante.

En SQL nativo, no conozco una biblioteca que pueda hacer eso. ¿Tal vez podría escribir el suyo, inspirándose en la documentación y el código de Hibernate Criteria?


O:

Si haces algo lo suficientemente complejo en el cliente (dicen a gestionar las prioridades entre AND y OR, puede anidar las condiciones de uso de paréntesis ...), entonces es probable que ya la construcción una estructura de datos que maneja esto en el cliente.

En ese caso, le sugiero que envíe esa estructura de datos al servidor y la use a través de bucles para crear su consulta.

0

Hibernate tiene una API de criterios que permite crear consultas dinámicas utilizando solo la invocación de métodos, sin necesidad de una composición manual de la consulta sql.

Pero debería considerar usar una solución para búsqueda de texto completo como Lucene o Hibernate Search, que reduce enormemente la necesidad de consultas con condiciones complejas. La búsqueda de texto completo también es una solución mucho mejor para la experiencia del usuario, ya que una búsqueda de texto completo es más sencilla de realizar y, por lo general, proporciona mejores resultados.

1

Yo usaría preparar y? para los parámetros de todos modos, aunque solo sea para evitar riesgos de inyección y otros errores de conversión.

Si sus criterios de búsqueda son de un tamaño limitado, puede listar estáticamente todas las consultas posibles para preparar.

De lo contrario, puede mantener un conjunto de consultas preparadas de forma dinámica. Esto no es tan útil para una aplicación web, donde probablemente no podrá volver a utilizar ninguna de las consultas que prepare.

0

La sugerencia de Massimiliano Fliri de mirar la API de Criteria me llevó en la dirección correcta. Dejé de construir "solo una cláusula where" y comencé a pensar en esto como una necesidad de construir declaraciones.

Esto me conduce a una solución: Onda irregular -SQL: http://code.google.com/p/squiggle-sql/

A partir de los documentos:

Onda irregular es una pequeña biblioteca Java para la generación dinámica de sentencias SQL SELECT. Es ideal para aplicaciones que necesitan crear consultas complicadas con criterios que cambian en tiempo de ejecución. Por lo general, puede ser bastante doloroso descubrir cómo construir esta cadena. Squiggle quita gran parte de este dolor.

+0

FYI: A primera vista, esa biblioteca no parece admitir declaraciones y parámetros preparados. Por ejemplo, las cadenas parecen incrustadas directamente en el SQL generado por la biblioteca. Esto PUEDE llevar a vulnerabilidades de ataques de inyección SQL. Podría estar equivocado... –

0

Si está utilizando Hibernate como ORM, utilice la API de Criteria para hacerlo. Debe ser más fácil agregar/eliminar cláusulas basadas en algunas condiciones.

Si usted está construyendo una consulta JDBC mantener la parte que es constante primera y anexar la parte variable de por ejemplo

seleccionar * de trans donde userid =?

y anexar según las condiciones, por ejemplo,
if cantidad! = Null luego anexar 'y cantidad>? '

Siempre que pueda mantener la parte constante bien segregada de la parte variable, no debería tener muchos problemas.

0

El libro "Expert SQL Server 2005 Development" de Adam Machanic tiene algunas sugerencias excelentes en el capítulo 7 sobre SQL dinámico. Se sumerge en todo tipo de problemas, incluidos el rendimiento, la facilidad de mantenimiento y la seguridad. No intentaré reescribir su capítulo, basta con decir que él cree que menos es más cuando se trata de SQL.

Es específico de SQL Server, pero creo que su enfoque general (enorme cláusula where vs. si/entonces SQL vs. dinámico) se puede aplicar en todos los ámbitos.

EDIT: Creo que vale la pena agregar ... nunca confíe en la entrada del cliente, siempre parametrice su entrada antes de usarla en SQL.

Cuestiones relacionadas