1.简介
在本教程中,我们将学习如何使用JPA和Spring Data JPA 限制查询结果。
首先,我们将查看要查询的表以及要重现的SQL查询。
然后我们将直接探讨如何使用JPA和Spring Data JPA实现这一目标。
让我们开始吧!
2.测试数据
下面我们将在本文中查询表格。
我们想要回答的问题是,“首先占用的座位是什么,占用者是谁?”。
名字 | 姓 | 座位号 |
---|---|---|
吉尔 | 工匠 | 50 |
前夕 | 杰克逊 | 94 |
弗雷德 | 布罗格斯 | 22 |
瑞奇 | 博比 | 36 |
思雅 | Kolisi | 85 |
3. SQL
使用SQL,我们可能会编写一个类似于下面的查询:
SELECT firstName, lastName, seatNumber FROM passengers ORDER BY seatNumber LIMIT 1;
4. JPA设置
使用JPA,我们首先需要一个实体来映射我们的表:
@Entity
class Passenger {
@Id
@GeneratedValue
@Column(nullable = false)
private Long id;
@Basic(optional = false)
@Column(nullable = false)
private String fistName;
@Basic(optional = false)
@Column(nullable = false)
private String lastName;
@Basic(optional = false)
@Column(nullable = false)
private int seatNumber;
// constructor, getters etc.
}
接下来我们需要一个封装查询代码的方法,在此实现为PassengerRepositoryImpl#findOrderedBySeatNumberLimitedTo(int limit):
@Repository
class PassengerRepositoryImpl {
@PersistenceContext
private EntityManager entityManager;
@Override
public List<Passenger> findOrderedBySeatNumberLimitedTo(int limit) {
return entityManager.createQuery("SELECT p FROM Passenger p ORDER BY p.seatNumber",
Passenger.class).setMaxResults(limit).getResultList();
}
}
在我们的存储库方法中,我们使用EntityManager创建一个Query,我们在其上调用 setMaxResults()方法。
对Query#setMaxResults的这一调用最终将导致将limit语句附加到生成的SQL:
select
passenger0_.id as id1_15_,
passenger0_.fist_name as fist_nam2_15_,
passenger0_.last_name as last_nam3_15_,
passenger0_.seat_number as seat_num4_15_
from passenger passenger0_ order by passenger0_.seat_number limit ?
5.使用Spring Data JPA
我们也可以使用Spring Data JPA生成SQL。
5.1。first or top
我们可以采用的一种方法是使用方法名称派生,使用关键字first或top。
我们可以选择将数字指定为将返回的最大结果大小。如果我们省略它,Spring Data JPA假设结果大小为1。
记住我们想知道什么是第一个占用的座位以及谁占用它,我们可以通过以下两种方式省略它的数量:
Passenger findFirstByOrderBySeatNumberAsc();
Passenger findTopByOrderBySeatNumberAsc();
如果我们限制为一个实例结果,如上所述,那么我们也可以使用Optional包装结果:
Optional<Passenger> findFirstByOrderBySeatNumberAsc();
Optional<Passenger> findTopByOrderBySeatNumberAsc();
如果我们看一看的默认实现JpaRepository, 该 SimpleJpaRepository, 我们可以看到,它也要求查询#setMaxResults:
protected <S extends T > Page < S > readPage(TypedQuery < S > query,
Class < S > domainClass, Pageable pageable,
@Nullable Specification < S > spec) {
if (pageable.isPaged()) {
query.setFirstResult((int) pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
}
return PageableExecutionUtils.getPage(query.getResultList(), pageable, () -> {
return executeCountQuery(this.getCountQuery(spec, domainClass));
});
}
5.3。Comparison
这两种替代方案都将产生我们追求的SQL:
select
passenger0_.id as id1_15_,
passenger0_.fist_name as fist_nam2_15_,
passenger0_.last_name as last_nam3_15_,
passenger0_.seat_number as seat_num4_15_
from passenger passenger0_ order by passenger0_.seat_number asc limit ?
With first and top favoring convention and Pageable favoring configuration.