Sorteren met slaapstand

1. Overzicht

Dit artikel illustreert hoe te sorteren met slaapstand, met behulp van zowel de Hibernate Query Language (HQL) als de Criteria API.

2. Sorteren met HQL

Sorteren met Hibernate's HQL is net zo eenvoudig als het toevoegen van de Bestel per clausule aan de HQL-queryreeks:

String hql = "VAN Foo f ORDER BY f.name"; Queryquery = sess.createQuery (hql);

Nadat deze code is uitgevoerd, genereert Hibernate de volgende SQL-query:

Slaapstand: selecteer foo0_.ID als ID1_0_, foo0_.NAME als NAME2_0_ van FOO foo0_ order by foo0_.NAME

De standaard sorteervolgorde is oplopend. Dit is de reden waarom de bestelvoorwaarde, asc, is niet opgenomen in de gegenereerde SQL-query.

2.1. Een expliciete sorteervolgorde gebruiken

Als u de sorteervolgorde handmatig wilt opgeven, moet u de volgorde van de volgorde in de HQL queryreeks:

String hql = "VAN Foo f ORDER BY f.name ASC"; Queryquery = sess.createQuery (hql);

In dit voorbeeld stelt u de asc clausule in de HQL is opgenomen in de gegenereerde SQL-query:

Slaapstand: selecteer foo0_.ID als ID1_0_, foo0_.NAME als NAME2_0_ van FOO foo0_ order by foo0_.NAME ASC

2.2. Sorteren op meer dan één kenmerk

Meerdere attributen, samen met een optionele sorteervolgorde, kunnen aan de Bestel per clausule in de HQL-queryreeks:

String hql = "VAN FOO f ORDER BY f.name DESC, f.id ASC"; Queryquery = sess.createQuery (hql);

De gegenereerde SQL-query zal dienovereenkomstig veranderen:

Slaapstand: selecteer foo0_.ID als ID1_0_, foo0_.NAME als NAME2_0_ van FOO foo0_ order door foo0_.NAME DESC, foo0_.ID ASC

2.3. Sorteerprioriteit van null-waarden instellen

Als het kenmerk waarop moet worden gesorteerd, standaard nul waarden, het is aan de RDMS om de prioriteit te bepalen. Deze standaardbehandeling kan worden opgeheven door een EERSTE NULLS of NULLS LAATSTE clausule in de HQL-queryreeks.

In dit eenvoudige voorbeeld worden alle null-waarden aan het einde van de resultatenlijst geplaatst:

String hql = "VAN Foo f ORDER BY f.name NULLS LAST"; Queryquery = sess.createQuery (hql);

Laten we eens kijken naar de is nul dan 1 anders 0 clausule in de gegenereerde SQL-query:

Slaapstand: selecteer foo0_.ID als ID1_1_, foo0_.NAME als NAME2_1_, foo0_.BAR_ID als BAR_ID3_1_, foo0_.idx als idx4_1_ van FOO foo0_ volgorde per geval wanneer foo0_.NAME nul is en 1 else 0 end, foo0_.NAME

2.4. Een naar veel relaties sorteren

Laten we een complex sorteergeval analyseren: het sorteren van entiteiten in een een-op-veel-relatieBar met een verzameling van Foo entiteiten.

We doen dit door de collectie te annoteren met de Slaapstand @OrderBy annotatie; we zullen het veld specificeren waarmee de bestelling wordt gedaan, evenals de richting:

@OrderBy (clausule = "NAAM DESC") Stel fooList = nieuwe HashSet ();

Let erop dat clausule argument bij de annotatie. Dit is uniek voor Hibernate @OrderBy, in vergelijking met vergelijkbaar @OrderBy JPA-annotatie. Een ander kenmerk dat deze benadering onderscheidt van zijn JPA-equivalent, is dat de clausule argument geeft aan dat het sorteren gebeurt op basis van de NAAM kolom van de FOO tafel, niet op de naam kenmerk van Foo.

Laten we nu eens kijken naar de daadwerkelijke sortering van Bars en Foos:

String hql = "VAN Bar b ORDER BY b.id"; Queryquery = sess.createQuery (hql);

De resulterende SQL-instructie laat zien dat de gesorteerde Foo's worden geplaatst in een fooList:

Hibernate: selecteer bar0_.ID als ID1_0_, bar0_.NAME als NAME2_0_ van BAR bar0_ order by bar0_.ID Hibernate: selecteer foolist0_.BAR_ID als BAR_ID3_0_0_, foolist0_.ID als ID1_1_0_, foolist0_.ID_AME_ as ID1_1_AME_1, foolist0_.ID_AME_ .BAR_ID als BAR_ID3_1_1_, foolist0_.idx als idx4_1_1_ van FOO foolist0_ waar foolist0_.BAR_ID =? bestellen door foolist0_.NAME desc

Een ding om in gedachten te houden is dat het zo is het is niet mogelijk om lijsten te sorteren zoals het geval was met JPA. In de slaapstanddocumentatie staat:

