Spring Data JPA 获取最后一条记录
1、概览
本文将带你了解使用 Spring Data JPA 获取最后一条记录的多种方式。
2、初始设置
首先,创建并初始化要查询的表。
创建一个 Post 实体类:
@Entity
public class Post {
@Id
private Long id;
private String title;
private LocalDate publicationDate;
// get、set 方法
}
@Entity 表示注解的类代表数据库中的一个表。@Id 注解定义了主键。
为了简单起见,这里使用的是 H2 内存数据库。
添加一个基本的 SQL 脚本,创建 Post 类对应的 post 表:
DROP TABLE IF EXISTS post;
CREATE TABLE post(
id INT PRIMARY KEY,
title VARCHAR(200),
publication_date DATE
)
接着,添加一些数据:
INSERT INTO post (id, title, publication_date) VALUES(1, 'Facebook post', '2020-11-10');
INSERT INTO post (id, title, publication_date) VALUES(2, 'Instagram post', '2020-12-24');
INSERT INTO post (id, title, publication_date) VALUES(3, 'Twitter post', '2023-01-10');
INSERT INTO post (id, title, publication_date) VALUES(4, 'tiktok post', '2023-03-18');
INSERT INTO post (id, title, publication_date) VALUES(5, 'Pinterest post', '2023-09-09');
如你所见,最后一条记录的 ID 是 5。
3、使用查询方法
Spring Data JPA 支持派生查询方法,这个特性提供了一种方便的方式,可以根据方法名生成查询,而无需手动编写SQL语句。
Spring Data JPA 并不提供获取最后一条记录的直接方法,但它提供了从一组记录的起始位置检索数据的方法。
例如,可以使用 findFirst 前缀创建一个获取第一条记录的派生查询:
public interface PostRepository extends JpaRepository<Post, Integer> {
Post findFirstByOrderByPublicationDateDesc();
}
方法名 findFirstByOrderByPublicationDateDesc() 的每个部分都有其意义。动词 find 告诉 Spring Data JPA 生成一个 select 查询,而 First 表示应从结果集中检索第一条记录。
此外,OrderByPublicationDateDesc 表示希望按照 publicationDate 属性对记录进行倒序排序。
Spring Data JPA 会智能地解析方法名称。首先,它会按 publicationDate 降序排列 post。这样,就会把最后一条记录放在结果的开头。
然后,它将 findFirst 解释为返回排序记录的第一个元素。结果就是,我们得到了表中的最后一条记录。
测试:
@Test
void givenPosts_whenUsingFindFirstDerivedQuery_thenReturnLastPost() {
Post post = postRepository.findFirstByOrderByPublicationDateDesc();
assertNotNull(post);
assertEquals(5, post.getId());
}
上述测试会执行通过。
同样,也可以使用 findTop 关键字来实现相同的结果。可以交替使用 firstFirst 或 findTop,而不会出现任何问题:
Post findTopByOrderByPublicationDateDesc();
最后,为 findTopByOrderByPublicationDateDesc() 方法创建另一个测试用例:
@Test
void givenPosts_whenUsingFindTopDerivedQuery_thenReturnLastPost() {
Post post = postRepository.findTopByOrderByPublicationDateDesc();
assertNotNull(post);
assertEquals(5, post.getId());
}
如上,测试用例成功通过。
4、使用 @Query 注解
另一种解决方案是使用 @Query 注解将方法绑定到可检索最后一条记录的查询中。默认情况下,@Query 接受 JPQL 查询。
在 PostRepository 中添加另一个名为 findLastPost() 的方法,并使用 @Query 来指定获取最后一条记录的查询:
@Query("SELECT p FROM Post p ORDER BY p.publicationDate DESC LIMIT 1")
Post findLastPost();
简而言之,这里按照 publicationDate 倒序 select 了 post 记录,然后,使用 LIMIT 1 只检索一个 post。返回的 post 表示最后一条记录。
同样,添加一个测试用例来测试这个方法:
@Test
void givenPosts_whenUsingQueryAnnotation_thenReturnLastPost() {
Post post = postRepository.findLastPost();
assertNotNull(post);
assertEquals(5, post.getId());
}
不出所料,最后一条记录的 ID 为 5。
5、总结
本文介绍了如何在 Spring Data JPA 中通过派生方法或者自定义 @Query 来实现检索数据表中的最后一条记录。
Ref:https://www.baeldung.com/spring-data-jpa-last-record