SpringDataJpa的使用 – 条件查询、排序查询、分页查询
本文以 Article.java 为数据存放类,操作接口为 ArticleRepository.java
@Data
lombok 的注解,用来生成 Getter、Setter、toString、hashCode 方法,当添加该注解的同时在添加 相应方法(如 toString())时,添加的方法不会被覆盖。
@NoArgsConstructor
lombok 的注解,用来生成 无参构造函数。
@AllArgsConstructor
lombok 的注解,用来生成 全参构造函数。
@JsonIgnore
用来破坏实体类序列化时,产生的无限递归循环。
在本次的测试中,还需要 重写 Author.java 的 toString 方法,目的是这两个类中必须有一方的 toString 方法没有外键属性,可以双方都没有。
Author.java
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "AUTHOR")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "author_id", nullable = false)
private Long authorId;
@Column(name = "author_Name", nullable = false)
private String authorName;
@Column(name = "author_referral", nullable = false)
private String authorReferral;
@JsonIgnore
@OneToMany(mappedBy = "author", fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.REMOVE})
private List<Article> articleList;
@Override
public String toString() {
return "Author{" +
"authorId=" + authorId +
", authorName='" + authorName + '\'' +
", authorReferral='" + authorReferral + '\'' +
'}';
}
}
Article.java
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "ARTICLE")
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "article_id", nullable = false)
private Long articleId;
@Column(name = "article_title", nullable = false)
private String articleTitle;
@Column(name = "article_content", nullable = false)
private String articleContent;
@Column(name = "article_type", nullable = false)
private String articleType;
@Column(name = "article_read_number", nullable = false)
private Integer articleReadNumber;
@Column(name = "article_likes_number", nullable = false)
private Integer articleLikesNumber;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "article_author_id", nullable = false)
private Author author;
}
ArticleRepository.java 这只是最基础的内容,会后续添加 接口或方法 来增加功能。
public interface ArticleRepository extends JpaRepository<Article, Long> {
}
排序查询
法 一
使用 JpaRepository 的 List findAll(Sort sort)
方法,无需添加新的 方法或接口。
-
Sort.by(String) 方法的参数是 字符串数组,可以添加一到多个类属性名来排序。
-
ascending 方法表示升序排序(默认就是),写法:Sort.by(String).ascending()。
-
descending 方法表示降序排序,写法:Sort.by(String).descending()。
-
根据多个类属性来排序时,是在不破坏前一个的排序结果的基础上对后一个进行排序,以此类推。
@Test
public void test1(){
List<Article> articleList=articleRepository.findAll(Sort.by("articleType").ascending());
System.out.println("====== 升序(类型) ======");
articleList.stream().map(Objects::toString).forEach(System.out::println);
List<Article> articleList1=articleRepository.findAll(Sort.by("articleType","articleReadNumber").ascending());
System.out.println("====== 升序(类型)(阅读量) ======");
articleList1.stream().map(Objects::toString).forEach(System.out::println);
}
- 如果 输入的类属性不存在就会报错,故需要:
检验输入的类属性是否存在
@Test
public void test2(){
List<Article> articleList=articleRepository.findAll(Sort.by("articleType1").ascending());
System.out.println("====== 升序(类型) ======");
articleList.stream().map(Objects::toString).forEach(System.out::println);
}
org.springframework.data.mapping.PropertyReferenceException: No property 'articleType1' found for type 'Article'! Did you mean ''articleType''?
- 能不能设置按第一个属性升序,再按第二个属性降序呢?答案是:
当然
。
by() 是静态方法,不支持变量调用,每一个 by() 后只能添加一个 排序方法。 但是,Sort 有一个 and(Sort) 方法,用来将两个 Sort 合并,该方法由变量调用,理论上可以无限叠加。
@Test
public void test3(){
List<Article> articleList=articleRepository.findAll(Sort.by("articleType","articleReadNumber").ascending());
System.out.println("====== 升序(类型)(阅读量) ======");
articleList.stream().map(Objects::toString).forEach(System.out::println);
Sort sort=Sort.by("articleType").ascending();
sort=sort.and(Sort.by("articleReadNumber").descending());
List<Article> articleList1=articleRepository.findAll(sort);
System.out.println("====== 类型升序、再阅读量降序 ======");
articleList1.stream().map(Objects::toString).forEach(System.out::println);
}
分页查询
法 一
使用 PagingAndSortingRepository 的 Page findAll(Pageable pageable)
方法,JpaRepository 继承了
PagingAndSortingRepository 接口,无需添加新的 方法或接口。
-
Page 几个常用的属性:
- content 数组 ,存放 List