“Hibernate negeert momenteel @OrderBy op @ElementCollection op bijv. Lijst. De volgorde van de elementen is zoals geretourneerd door de database, niet gedefinieerd. "

Als een kanttekening: het is mogelijk om deze beperking te omzeilen door legacy XML-configuratie voor Hibernate te gebruiken en de element met een element.

3. Sorteren met slaapstandcriteria

De Criteria Object API biedt de Bestellen class als de belangrijkste API om het sorteren te beheren.

3.1. De sorteervolgorde instellen

De Bestellen class heeft twee methoden om de sorteervolgorde in te stellen:

  • asc(String-attribuut) : Sorteert de zoekopdracht op attribuut in oplopende volgorde.
  • aflop(String-attribuut) : Sorteert de zoekopdracht op attribuut in aflopende volgorde.

Laten we beginnen met een eenvoudig voorbeeld - sorteren op één ID kaart attribuut:

Criteria criteria = sess.createCriteria (Foo.class, "FOO"); criteria.addOrder (Order.asc ("id"));

Merk op dat het argument voor de asc methode is hoofdlettergevoelig en moet overeenkomen met de naam van het attribuut waarop moet worden gesorteerd.

De Object API van Hibernate Criteria stelt expliciet een sorteervolgorde in en dit wordt weerspiegeld in de SQL-instructie die door de code wordt gegenereerd:

Slaapstand: selecteer this_.ID als ID1_0_0_, this_.NAME als NAME2_0_0_ van FOO this_ order by this_.ID sac

3.2. Sorteren op meer dan één kenmerk

Als u op meerdere attributen sorteert, hoeft u alleen een Bestellen bezwaar maken tegen de Criteria bijvoorbeeld, zoals in het onderstaande voorbeeld:

Criteria criteria = sess.createCriteria (Foo.class, "FOO"); criteria.addOrder (Order.asc ("naam")); criteria.addOrder (Order.asc ("id"));

De query die wordt gegenereerd in SQL is:

Slaapstand: selecteer this_.ID als ID1_0_0_, this_.NAME als NAME2_0_0_ van FOO this_ order by this_.NAME asc, this_.ID sac

3.3. Sorteerprioriteit van null-waarden instellen

Als het kenmerk waarop moet worden gesorteerd, standaard nul waarden, het is aan de RDMS om de prioriteit te bepalen. Hibernate Criteria Object API maakt het eenvoudig om die standaard en plaats nulwaarden aan het einde van een oplopende geordende lijst:

Criteria criteria = sess.createCriteria (Foo.class, "FOO"); criteria.addOrder (Order.asc ("naam"). nulls (NullPrecedence.LAST));

Hier is het onderliggende SQL query - met de is nul dan 1 anders 0 clausule:

Slaapstand: selecteer this_.ID als ID1_1_1_, this_.NAME als NAME2_1_1_, this_.BAR_ID als BAR_ID3_1_1_, this_.idx als idx4_1_1_, bar2_.ID als ID1_0_0_, bar2_.NAME als NAME2_0_0_ van FOO sorteer per geval wanneer this_.NAME null is 1 else 0 einde, this_NAAM asc

Als alternatief kunnen we ook plaats de nullen aan het begin van een aflopende geordende lijst:

Criteria criteria = sess.createCriteria (Foo.class, "FOO"); criteria.addOrder (Order.desc ("naam"). nulls (NullPrecedence.FIRST));

De bijbehorende SQL-query volgt - met de is nul dan 0 anders 1 clausule:

Slaapstand: selecteer this_.ID als ID1_1_1_, this_.NAME als NAME2_1_1_, this_.BAR_ID als BAR_ID3_1_1_, this_.idx als idx4_1_1_, bar2_.ID als ID1_0_0_, bar2_.NAME als NAME2_0_0_ van FOO sorteer per geval wanneer this_.NAME null is 0 anders 1 einde, this_.NAME desc

Let daar op, als het attribuut waarop moet worden gesorteerd een primitief type is, zoals een int, een PresisitenceException zal gooien.

Als de waarde van f.anIntVariable nul is, dan is de uitvoering van de vraag:

String jql = "Selecteer f uit Foo als f volgorde door f.anIntVariable desc NULLS FIRST"; Query sortQuery = entityManager.createQuery (jql);

zal gooien:

javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: Null-waarde is toegewezen aan een eigenschap van het primitieve type setter van com.cc.jpa.example.Foo.anIntVariable

4. Conclusie

Dit artikel onderzoekt het sorteren met Hibernate - het gebruik van de beschikbare API's voor zowel eenvoudige entiteiten als entiteiten in een een-op-veel-relatie.

De implementatie van deze Hibernate Sorting Tutorial is te vinden in het github-project - dit is een op Eclipse gebaseerd project, dus het zou gemakkelijk te importeren en uit te voeren moeten zijn zoals het is.