Frage

Ich bin auf der Suche nach einem generator für HQL in Java.Ich möchte, um loszuwerden, Dinge wie:

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

Ich hätte lieber so etwas wie:

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

Ich habe ein wenig gegoogelt, und ich konnte Sie nicht finden.

Ich schrieb eine schnelle & dumb HqlBuilder das passt zu meinen Bedürfnissen für jetzt, aber ich würde lieben zu finden, das mehr Benutzer und tests als mich allein.

Hinweis:Ich möchte in der Lage sein, Dinge zu tun wie diese und mehr, was ich tun konnte, mit der Kriterien-API:

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

ie.wählen Sie alle Aktien, deren Eigenschaft someValue Punkte alle bonus der Bonus-Tabelle.

Vielen Dank!

War es hilfreich?

Lösung

Sébastien Rocca-Serra
Jetzt sind wir irgendwo Beton bekommen. Die Art verbinden Sie versuchen zu tun ist nicht wirklich möglich, durch die Kriterien API, sondern eine Unter Abfrage sollte das Gleiche erreichen. Zuerst eine DetachedCriteria für die Bonus-Tabelle erstellen, verwenden Sie dann den IN Operator für someValue.

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

Dies ist äquivalent zu

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

Der einzige Nachteil wäre, wenn Sie in allen Tabellen Verweise auf verschiedene Tabellen in someValue und Ihre IDs sind nicht eindeutig zuzuordnen sind. Aber Ihre Anfrage würde aus dem gleichen Fehler leiden.

Andere Tipps

nicht das Criteria API tun es für Sie? Es sieht fast genauso aus wie, was Sie fordern.

Für einen typsichere Ansatz für Ihr Problem, betrachten Querydsl .

Das Beispiel Abfrage wird

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

Querydsl verwendet für die Codegenerierung wie JPA2 APT und unterstützt JPA / Hibernate, JDO, SQL und Java-Sammlungen.

Ich bin der Maintainer von Querydsl, so dass diese Antwort ist voreingenommen.

Für eine andere typsichere Abfrage dsl, empfehle ich http://www.torpedoquery.org . Die Bibliothek ist noch jung, aber es bietet Typsicherheit durch direkt Ihre Unternehmens-Klassen. Dies bedeutet, früh Compiler-Fehler, wenn die Abfrage nicht mehr gilt vor der Umgestaltung oder Neugestaltung.

ich Ihnen auch mit einem Beispiel versehen. Ich denke, von Ihren Beiträgen, die Sie, wo eine Unterabfrage Einschränkung zu tun versuchen, so dass ich auf Basis der exemple auf, dass:

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);

Es sieht aus wie Sie die Kriterien Abfrage API gebaut in den Ruhezustand verwenden möchten. Gehen Sie Ihre obige Abfrage würde es so aussehen:

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

Wenn Sie keinen Zugriff auf die Hibernate Session noch haben, können Sie verwendet ‚DetachedCriteria‘ wie folgt:

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

Wenn Sie wollen alle Aktien erhalten, die einen Bonus mit einer bestimmten ID haben Sie Folgendes tun können:

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

Für mehr infromation Besuche Kriterien Abfragen aus der Hibernate-Dokumentation

Sébastien Rocca-Serra

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

Das ist nur ein beizutreten. Hibernate funktioniert es automatisch, wenn und nur wenn Sie die Zuordnung zwischen Stock und Bonus Setup haben und wenn bonus eine Eigenschaft von Stock ist. Criteria.list() wird Stock Objekte zurückgeben und Sie nur stock.getBonus() nennen.

Beachten Sie, wenn Sie wollen, etwas zu tun wie

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

Sie müssen Criteria.createAlias() . Es wäre so etwas wie

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

Kriterien API bietet nicht alle Funktionen verfügbar in HQL. Zum Beispiel können Sie nicht mehr tun, als eine über den gleichen Spalt verbinden.

Warum Sie nicht Benannte Abfragen ? Der Blick viel mehr sauber:

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

Ich schrieb eine GPL-Lösung für OMERO, die Sie leicht auf Ihre Situation geeignet bauen könnten.

Verbrauch:

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);

Es fungiert als eine Zustandsmaschine „select-> von-> join-> wo-> Ordnung“ usw. und hält mit optionalen Parametern auf. Es gab mehrere Anfragen, die die Kriterien API nicht durchführen konnte (siehe HHH-879 ), so am Ende ist es einfacher war, diese kleine Klasse zu schreiben String zu wickeln. (Hinweis: Es ist eine Ticket HHH-2407 eine Hibernate Zweig beschreibt die die beiden vereinigen sollte. Danach würde es wahrscheinlich sinnvoll, um die Kriterien API erneut besuchen)

Schauen Sie sich auf die Suche Paket aus dem Hibernate-generic-dao Projekt. Dies ist eine recht ordentliche HQL-Builder-Implementierung.

Ich weiß, dieser Thread ist ziemlich alt, aber ich war auch auf der Suche nach einem HqlBuilder Und ich fand diese "Bildschirmschoner" Projekt
Es ist nicht ein Windows-Bildschirmschoner, es ist ein " Laborinformationsmanagementsystem (LIMS) für Hochdurchsatz-Screening (HTS) Einrichtungen, die mit kleinen Molekülen und RNAi-Screens durchführen. "

Es enthält eine HQLBuilder, die ziemlich gut aussieht.
Hier ist eine Beispielliste der verfügbaren Methoden:

...
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();
...

gibt es jetzt auch den Standard JPA Typen Sicher Abfrage und eine weniger Standard, sondern auch gute Objektabfrage

Beispiele:

JPA Typ Sicher

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();

Objektabfrage

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);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top