¿Cómo generar dinámicamente consulta SQL sobre la base de las selecciones del usuario?

StackOverflow https://stackoverflow.com/questions/2041312

Pregunta

Esta es la misma pregunta que:

cómo generar dinámicamente consulta SQL en función del usuario de selecciones?

La única diferencia es, que estoy interesado en ver soluciones también usando Java / JPA (+ posiblemente EclipseLink o Hibernate extensiones específicas).

Es necesario crear una interfaz gráfica de usuario, mediante el cual los usuarios pueden seleccionar varios atributos que serán utilizados para consultar la base de datos para encontrar las personas adecuadas. Estoy en busca de ideas de cómo generar dinámicamente la consulta de base de datos de acuerdo a las opciones de usuario.

Consulta contendrá varios campos, pero para llegar a la idea voy a incluir sólo tres de los de abajo como un ejemplo:

  • Ocupación - no puede ser de 0 a n cadenas de ocupación. Si se dan las cadenas de ocupación, uno de ellos tienen que coincidir.

  • Age - edad se puede dar como:

    1. coincidencia exacta (30)
    2. gama (por ejemplo 30-40)
    3. inferior a un valor (-40)
    4. más de un valor (30 -)

parámetro de edad es opcional en la consulta. Además, el usuario puede especificar si la edad es un parámetro necesario. Si no se requiere, y una persona no tiene la edad es su / su perfil, criterios de edad se ignora para esta persona.

  • Altura - similar a la edad

Consultas de ejemplo:

No se ha dado criterios:

select * from persons

Sólo la ocupación se ha dado:

select * from persons where occupation = 'dentist'

Varias ocupaciones se les ha dado:

select * from persons where (occupation = 'dentist' or occupation = 'engineer')

La edad ha sido dada como un valor mayor que, y es necesario para existir en el perfil de la persona:

select * from persons where age >= 30

Altura se ha dado como un rango, y no es necesario para existir en el perfil de la persona:

select * from persons where (height is null or (height >= 30 and height <= 40))

La combinación de criterios diferentes:

select * from persons where occupation = 'dentist' and age >= 30 and (height is null or (height >= 30 and height <= 40))

Ya he implementado código que es capaz de generar consultas como cadenas, pero ciertamente no es demasiado bonita. Estoy buscando ideas de lo que sería la forma más eficiente y más bonito para lograrlo.

¿Fue útil?

Solución

En Hibernate, puede utilizar Criterios consultas.

En Toplink, llegamos Expresión y ExpressionBuilder.

Otros consejos

Hay muchas herramientas diferentes la mejor creo que son querydsl , torpedoquery e consulta de objetos , este tres permiten escribir typesafe consulta, de lo contrario puede utilizar los criterios del API, y si está utilizando JPA 2 también JPA2 Typesafe consulta .

con todas estas herramientas se puede crear una consulta en tiempo de ejecución !!

Si usted quiere hacer esto en JPA 1.x, se puede usar generador de consultas personalizado como se describe aquí http://rrusin.blogspot.com/2010/02/jpa-query-builder.html . Esto permite la creación de consultas de esta manera:

return new JpaQueryBuilder().buildQuery(em,
                new Object[] {
                    "select c from Car c where c.name is not null",
                    new JQBParam("name", name, " and c.name = :name"),
                    new JQBParam("type", type, " and c.type = :type")
                }
            )

Yo uso el marco Querydsl porque estoy usando JPA 1.0, que no incluye la API Criteria y yo también es necesario las características que usted describió. Escribir código Querydsl es fácil y el código es más corto que el código criterios del API. Querydsl es libre de usar y compatible con las consultas typesafe.

En mi código, estoy usando AND y OR objetos de este. Toman como listas de parámetros (se ve bien con argumentos variadic de Java 5) y concatenan en cuerdas con los espacios y los paréntesis necesarios. pseudo código:

AND(WhereCond ... conds) { this.conds = conds; }
toString() { return conds.length == 0 ? "" : "(" + join(conds, " AND ") + ")" };

donde join() convierte la tabla de objeto a matriz de cadena y luego se une a los elementos con el parámetro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top