用于 Spring-Data-JPA 注释的 setMaxResults? ?

我正在尝试将 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);
}

我只需要从 other Obj 返回 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

207544 次浏览

从 Spring Data 开始,JPA1.7.0(Evans 发布系列)。

您可以使用新引入的 TopFirst关键字,它们允许您像下面这样定义查询方法:

findTop10ByLastnameOrderByFirstnameAsc(String lastname);

SpringData 会自动将结果限制为您定义的数字(如果省略,则默认为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配备了排序信息,以获得稳定的结果。否则,您可能会触发两次查询,即使底层的数据没有更改,也会得到不同的结果。

使用 Spring Data Evans (1.7.0版本)

新发布的 Spring Data JPA 和另一个模块列表 埃文斯一起具有使用关键字 Top20First来限制查询结果的特点,

所以你现在可以写作了

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

或者

List<User> findTop20ByLastnameOrderByIdDesc(String lastname);

或者只为了一个结果

List<User> findFirstByLastnameOrderByIdDesc(String lastname);

有一种方法可以通过注释提供等效的“ asetMaxResults (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条记录:

new PageRequest(0, 10)

下面的示例使用 org.eclipse.persence.config. QueryHint # JDBC _ MAX _ ROWS

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

如果您正在使用 Java8和 SpringData1.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));
}


}

对我来说,最好的选择是本地查询:

@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>

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