1、概览 {#1概览}
本文将带你了解使用 Spring Data JPA 获取最后一条记录的多种方式。
2、初始设置 {#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、使用查询方法 {#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
注解 {#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、总结 {#5总结}
本文介绍了如何在 Spring Data JPA 中通过派生方法或者自定义 @Query
来实现检索数据表中的最后一条记录。
Ref:https://www.baeldung.com/spring-data-jpa-last-record