setMaxResults für Spring-Data-JPA-Annotation?

Lesezeit: 7 Minuten

setMaxResults fur Spring Data JPA Annotation
kleinufo

Ich versuche, Spring-Data-JPA in mein Projekt zu integrieren. Eine Sache, die mich verwirrt, ist, wie ich setMaxResults(n) durch Annotation erreiche?

zum Beispiel mein Code:

public interface UserRepository extends CrudRepository<User , Long>
{
  @Query(value="From User u where u.otherObj = ?1 ")
  public User findByOtherObj(OtherObj otherObj);
}

Ich muss nur zurück one (and only one) Benutzer von otherObj, aber ich kann keine Möglichkeit finden, die maxResults zu kommentieren. Kann mir jemand einen Hinweis geben?

(mysql beschwert sich:

com.mysql.jdbc.JDBC4PreparedStatement@5add5415: select user0_.id as id100_, user0_.created as created100_ from User user0_ where user0_.id=2 limit ** NOT SPECIFIED **
WARN  util.JDBCExceptionReporter - SQL Error: 0, SQLState: 07001
ERROR util.JDBCExceptionReporter - No value specified for parameter 2

)

Ich habe einen Link gefunden: https://jira.springsource.org/browse/DATAJPA-147, ich habe es versucht, bin aber gescheitert. Es scheint jetzt nicht möglich zu sein? Warum ist eine so wichtige Funktion nicht in Spring-Data integriert?

Wenn ich diese Funktion manuell implementiere:

public class UserRepositoryImpl implements UserRepository

Ich muss unzählige vordefinierte Methoden implementieren CrudRepositorydas wäre schrecklich.

Umgebungen: spring-3.1 , spring-data-jpa-1.0.3.RELEASE.jar , spring-data-commons-core-1.1.0.RELEASE.jar

setMaxResults fur Spring Data JPA Annotation
Oliver Drotbohm

Ab Spring Data JPA 1.7.0 (Evans Release Train).

Sie können die neu eingeführten verwenden Top und First Schlüsselwörter, mit denen Sie Abfragemethoden wie folgt definieren können:

findTop10ByLastnameOrderByFirstnameAsc(String lastname);

Spring Data begrenzt die Ergebnisse automatisch auf die von Ihnen definierte Zahl (standardmäßig 1, wenn weggelassen). Beachten Sie, dass die Reihenfolge der Ergebnisse hier relevant wird (entweder durch eine OrderBy Klausel wie im Beispiel zu sehen oder durch Übergabe von a Sort Parameter in die Methode). Lesen Sie mehr dazu im Blogbeitrag zum Thema neue Funktionen des Release Train von Spring Data Evans oder im Dokumentation.

Für frühere Versionen

Um nur Datensegmente abzurufen, verwendet Spring Data die Paginierungsabstraktion, die mit a geliefert wird Pageable Schnittstelle auf der anfordernden Seite sowie a Page Abstraktion auf der Ergebnisseite der Dinge. Damit könntest du anfangen

public interface UserRepository extends Repository<User, Long> {

  List<User> findByUsername(String username, Pageable pageable);
}

und benutze es so:

Pageable topTen = new PageRequest(0, 10);
List<User> result = repository.findByUsername("Matthews", topTen);

Wenn Sie den Kontext des Ergebnisses wissen müssen (um welche Seite handelt es sich eigentlich? Ist es die erste? Wie viele sind es insgesamt?), verwenden Sie Page als Rückgabetyp:

public interface UserRepository extends Repository<User, Long> {

  Page<User> findByUsername(String username, Pageable pageable);
}

Der Client-Code kann dann so etwas tun:

Pageable topTen = new PageRequest(0, 10);
Page<User> result = repository.findByUsername("Matthews", topTen);
Assert.assertThat(result.isFirstPage(), is(true));

