two tables query not functions java hibernate hql

java - tables - Buscando un constructor HQL(Hibernate Query Language)



hql trim (11)

¿La API de Criteria no lo hace por usted? Se ve casi exactamente como lo que estás pidiendo.

Estoy buscando un constructor para HQL en Java. Quiero deshacerme de cosas como:

StringBuilder builder = new StringBuilder() .append("select stock from ") .append( Stock.class.getName() ) .append( " as stock where stock.id = ") .append( id );

Prefiero tener algo como:

HqlBuilder builder = new HqlBuilder() .select( "stock" ) .from( Stock.class.getName() ).as( "stock" ) .where( "stock.id" ).equals( id );

Busqué en Google un poco, y no pude encontrar uno.

Escribí un HqlBuilder rápido y tonto que se ajusta a mis necesidades por ahora, pero me encantaría encontrar uno que tenga más usuarios y pruebas que yo solo.

Nota: Me gustaría poder hacer cosas como esta y más, lo cual no pude hacer con la API de Criteria:

select stock from com.something.Stock as stock, com.something.Bonus as bonus where stock.someValue = bonus.id

es decir. seleccione todas las acciones cuya propiedad someValue apunte a cualquier bonificación de la tabla Bonus.

¡Gracias!


Criteria API no proporciona toda la funcionalidad disponible en HQL. Por ejemplo, no puede hacer más de una unión sobre la misma columna.

¿Por qué no usas QUERIAS NOMBRADAS ? El aspecto mucho más limpio:

Person person = session.getNamedQuery("Person.findByName") .setString(0, "Marcio") .list();


Parece que desea utilizar la API de consulta Criteria integrada en Hibernate. Para hacer su consulta anterior, se vería así:

List<Stock> stocks = session.createCriteria(Stock.class) .add(Property.forName("id").eq(id)) .list();

Si aún no tiene acceso a la sesión de Hibernate, puede usar ''DetachedCriteria'' de la siguiente manera:

DetachedCriteria criteria = DetachedCriteria.forClass(Stock.class) .add(Property.forName("id").eq(id));

Si desea obtener todas las acciones que tienen una bonificación con una identificación específica, puede hacer lo siguiente:

DetachedCriteria criteria = DetachedCriteria.forClass(Stock.class) .createCriteria("Stock") .add(Property.forName("id").eq(id)));

Para obtener más información, consulte Consultas de criterios de los documentos de Hibernate


Escribí una solución GPL para OMERO que puedes construir fácilmente adaptada a tu situación.

Uso:

QueryBuilder qb = new QueryBuilder(); qb.select("img"); qb.from("Image", "img"); qb.join("img.pixels", "pix", true, false); // Can''t join anymore after this qb.where(); // First qb.append("("); qb.and("pt.details.creationTime > :time"); qb.param("time", new Date()); qb.append(")"); qb.and("img.id in (:ids)"); qb.paramList("ids", new HashSet()); qb.order("img.id", true); qb.order("this.details.creationEvent.time", false);

Funciona como una máquina de estados "select-> from-> join-> where-> order", etc. y se mantiene al día con los parámetros opcionales. Hubo varias consultas que la API de Criteria no pudo realizar (ver HHH-879 ), así que al final fue más simple escribir esta pequeña clase para envolver StringBuilder. (Nota: hay un boleto HHH-2407 que describe una sucursal de Hibernate que debería unificar los dos. Después de eso, probablemente tendría sentido volver a visitar la API de Criteria)


Eche un vistazo al paquete de búsqueda disponible del proyecto hibernate-generic-dao . Esta es una implementación bastante decente de HQL Builder.


Sé que este hilo es bastante antiguo, pero también estaba buscando un HqlBuilder. Encontré este proyecto de "protector de pantalla"
NO es un protector de pantalla de Windows, es un " Sistema de gestión de información de laboratorio (LIMS) para instalaciones de detección de alto rendimiento (HTS) que realizan pantallas de moléculas pequeñas y de ARNi " .

Contiene un HQLBuilder que se ve bastante bien.
Aquí hay una lista de ejemplos de métodos disponibles:

