Spring-Data-JPAをプロジェクトに組み込むことを試みています。私を混乱させる1つのことは、注釈によってsetMaxResults(n)をどのように達成するのですか?
たとえば、私のコード:
public interface UserRepository extends CrudRepository<User , Long>
{
@Query(value="From User u where u.otherObj = ?1 ")
public User findByOhterObj(OtherObj otherObj);
}
OtherObjからone (and only one)
Userのみを返す必要がありますが、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
新しく導入されたTop
およびFirst
キーワードを使用して、次のようなクエリメソッドを定義できます。
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回トリガーされ、その下でデータが変更されていなくても異なる結果が得られる場合があります。
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));
}
}
次のように、「注釈による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);
}
これは、ページング可能なものがパラメーターとして送信されるときに、トリックを行う必要があります。たとえば、最初の10レコードを取得するには、ページング可能をこの値に設定する必要があります。
new PageRequest(0, 10)
Evans と呼ばれるモジュールの別のリストを含むSpring Data JPAの新しいリリースには、キーワードTop20
およびFirst
を使用してクエリ結果を制限する機能があります。
だからあなたは今書くことができます
List<User> findTop20ByLastname(String lastname, Sort sort);
または
List<User> findTop20ByLastnameOrderByIdDesc(String lastname);
または単一の結果
List<User> findFirstByLastnameOrderByIdDesc(String lastname);
私にとって最良の選択はネイティブクエリです。
@Query(value="SELECT * FROM users WHERE other_obj = ?1 LIMIT 1", nativeQuery = true)
User findByOhterObj(OtherObj otherObj);
クラス@Repository
がJpaRepository
を拡張する場合、以下の例を使用できます。
int limited = 100;
Pageable pageable = new PageRequest(0,limited);
Page<Transaction> transactionsPage = transactionRepository.findAll(specification, pageable);
return transactionsPage.getContent();
getContentはList<Transaction>
を返します。
@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();