Java Spring数据JPA注释的setMaxResults?

Java Spring数据JPA注释的setMaxResults?,java,spring,jpa,spring-data,spring-data-jpa,Java,Spring,Jpa,Spring Data,Spring Data Jpa,我正在尝试将Spring数据JPA合并到我的项目中。 让我困惑的一件事是如何通过注释实现setMaxResults(n) 例如,我的代码: public interface UserRepository extends CrudRepository<User , Long> { @Query(value="From User u where u.otherObj = ?1 ") public User findByOtherObj(OtherObj oth

我正在尝试将Spring数据JPA合并到我的项目中。 让我困惑的一件事是如何通过注释实现setMaxResults(n)

例如,我的代码:

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

我找到了一个链接:, 我试过了,但失败了。现在看来不可能了? 为什么Spring数据中没有内置如此重要的功能

如果我手动实现此功能:

public class UserRepositoryImpl implements UserRepository
我必须在
crudepository
中实现大量预定义的方法,这将非常糟糕

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

自spring-data jpa 1.7.0(Evans发布系列)起。 您可以使用新引入的
Top
First
关键字来定义如下查询方法:

findTop10ByLastnameOrderByFirstnameAsc(String lastname);
Pageable topTen = new PageRequest(0, 10);
List<User> result = repository.findByUsername("Matthews", topTen);
Pageable topTen = new PageRequest(0, 10);
Page<User> result = repository.findByUsername("Matthews", topTen);
Assert.assertThat(result.isFirstPage(), is(true));
List<User> findByUsername(String username, Pageable pageable)
Spring数据将自动将结果限制为您定义的数字(如果省略,则默认为1)。请注意,结果的顺序在这里变得相关(如示例中所示,可以通过
OrderBy
子句,也可以通过将
Sort
参数传递到方法中)。阅读更多关于这一点的博客文章或在

对于以前的版本 为了只检索数据片段,Spring数据使用分页抽象,它在请求端带有一个
Pageable
接口,在结果端带有一个
Page
抽象。所以你可以从

public interface UserRepository extends Repository<User, Long> {

  List<User> findByUsername(String username, Pageable pageable);
}
然后,客户端代码可以执行以下操作:

findTop10ByLastnameOrderByFirstnameAsc(String lastname);
Pageable topTen = new PageRequest(0, 10);
List<User> result = repository.findByUsername("Matthews", topTen);
Pageable topTen = new PageRequest(0, 10);
Page<User> result = repository.findByUsername("Matthews", topTen);
Assert.assertThat(result.isFirstPage(), is(true));
List<User> findByUsername(String username, Pageable pageable)
Pageable topTen=新页面请求(0,10);
页面结果=repository.findByUsername(“Matthews”,前十名);
Assert.assertThat(result.isFirstPage(),is(true));
并不是说,如果您使用
Page
作为返回类型,我们将触发实际查询的计数投影,因为我们需要找出总共有多少个元素来计算元数据。除此之外,请确保实际为
PageRequest
配备了排序信息,以获得稳定的结果。否则,即使下面的数据没有更改,也可能会触发两次查询并获得不同的结果

Spring Data JPA的新版本与另一个模块列表一起命名,具有使用关键字
Top20
First
限制查询结果的功能

所以你现在可以写了

List findTop20ByLastname(字符串lastname,排序);

列出findtop20bylastnameordbyiddesc(字符串lastname);
还是为了一个结果

列出findfirstbylastname orderbyiddesc(字符串lastname);

有一种方法可以提供与“setMaxResults(n)by annotation”等效的结果,如下所示:

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

也可以使用@QueryHints。下面的示例使用org.eclipse.persistence.config.QueryHints#JDBC_MAX_行

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

如果您使用的是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));
  }

}
public interface UserRepository扩展了分页和排序存储库{
@查询(“来自用户u,其中…”)
列出findAllUsersWhereFoo(@Param(“foo”)foo-foo,可分页;
默认列表findTop10UsersWhereFoo(Foo-Foo){
返回findAllUsersWhereFoo(foo,新页面请求(0,10));
}
}

我的最佳选择是本机查询:

@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();
int limited=100;
Pageable Pageable=新的页面请求(0,有限);
Page TransactionPage=transactionRepository.findAll(规范,可分页);
返回TransactionPage.getContent();
getContent返回一个
列表

新页面请求(0,10)
在较新的Spring版本中不起作用(我使用的是
2.2.1.版本
)。基本上,构造函数获得了一个附加参数,即
Sort
type。此外,构造函数受
保护
,因此您必须使用它的一个子类或调用它的
of
静态方法:

PageRequest.of(0, 10, Sort.sort(User.class).by(User::getFirstName).ascending()))
您还可以省略使用
Sort
参数,隐式使用默认排序(按主键排序等):

您的函数声明应该如下所示:

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

谢谢,但我还是希望有一个“基于注释”的解决方案。因为在这种情况下,“分页/可分页”太过分了。客户端必须创建一个可分页/页面来检索“一个且只有一个”结果。。。使用起来很不友好。看起来您负责Spring数据,我希望您能进一步研究这个问题:。你能确认这是否是Spring Data的错误吗?+这很有效,谢谢,但在较新版本中,基于注释的解决方案会更好。如果我们需要有限的查询,这里会触发计数查询,这是完全不必要的。如果你使用
List
作为方法的返回类型,这不是问题。我认为,
Top
First
关键字不适用于使用
@Query
注释的方法?只有那些使用基于方法名的查询生成的?我已经测试了这段代码,但它不起作用。没有例外,但没有适当的结果。此外,关于查询点的文档也非常少。见下文。IIRC,不能保证会遵循查询提示。这只是向实现传递“友好建议”的一种方式。我在hibernate中尝试使用
@QueryHints({@QueryHint(name=org.hibernate.annotations.FETCH_SIZE,value=“1”)}
,但别名:(不工作rg.hibernate.annotations.FETCH_调整其获取大小,而不是限制,而不是最大结果。Hiber cantOptional findFirstByLastnameOrderByIdDesc(字符串lastname);在获得前20个结果后,当我使用分页进入网站的下一页时,我将如何获得下20个结果?@kittu,这当然是另一个问题,但你需要传递一个
Pageable
对象。查看spring文档为什么他们让方法返回一个该死的列表,如果它是先指定的??最好将返回类型写为l作为