java 为Spring-Data-JPA注解设置最大结果?

lyfkaqu1  于 2023-01-07  发布在  Java
关注(0)|答案(9)|浏览(158)

我正在尝试将Spring-Data-JPA合并到我的项目中,有一件事让我很困惑,那就是如何通过注解实现setMaxResults(n)?
例如,我的代码:

public interface UserRepository extends CrudRepository<User , Long>
{
  @Query(value="From User u where u.otherObj = ?1 ")
  public User findByOtherObj(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数据-jpa -1.0.3.版本. jar、Spring数据-通用核心-1.1.0.版本. jar

qpgpyjmq

qpgpyjmq1#

自Spring Data JPA 1.7.0(Evans发布系列)起。

您可以使用新引入的TopFirst关键字来定义如下查询方法:

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配备了排序信息,以获得稳定的结果。否则,您可能会触发查询两次,即使底层数据没有更改,也会得到不同的结果。

b1zrtrql

b1zrtrql2#

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

}
ghhkc1vu

ghhkc1vu3#

有一种方法可以提供“a 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);
}

当一个pagable作为参数发送时,这应该可以解决问题。例如,要获取前10条记录,您需要将pagable设置为以下值:

new PageRequest(0, 10)
h22fl7wq

h22fl7wq4#

使用Spring Data Evans(1.7.0版本)

SpringDataJPA的新版本与另一个模块列表一起称为Evans,具有使用关键字Top20First来限制查询结果的特性,
所以你现在可以写

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

List<User> findTop20ByLastnameOrderByIdDesc(String lastname);

或用于单个结果

List<User> findFirstByLastnameOrderByIdDesc(String lastname);
cngwdvgl

cngwdvgl5#

对我来说,最佳选择是原生查询:

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

cgyqldqp6#

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

PageRequest.of(0, 10, Sort.sort(User.class).by(User::getFirstName).ascending()))

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

PageRequest.of(0, 10)

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

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

并且函数将是:

userRepository.findByUsername("Abbas", PageRequest.of(0,10, Sort.sort(User.class).by(User::getLastName).ascending());
tct7dpnv

tct7dpnv7#

使用@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();
o8x7eapl

o8x7eapl8#

如果你的类@Repository扩展了JpaRepository,你可以使用下面的例子。

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

getContent返回一个List<Transaction>

cld4siwp

cld4siwp9#

用途

Pageable pageable = PageRequest.of(0,1);
Page<Transaction> transactionsPage = transactionRepository.findAll(specification, pageable);
return transactionsPage.getContent();

相关问题