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.
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
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:
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)
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,
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
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:
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
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();
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
.
7847000cookie-checksetMaxResults für Spring-Data-JPA-Annotation?yes