Hibernate Named Query

1. Overzicht

Een groot nadeel van HQL en SQL verspreid over data access-objecten is dat het de code onleesbaar maakt. Daarom kan het zinvol zijn om alle HQL en SQL op één plaats te groeperen en alleen hun referentie in de feitelijke gegevenstoegangscode te gebruiken. Gelukkig stelt Hibernate ons in staat om dit te doen met benoemde zoekopdrachten.

Een benoemde query is een statisch gedefinieerde query met een vooraf gedefinieerde, onveranderlijke querytekenreeks. Ze worden gevalideerd bij het aanmaken van de session factory, waardoor de applicatie snel faalt in geval van een fout.

In dit artikel zullen we zien hoe u Hibernate Named Queries kunt definiëren en gebruiken met de @NamedQuery en @NamedNativeQuery annotaties.

2. De entiteit

Laten we eerst kijken naar de entiteit die we in dit artikel gaan gebruiken:

@Entity openbare klasse DeptEmployee {@Id @GeneratedValue (strategy = GenerationType.SEQUENCE) lange privé-id; privé String employeeNumber; private String-aanduiding; private String naam; @ManyToOne privéafdeling; // getters en setters}

In ons voorbeeld halen we een medewerker op op basis van zijn medewerkersnummer.

3. Benoemde zoekopdracht

Om dit als een benoemde query te definiëren, gebruiken we de org.hibernate.annotations.NamedQuery annotatie. Het breidt de javax.persistence.NamedQuery met Hibernate-functies.

We zullen het definiëren als een annotatie van de DeptMedewerker klasse:

@ org.hibernate.annotations.NamedQuery (name = "DeptEmployee_findByEmployeeNumber", query = "van DeptEmployee waar employeeNumber =: employeeNo") 

Het is belangrijk op te merken dat elk @NamedQuery annotatie is gekoppeld aan precies één entiteitsklasse of toegewezen superklasse. Maar,aangezien het bereik van benoemde query's de volledige persistentie-eenheid is, moeten we de querynaam zorgvuldig selecteren om een ​​botsing te voorkomen. En we hebben dit bereikt door de entiteitsnaam als voorvoegsel te gebruiken.

Als we meer dan één benoemde query voor een entiteit hebben, gebruiken we de @NamedQueries annotatie om deze te groeperen:

@ org.hibernate.annotations.NamedQueries ({@ org.hibernate.annotations.NamedQuery (name = "DeptEmployee_FindByEmployeeNumber", query = "van DeptEmployee waar employeeNumber =: employeeNo"), @ org.hibernate.annotations.NamedQuery (name = " DeptEmployee_FindAllByDesgination ", query =" van DeptEmployee where designation =: designation "), @ org.hibernate.annotations.NamedQuery (name =" DeptEmployee_UpdateEmployeeDepartment ", query =" Update DeptEmployee set department =: employeeNo "). ..})

Merk op dat de HQL-query een bewerking in DML-stijl kan zijn. Het hoeft dus geen selecteer alleen verklaring. We kunnen bijvoorbeeld een updatevraag hebben zoals in DeptEmployee_UpdateEmployeeDesignation bovenstaande.

3.1. Queryfuncties configureren

We kunnen verschillende zoekfuncties instellen met de @NamedQuery annotatie. Laten we naar een voorbeeld kijken:

@ org.hibernate.annotations.NamedQuery (name = "DeptEmployee_FindAllByDepartment", query = "van DeptEmployee waar department =: department", time-out = 1, fetchSize = 10)

Hier hebben we het time-outinterval en de ophaalgrootte geconfigureerd. Naast deze twee kunnen we ook features instellen zoals:

  • cachebaar - of de vraag (resultaten) cachebaar is of niet
  • cacheMode - de cachemodus die voor deze zoekopdracht wordt gebruikt; dit kan er een zijn van KRIJGEN, NEGEREN, NORMAAL, ZET, of VERFRISSEN
  • cacheRegion - Als de queryresultaten cachebaar zijn, geef dan een naam op het te gebruiken querycache-gebied
  • commentaar - een opmerking toegevoegd aan de gegenereerde SQL-query; gericht op DBA's
  • flushMode - de doorspoelmodus voor deze query, een van ALTIJD, AUTO, COMMIT, HANDMATIG, of PERSISTENCE_CONTEXT

3.2. Met behulp van de benoemde query

Nu we de benoemde query hebben gedefinieerd, kunnen we deze gebruiken om een ​​medewerker op te halen:

Queryquery = session.createNamedQuery ("DeptEmployee_FindByEmployeeNumber", DeptEmployee.class); query.setParameter ("employeeNo", "001"); DeptEmployee-resultaat = query.getSingleResult (); 

Hier hebben we de createNamedQuery methode. Het neemt de naam van de query over en retourneert een org.hibernate.query.Query voorwerp.

4. Genoemde native query

Naast HQL-query's kunnen we ook native SQL definiëren als een benoemde query. Om dit te doen, kunnen we de @NamedNativeQuery annotatie. Hoewel het vergelijkbaar is met de @NamedQuery, het vereist een beetje meer configuratie.

Laten we deze annotatie onderzoeken aan de hand van een voorbeeld:

@ org.hibernate.annotations.NamedNativeQueries (@ org.hibernate.annotations.NamedNativeQuery (name = "DeptEmployee_GetEmployeeByName", query = "selecteer * uit dienstmedewerker emp waar naam =: naam", resultClass = DeptEmployee.class))

Omdat dit een native query is, moeten we Hibernate vertellen aan welke entiteitsklasse de resultaten moeten worden toegewezen. Daarom hebben we de resultaatklasse eigendom om dit te doen.

Een andere manier om de resultaten in kaart te brengen, is door de resultSetMapping eigendom. Hier kunnen we de naam specificeren van een voorgedefinieerd SQLResultSetMapping.

Merk op dat we er slechts één kunnen gebruiken resultaatklasse en resultSetMapping.

4.1. Met behulp van de Named Native Query

Om de benoemde native query te gebruiken, kunnen we de Session.createNamedQuery ():

Queryquery = session.createNamedQuery ("DeptEmployee_FindByEmployeeName", DeptEmployee.class); query.setParameter ("naam", "John Wayne"); DeptEmployee-resultaat = query.getSingleResult ();

Of de Session.getNamedNativeQuery ():

NativeQuery-query = session.getNamedNativeQuery ("DeptEmployee_FindByEmployeeName"); query.setParameter ("naam", "John Wayne"); DeptEmployee-resultaat = (DeptEmployee) query.getSingleResult ();

Het enige verschil tussen deze twee benaderingen is het retourtype. De tweede benadering retourneert een NativeQuery, dat is een subklasse van Vraag.

5. Opgeslagen procedures en functies

We kunnen de @NamedNativeQuery annotatie om ook oproepen naar opgeslagen procedures en functies te definiëren:

@ org.hibernate.annotations.NamedNativeQuery (name = "DeptEmployee_UpdateEmployeeDesignation", query = "call UPDATE_EMPLOYEE_DESIGNATION (: employeeNumber,: newDesignation)", resultClass = DeptEmployee.class)

Merk op dat hoewel dit een updatevraag is, we de resultaatklasse eigendom. Dit komt doordat Hibernate geen pure native scalaire query's ondersteunt. En de manier om het probleem te omzeilen, is door een resultaatklasse of een resultSetMapping.

6. Conclusie

In dit artikel hebben we gezien hoe benoemde HQL en native queries kunnen worden gedefinieerd en gebruikt.

De broncode is beschikbaar op GitHub.