Nicht, dass wir eine Zählprojektion der tatsächlich auszuführenden Abfrage auslösen, falls Sie verwenden Page als Rückgabetyp, da wir herausfinden müssen, wie viele Elemente es insgesamt gibt, um die Metadaten zu berechnen. Stellen Sie darüber hinaus sicher, dass Sie die tatsächlich ausrüsten PageRequest mit Sortierinformationen, um stabile Ergebnisse zu erhalten. Andernfalls könnten Sie die Abfrage zweimal auslösen und unterschiedliche Ergebnisse erhalten, auch ohne dass sich die Daten darunter geändert haben.

  • Danke, aber ich hoffe immer noch auf eine annotationsbasierte Lösung. Denn ‘Page / Pageable’ sind in diesem Fall zu übertrieben. Und der Client muss eine Pageable/Page erstellen, um “ein und nur ein” Ergebnis abzurufen … Es ist sehr unfreundlich zu verwenden. Und es scheint, dass Sie für Spring-Data verantwortlich sind. Ich hoffe, Sie können dieses Problem weiter untersuchen: stackoverflow.com/questions/9276461/… . Können Sie bestätigen, ob es sich um den Fehler von Spring-Data handelt?

    – Kleinufo

    17. Februar 12 um 0:59 Uhr

  • + das funktioniert, danke, aber eine annotationsbasierte Lösung wäre in neueren Versionen besser

    – aserafati

    28. Juni 14 um 12:17 Uhr


  • Hier wird eine Zählabfrage ausgelöst, was völlig unnötig ist, wenn wir eine begrenzte Abfrage wünschen.

    – aserafati

    16. September 14 um 9:11 Uhr

  • Es ist nicht, wenn Sie verwenden List als Rückgabetyp der Methode.

    – Oliver Drotbohm

    16. September 14 um 15:05 Uhr

  • Ich denke, Top und First Schlüsselwörter sind nicht auf Methoden anwendbar, die verwenden @Query Anmerkung? Nur die, die Methodennamen-basierte Abfragegenerierung verwenden?

    – Ruslan Stelmachenko

    27. Juni 16 um 2:38 Uhr

Wenn Sie Java 8 und Spring Data 1.7.0 verwenden, können Sie Standardmethoden verwenden, wenn Sie a kombinieren möchten @Query Anmerkung mit Einstellung der maximalen Ergebnisse:

public interface UserRepository extends PagingAndSortingRepository<User,Long> {
  @Query("from User u where ...")
  List<User> findAllUsersWhereFoo(@Param("foo") Foo foo, Pageable pageable);

  default List<User> findTop10UsersWhereFoo(Foo foo) {
    return findAllUsersWhereFoo(foo, new PageRequest(0,10));
  }

}

  • potenziell nützlich für ein einzelnes Ergebnis Stream<User> ... {...} default Optional<User> ... { ...findAny() }

    – Fremdenmord

    2. Februar 17 um 23:16 Uhr

Es gibt eine Möglichkeit, das Äquivalent von “a setMaxResults(n) by annotation” wie im Folgenden bereitzustellen:

public interface ISomething extends JpaRepository<XYZ, Long>
{
    @Query("FROM XYZ a WHERE a.eventDateTime < :before ORDER BY a.eventDateTime DESC")
    List<XYZ> findXYZRecords(@Param("before") Date before, Pageable pageable);
}

Dies sollte funktionieren, wenn ein Pageable als Parameter gesendet wird. Um beispielsweise die ersten 10 Datensätze abzurufen, müssen Sie pageable auf diesen Wert setzen:

new PageRequest(0, 10)

  • Wenn Sie Pagable verwenden, ist die Rückgabe Page nicht List

    – Arundew

    4. August 17 um 11:05 Uhr

  • @Arundev falsch – List funktioniert einwandfrei (und vermeidet eine unnötige count Abfrage wie bereits in einem vorherigen Kommentar erwähnt)

    – Janaka Bandara

    14. Juni 20 um 5:36 Uhr


1644074290 12 setMaxResults fur Spring Data JPA Annotation
Aserafati

Verwenden Sie Spring Data Evans (Version 1.7.0)

die neue Version von Spring Data JPA mit einer anderen Liste von Modulen zusammen genannt Evans hat die Funktion, Schlüsselwörter zu verwenden Top20 und First um das Abfrageergebnis einzuschränken,

so könntest du jetzt schreiben

List<User> findTop20ByLastname(String lastname, Sort sort);

oder

List<User> findTop20ByLastnameOrderByIdDesc(String lastname);

oder für ein einzelnes Ergebnis

List<User> findFirstByLastnameOrderByIdDesc(String lastname);

Die beste Wahl für mich ist die native Abfrage:

@Query(value="SELECT * FROM users WHERE other_obj = ?1 LIMIT 1", nativeQuery = true)
User findByOhterObj(OtherObj otherObj);

  • Nicht sicher, ob das Limit im Ruhezustand unterstützt wird: forum.hibernate.org/viewtopic.php?f=9&t=939314

    – Witold Kaczurba

    28. April 17 um 12:38 Uhr

  • Bricht das ganze Konzept! Verwenden Sie stattdessen besser den EntityManager!

    – Spektakulatius

    7. Juli 17 um 12:08 Uhr

  • @Code.IT Ich propagiere das KISS-Konzept. Abgesehen davon JPA nativeQuery Anmerkungsparameter hinzugefügt, nicht zum Ignorieren.

    – Grigori Kislin

    11. Juli 17 um 14:08 Uhr


  • @GKislin, dann müssen Sie Ihre Methode wie findLimitOneByOtherObj umbenennen. Außerdem haben Sie vergessen, ein OrderBy hinzuzufügen, was zu einem falschen Ergebnis führt, wenn das other_obj nicht eindeutig ist. Andernfalls sollte eine Where-Anweisung in einer eindeutigen Spalte ohne Begrenzung ausreichen

    – Spektakulatius

    11. Juli 17 um 14:13 Uhr

  • Das Schlüsselwort LIMIT ist nicht Hibernate, sondern postgres/mysql

    – Acewin

    17. September 18 um 15:52 Uhr