... HqlBuilder select(String alias); HqlBuilder select(String alias, String property); HqlBuilder from(Class<?> entityClass, String alias); HqlBuilder fromFetch(String joinAlias, String joinRelationship, String alias); HqlBuilder where(String alias, String property, Operator operator, Object value); HqlBuilder where(String alias, Operator operator, Object value); HqlBuilder where(String alias1, Operator operator, String alias2); HqlBuilder whereIn(String alias, String property, Set<?> values); HqlBuilder whereIn(String alias, Set<?> values); HqlBuilder where(Clause clause); HqlBuilder orderBy(String alias, String property); HqlBuilder orderBy(String alias, SortDirection sortDirection); HqlBuilder orderBy(String alias, String property, SortDirection sortDirection); String toHql(); ...


Para un enfoque tipo seguro para su problema, considere Querydsl .

La consulta de ejemplo se convierte

HQLQuery query = new HibernateQuery(session); List<Stock> s = query.from(stock, bonus) .where(stock.someValue.eq(bonus.id)) .list(stock);

Querydsl utiliza APT para la generación de código como JPA2 y admite colecciones JPA / Hibernate, JDO, SQL y Java.

Soy el mantenedor de Querydsl, por lo que esta respuesta es parcial.


Para otra consulta de tipo seguro dsl, recomiendo http://www.torpedoquery.org . La biblioteca todavía es joven, pero proporciona seguridad de tipo mediante el uso directo de las clases de su entidad. Esto significa errores tempranos del compilador cuando la consulta ya no se aplica antes de refactorizar o rediseñar.

También te proporcioné un ejemplo. Creo que por tus publicaciones intentaste hacer una restricción de subconsulta, así que basé el ejemplo en eso:

import static org.torpedoquery.jpa.Torpedo.*; Bonus bonus = from(Bonus.class); Query subQuery = select(bonus.getId()); Stock stock = from(Stock.class); where(stock.getSomeValue()).in(subQuery); List<Stock> stocks = select(stock).list(entityManager);


Ahora también están disponibles la consulta segura tipo JPA estándar y una consulta de objetos menos estándar pero también buena.

Ejemplos:

Tipo de JPA seguro

EntityManager em = ... CriteriaBuilder qb = em.getCriteriaBuilder(); CriteriaQuery<Stock> c = qb.createQuery(Stock.class); Root<Stock> = c.from(Stock.class); Predicate condition = qb.eq(p.get(Stock_.id), id); c.where(condition); TypedQuery<Stock> q = em.createQuery(c); List<Stock> result = q.getResultList();

Consulta de objeto

EntityManager em = ... ObjectQuery<Stock> query = new GenericObjectQuery<Stock>(Stock.class); Stock toSearch = query.target(); query.eq(toSearch.getId(),id); List<Stock> res = (List<Stock>)JPAObjectQuery.execute(query, em);


@ Sébastien Rocca-Serra

select stock from com.something.Stock as stock, com.something.Bonus as bonus where stock.bonus.id = bonus.id

Eso es solo una unión. Hibernate lo hace de forma automática, si y solo si tiene la asignación entre la configuración de Stock y Bonus y si la bonus es una propiedad de Stock . Criteria.list() devolverá objetos Stock y usted simplemente llamará a stock.getBonus() .

Tenga en cuenta que si quiere hacer algo como

select stock from com.something.Stock as stock where stock.bonus.value > 1000000

Debe usar Criteria.createAlias() . Sería algo así como

session.createCriteria(Stock.class).createAlias("bonus", "b") .add(Restrictions.gt("b.value", 1000000)).list()


@ Sébastien Rocca-Serra
Ahora estamos llegando a un lugar concreto. El tipo de unión que estás tratando de hacer no es realmente posible a través de la API de Criteria, pero una sub consulta debería lograr lo mismo. Primero, crea un someValue DetachedCriteria para la tabla de bonificación, luego usa el operador IN para someValue .

DetachedCriteria bonuses = DetachedCriteria.forClass(Bonus.class); List stocks = session.createCriteria(Stock.class) .add(Property.forName("someValue").in(bonuses)).list();

Esto es equivalente a

select stock from com.something.Stock as stock where stock.someValue in (select bonus.id from com.something.Bonus as bonus)

El único inconveniente sería si tiene referencias a diferentes tablas en someValue y sus identificaciones no son únicas en todas las tablas. Pero su consulta sufriría el mismo defecto.