Spring-Data-JPA注释的setMaxResults?

sma*_*ufo 110 java spring jpa spring-data spring-data-jpa

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

例如,我的代码:

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

我只需one (and only one)要从otherObj 返回用户,但我找不到一种方法来注释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
Run Code Online (Sandbox Code Playgroud)

)

我找到了一个链接:https://jira.springsource.org/browse/DATAJPA-147,我试过但失败了.现在似乎不可能?为什么Spring-Data中没有内置这么重要的功能?

如果我手动实现此功能:

public class UserRepositoryImpl implements UserRepository
Run Code Online (Sandbox Code Playgroud)

我必须实现大量的预定义方法CrudRepository,这将是可怕的.

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

Oli*_*ohm 167

截至Spring Data JPA 1.7.0(Evans发布列车).

...您可以使用新引进的Top,并First允许您定义的查询方法,如这些关键字:

findTop10ByLastnameOrderByFirstnameAsc(String lastname);
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

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

如果你需要知道结果的上下文(它实际上是哪一页?它是第一个?总共有多少?)Page用作返回类型:

public interface UserRepository extends Repository<User, Long> {

  Page<User> findByUsername(String username, Pageable pageable);
}
Run Code Online (Sandbox Code Playgroud)

然后客户端代码可以执行以下操作:

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

并不是我们将触发要执行的实际查询的计数投影,以防您使用Page返回类型,因为我们需要找出总计有多少元素来计算元数据.除此之外,请确保您实际装备了PageRequest分类信息以获得稳定的结果.否则,您可能会触发查询两次并获得不同的结果,即使数据没有在下面更改.

  • 谢谢,但我仍然希望有一个'基于注释'的解决方案.因为在这种情况下'Page/Pageable'太过分了.客户必须创建一个Pageable/Page来检索"一个且唯一一个"的结果......使用起来非常不友好.看来你负责Spring-Data,我希望你能进一步研究这个问题:http://stackoverflow.com/questions/9276461/spring-data-makes-spring-unable-to-find-jaxrss-提供者.你能否确认它是否是Spring-Data的错误? (12认同)
  • 对,如何使用命名查询? (3认同)
  • 我认为,`Top`和`First`关键字不适用于使用`@ Query`注释的方法?只有那些使用基于方法名称的查询生成? (3认同)
  • + 这可行,谢谢,但基于注释的解决方案在新版本中会更好 (2认同)
  • 这里触发了一个计数查询,如果我们想要一个有限的查询,这是完全没有必要的。 (2认同)

Wim*_*uwe 96

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

}
Run Code Online (Sandbox Code Playgroud)

  • 可能对单个结果有用`Stream <User> ... {...} default可选<User> ... {... findAny()}` (3认同)

nca*_*cea 27

有一种方法可以提供相当于"a by注释的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);
}
Run Code Online (Sandbox Code Playgroud)

当将可分页作为参数发送时,这应该可以解决问题.例如,要获取前10条记录,您需要将可分页设置为此值:

new PageRequest(0, 10)
Run Code Online (Sandbox Code Playgroud)


aze*_*ati 21

使用Spring Data Evans(1.7.0 RELEASE)

新版本的Spring Data JPA和另一个名为Evans的模块列表具有使用关键字Top20First限制查询结果的功能,

所以你现在可以写了

List<User> findTop20ByLastname(String lastname, Sort sort);
Run Code Online (Sandbox Code Playgroud)

要么

List<User> findTop20ByLastnameOrderByIdDesc(String lastname);
Run Code Online (Sandbox Code Playgroud)

或者单个结果

List<User> findFirstByLastnameOrderByIdDesc(String lastname);
Run Code Online (Sandbox Code Playgroud)

  • 可选<User> findFirstByLastnameOrderByIdDesc(String lastname); (4认同)

GKi*_*lin 11

我的最佳选择是原生查询:

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

  • 打破整个概念!最好使用 EntityManager 代替! (2认同)

小智 8

new PageRequest(0,10)在较新的 Spring 版本中不起作用(我正在使用2.2.1.RELEASE)。基本上,构造函数有一个额外的参数作为Sort类型。此外,构造函数protected使您必须使用其子类之一或调用其of静态方法:

PageRequest.of(0, 10, Sort.sort(User.class).by(User::getFirstName).ascending()))
Run Code Online (Sandbox Code Playgroud)

您还可以省略Sort参数的使用并隐式使用默认排序(按 pk 等排序):

PageRequest.of(0, 10)
Run Code Online (Sandbox Code Playgroud)

你的函数声明应该是这样的:

List<User> findByUsername(String username, Pageable pageable)
Run Code Online (Sandbox Code Playgroud)

功能将是:

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


kra*_*ken 6

它也可以使用@QueryHints.示例bellow使用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();
Run Code Online (Sandbox Code Playgroud)

  • org.hibernate.annotations.FETCH_SIZE其获取大小,不限制,不是最大结果.Hiber不能 (2认同)

小智 5

如果您的课程@Repository扩展了,JpaRepository您可以使用下面的示例。

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

getContent返回List<Transaction>