148

Spring-Data-JPA を自分のプロジェクトに取り込もうとしています。私を混乱させることの 1 つは、注釈によって setMaxResults(n) を達成する方法です。

たとえば、私のコード:

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

user を otherObjから返す必要があるだけですがone (and only one)、maxResults に注釈を付ける方法が見つかりません。誰かが私にヒントを与えることができますか?

(mysqlは不平を言います:

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

)

リンクを見つけました: https://jira.springsource.org/browse/DATAJPA-147、試してみましたが失敗しました。今は無理っぽい?このような重要な機能が Spring-Data に組み込まれていないのはなぜですか?

この機能を手動で実装する場合:

public class UserRepositoryImpl implements UserRepository

に大量の事前定義されたメソッドを実装CrudRepositoryする必要があります。これはひどいことです。

環境: spring-3.1 、 spring-data-jpa-1.0.3.RELEASE.jar 、 spring-data-commons-core-1.1.0.RELEASE.jar

4

8 に答える 8

201

Spring Data JPA 1.7.0 (Evans リリーストレイン) 以降。

新しく導入されたTopandFirstキーワードを使用して、次のようにクエリ メソッドを定義できます。

findTop10ByLastnameOrderByFirstnameAsc(String lastname);

Spring Data は、結果を定義した数に自動的に制限します (省略した場合のデフォルトは 1 です)。ここでは、結果の順序が重要になることに注意してください (OrderBy例に示されている句を使用するかSort、メソッドにパラメーターを渡すことによって)。詳細については、Spring Data Evans リリース トレインの新機能をカバーするブログ投稿またはドキュメントを参照してください。

以前のバージョンの場合

データのスライスのみを取得するために、Spring Data はPageable、要求側のインターフェースとPage結果側の抽象化に付属するページネーション抽象化を使用します。だからあなたはから始めることができます

public interface UserRepository extends Repository<User, Long> {

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

次のように使用します。

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

結果のコンテキストを知る必要がある場合 (実際にはどのページですか? 最初のページですか? 合計で何ページありますか?)、Page戻り値の型として使用します。

public interface UserRepository extends Repository<User, Long> {

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

クライアントコードは、次のようなことを行うことができます:

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

Pageメタデータを計算するために合計でいくつの要素があるかを調べる必要があるため、戻り値の型として使用する場合に実行される実際のクエリのカウント プロジェクションをトリガーするわけではありません。PageRequestそれを超えて、安定した結果を得るために、実際に並べ替え情報を備えていることを確認してください。そうしないと、下のデータが変更されていなくても、クエリを 2 回トリガーして異なる結果が得られる可能性があります。

于 2012-02-16T17:26:34.977 に答える
115

Java 8 と Spring Data 1.7.0 を使用している場合、@Queryアノテーションを組み合わせて最大結果を設定する場合は、デフォルトのメソッドを使用できます。

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

}
于 2016-02-08T08:50:10.833 に答える
30

次のように、「注釈による setMaxResults(n)」に相当するものを提供する方法があります。

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

pageable がパラメーターとして送信された場合、これでうまくいくはずです。たとえば、最初の 10 レコードを取得するには、pageable を次の値に設定する必要があります。

new PageRequest(0, 10)
于 2015-02-10T23:54:49.357 に答える
26

Spring Data Evans を使用する (1.7.0 RELEASE)

Evansと呼ばれるモジュールの別のリストをまとめた Spring Data JPA の新しいリリースには、キーワードを使用してクエリ結果を制限する機能がTop20ありFirstます。

だからあなたは今書くことができます

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

また

List<User> findTop20ByLastnameOrderByIdDesc(String lastname);

または単一の結果

List<User> findFirstByLastnameOrderByIdDesc(String lastname);
于 2014-10-19T09:38:58.160 に答える
14

私にとって最良の選択はネイティブクエリです:

@Query(value="SELECT * FROM users WHERE other_obj = ?1 LIMIT 1", nativeQuery = true)
User findByOhterObj(OtherObj otherObj);
于 2016-12-07T18:56:11.937 に答える
6

@QueryHints を使用することも可能です。以下の例では、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();
于 2015-08-26T08:12:59.950 に答える
5

クラス@Repositoryが拡張されJpaRepositoryている場合は、以下の例を使用できます。

int limited = 100;
Pageable pageable = new PageRequest(0,limited);
Page<Transaction> transactionsPage = transactionRepository.findAll(specification, pageable);
return transactionsPage.getContent();

getContent を返しますList<Transaction>

于 2017-09-22T20:02:11.653 に答える