1. 概述
在这个简短的教程中,我们将探讨在Spring Data JPA中获取最后一条记录的不同方法。首先,我们将了解如何使用衍生查询方法。然后,我们将研究如何使用@Query
注解实现相同的功能。
2. 准备工作
首先,让我们创建并初始化我们想要查询的表。 我们从创建一个Post
实体类开始:
@Entity
public class Post {
@Id
private Long id;
private String title;
private LocalDate publicationDate;
// standard getters and setters
}
@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的那一条。因此,为了达到获取表中最后一条记录的目标,我们将根据publication_date
倒序排列记录。然后,我们将使用Spring Data JPA的方法从排序结果中获取第一条记录。这样,我们就能得到表的最后一条记录。
3. 使用衍生查询方法
Spring Data JPA因其衍生查询方法而受到赞誉。这个特性提供了一种方便的方式,无需手动编写SQL语句,即可从方法名称生成查询。
Spring Data JPA并没有直接提供获取最后一条记录的方法。然而,它提供了简单的方法来从一组记录的开头检索数据。
例如,我们可以使用findFirst
前缀创建一个衍生查询,该查询从结果集中获取第一条记录。让我们看看它是如何工作的:
public interface PostRepository extends JpaRepository<Post, Integer> {
Post findFirstByOrderByPublicationDateDesc();
}
方法名称findFirstByOrderByPublicationDateDesc()
的每一部分都有其含义。动词“find”告诉Spring Data JPA生成一个选择查询,而“First”表示从结果集中获取第一条记录。
此外,“OrderByPublicationDateDesc”表示我们希望按publicationDate
属性的降序对记录进行排序。
Spring Data JPA智能地解释方法名称。它首先按照发布日期的降序对帖子进行排序。这样,它将最后一条记录放在结果的开头。
然后,它解释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();
简单来说,我们选择了按发布日期降序排序的帖子,然后使用LIMIT 1
只获取一条帖子。返回的帖子代表了最后一条记录。
一如既往,我们添加一个测试用例来测试新方法:
@Test
void givenPosts_whenUsingQueryAnnotation_thenReturnLastPost() {
Post post = postRepository.findLastPost();
assertNotNull(post);
assertEquals(5, post.getId());
}
不出所料,最后一条记录是id为5的帖子。
5. 总结
在这篇教程中,我们探讨了使用Spring Data JPA从特定表中获取最后一条记录的不同方法。首先,我们了解了如何使用衍生查询方法。然后,我们在@Query
注解中编写了一个JPQL查询,获得了相同的结果。
完整的代码示例可以在GitHub上找到。