Vra

Ek is op soek na 'n bouer vir HQL in Java. Ek wil om ontslae te raak van dinge soos:

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

Ek wil eerder iets soos:

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

Ek googled 'n bietjie, en ek kon nie een vind.

Ek het 'n vinnige en stom HqlBuilder wat pas by my behoeftes vir nou, maar ek sou graag wou een wat meer gebruikers en toetse alleen as my vind.

Let wel: Ek wil graag in staat wees om dinge te doen soos hierdie en nog baie meer, wat ek versuim het om te doen met die kriteria API:

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

ie. Kies alle aandele waarvan die eiendom someValue punte na enige bonus van die Bonus tafel.

Dankie!

Was dit nuttig?

Oplossing

@ Sébastien Rocca-Serra
Nou is ons om iewers beton. Die soort van aan te sluit jy probeer om te doen is nie regtig moontlik deur die kriteria API, maar 'n sub-navraag moet dieselfde ding te bewerkstellig. Eerste 'n DetachedCriteria vir die bonus tafel skep jy, gebruik dan die IN operateur vir someValue.

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

Dit is gelykstaande aan

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

Die enigste nadeel sou wees as jy verwysings na verskillende tafels in someValue en jou ID's is nie uniek in alle tafels. Maar jou navraag sou ly aan dieselfde fout.

Ander wenke

Maak nie die Kriteria API doen dit vir jou? Dit lyk amper presies soos wat jy vra vir.

Vir 'n tipe-veilige benadering tot jou probleem, oorweeg Querydsl .

Die voorbeeld navraag word

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

Querydsl gebruik APT vir kodegenerasie soos JPA2 en ondersteun JPA / Hibernate, JDO, SQL en Java versamelings.

Ek is die onderhouer van Querydsl, so hierdie antwoord is bevooroordeeld.

Vir 'n ander tipe-veilige navraag dsl, Ek beveel aan http://www.torpedoquery.org . Die biblioteek is nog jonk, maar dit bied tipe veiligheid deur direk met behulp van klasse jou entiteit. Dit beteken vroeë samesteller foute wanneer die navraag nie meer van toepassing is voor van refactoring of herontwerp.

Ek julle het ook saam met 'n voorbeeld. Ek dink van jou poste wat jy waar probeer om 'n subquery beperking doen, so ek op grond van die exemple op dat:

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

Dit lyk asof jy wil hê dat die kriteria navraag API gebou in Hibernate gebruik. Om jou bo navraag doen dit sou lyk:

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

As jy toegang tot die Hibernate Sessie nog nie het nie, kan jy gebruik 'DetachedCriteria' soos so:

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

As jy wil al Stock dat 'n Bonus met 'n spesifieke ID kan jy die volgende doen het kry:

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

Vir meer inligting bevat check Kriteria Navrae van die Hibernate docs

@ Sébastien Rocca-Serra

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

Dit is net 'n aan te sluit. Hibernate doen dit outomaties, as en slegs as jy die kartering tussen Stock en Bonus opstel en indien het bonus is 'n eienskap van Stock. Criteria.list() sal Stock voorwerpe terugkeer en jy net stock.getBonus() noem.

Let wel, as jy wil om iets te doen soos

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

Jy moet gebruik Criteria.createAlias() . Dit sou so iets wees

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

Kriteria API verskaf nie al die funksies avaiable in HQL. Byvoorbeeld, kan jy nie meer as een aan te sluit oor dieselfde kolom doen.

Hoekom het jy nie gebruik NAAM NAVRAE ? Die voorkoms veel meer skoon:

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

Ek het 'n GPL'd oplossing vir OMERO wat jy maklik geskik is vir jou situasie kan bou.

Gebruik:

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

Dit funksioneer as 'n toestand masjien "Kies-> uit-> join-> waar-> orde", ens en tred hou met opsionele parameters. Daar was 'n hele paar navrae wat die kriteria API nie kan voer (sien HHH-879 ), so op die ou end is dit makliker was om hierdie klein klas te draai StringBuilder skryf. (Let wel: daar is 'n kaartjie HHH-2407 beskrywing van 'n Hibernate tak wat die twee moet verenig. Daarna sal dit waarskynlik sin maak om weer na die kriteria API)

Ek weet hierdie draad is redelik oud, maar ek is ook op soek na 'n HqlBuilder En ek het gevind dat hierdie " "projek screensaver
Dit is NIE 'n Windows screensaver, dit is 'n " Lab Information Management System (LIMS) vir hoë deurset screening (HTS) fasiliteite wat klein molekule en RNAi skerms uit te voer. "

Dit bevat 'n HQLBuilder wat op soek is redelik goed.
Hier is 'n voorbeeld lys van beskikbare metodes:

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

Nou is ook beskikbaar die standaard navraag JPA Tipe Veilige en 'n minder standaard, maar ook 'n goeie Object Query

Voorbeelde:

JPA Tipe Veilige

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

Object Query

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);
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top