1644074290 717 setMaxResults fur Spring Data JPA Annotation
Abbas Hosseini

new PageRequest(0,10) funktioniert nicht in neueren Spring-Versionen (ich verwende 2.2.1.RELEASE). Grundsätzlich hat der Konstruktor einen zusätzlichen Parameter als erhalten Sort Typ. Außerdem ist der Konstruktor protected Sie müssen also entweder eine ihrer untergeordneten Klassen verwenden oder sie aufrufen of statische Methode:

PageRequest.of(0, 10, Sort.sort(User.class).by(User::getFirstName).ascending()))

Sie können auch auf die Verwendung von verzichten Sort Parameter und verwenden Sie implizit die Standardsortierung (sortieren nach pk usw.):

PageRequest.of(0, 10)

Ihre Funktionsdeklaration sollte in etwa so aussehen:

List<User> findByUsername(String username, Pageable pageable)

und die Funktion wird sein:

userRepository.findByUsername("Abbas", PageRequest.of(0,10, Sort.sort(User.class).by(User::getLastName).ascending());

  • Nicht sicher, ob das Limit im Ruhezustand unterstützt wird: forum.hibernate.org/viewtopic.php?f=9&t=939314

    – Witold Kaczurba

    28. April 17 um 12:38 Uhr

  • Bricht das ganze Konzept! Verwenden Sie stattdessen besser den EntityManager!

    – Spektakulatius

    7. Juli 17 um 12:08 Uhr

  • @Code.IT Ich propagiere das KISS-Konzept. Abgesehen davon JPA nativeQuery Anmerkungsparameter hinzugefügt, nicht zum Ignorieren.

    – Grigori Kislin

    11. Juli 17 um 14:08 Uhr


  • @GKislin, dann müssen Sie Ihre Methode wie findLimitOneByOtherObj umbenennen. Außerdem haben Sie vergessen, ein OrderBy hinzuzufügen, was zu einem falschen Ergebnis führt, wenn das other_obj nicht eindeutig ist. Andernfalls sollte eine Where-Anweisung in einer eindeutigen Spalte ohne Begrenzung ausreichen

    – Spektakulatius

    11. Juli 17 um 14:13 Uhr

  • Das Schlüsselwort LIMIT ist nicht Hibernate, sondern postgres/mysql

    – Acewin

    17. September 18 um 15:52 Uhr

1644074291 978 setMaxResults fur Spring Data JPA Annotation
Krake

Es ist auch möglich, @QueryHints zu verwenden. Das folgende Beispiel verwendet org.eclipse.persistence.config.QueryHints#JDBC_MAX_ROWS

@Query("SELECT u FROM User u WHERE .....")
@QueryHints(@QueryHint(name = JDBC_MAX_ROWS, value = "1"))
Voter findUser();

  • Ich habe diesen Code getestet, aber er funktioniert nicht. Keine Ausnahme, aber kein richtiges Ergebnis nacht. Auch die Dokumentation zu QueryHints ist sehr dünn. Siehe unten. docs.spring.io/spring-data/jpa/docs/1.7.1.RELEASE/reference/…

    – bogdan.rusu

    28. Oktober 15 um 9:37 Uhr


  • IIRC, es gibt keine Garantien dass ein Abfragehinweis befolgt wird. Es ist nur eine Möglichkeit, “freundliche Empfehlungen” an die Implementierung weiterzugeben.

    – Priidu Neemre

    26. April 16 um 13:38 Uhr


  • Ich versuche es mit @QueryHints({@QueryHint(name = org.hibernate.annotations.FETCH_SIZE, value = "1")}) im Ruhezustand, aber alias:( funktioniert nicht

    – Grigori Kislin

    7. Dezember 16 um 15:24 Uhr

  • org.hibernate.annotations.FETCH_SIZE seine Abrufgröße, es ist kein Limit, nicht die maximalen Ergebnisse. Hiber kann nicht

    – Zhuravskiy Vitaliy

    23. Juni 17 um 6:05 Uhr

.

784700cookie-checksetMaxResults für Spring-Data-JPA-Annotation?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy