Spring Data JPA实现排序与分页查询超详细流程讲解
作者:showswoller
在介绍Spring Data JPA的时候,我们首先认识下Hibernate。Hibernate是数据访问解决技术的绝对霸主,使用O/R映射技术实现数据访问,O/R映射即将领域模型类和数据库的表进行映射,通过程序操作对象而实现表数据操作的能力,让数据访问操作无须关注数据库相关的技术
前言
在实际开发场景中,排序与分页查询是必须的,幸运的是Spring Data JPA充分考虑了排序与分页查询的场景,为我们提供Sort类 Page接口 Pageable接口 下面通过一个实战来阐明
1、创建持久化实体类
创建名为com.ch.ch6_4.entity的包 并在该包中创建名为Article和Author的持久化实体类
代码如下
Article
package com.ch.ch6_2.entity; import java.io.Serializable; import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.Lob; import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Size; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @Entity @Table(name = "article_table") @JsonIgnoreProperties(value = { "hibernateLazyInitializer"}) public class Article implements Serializable{ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; //标题 @NotEmpty(message = "标题不能为空") @Size(min = 2, max = 50) @Column(nullable = false, length = 50) private String title; //文章内容 @Lob //大对象,映射 为MySQL的Long文本类型 @Basic(fetch = FetchType.LAZY) @NotEmpty(message = "内容不能为空") @Size(min = 2) @Column(nullable = false) private String content; //所属作者,文章与作者是多对一的关系 @ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false) //可选属性optional=false,表示author不能为空。删除文章,不影响用户 @JoinColumn(name="id_author_id")//设置在article表中的关联字段(外键) @JsonIgnore private Author author; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Author getAuthor() { return author; } public void setAuthor(Author author) { this.author = author; } }
Author
package com.ch.ch6_2.entity; import java.io.Serializable; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @Entity @Table(name = "author_table") @JsonIgnoreProperties(value = { "hibernateLazyInitializer"}) public class Author implements Serializable{ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; //作者名 private String aname; //文章列表,作者与文章是一对多的关系 @OneToMany( mappedBy = "author", cascade=CascadeType.ALL, targetEntity = Article.class, fetch=FetchType.LAZY ) private List<Article> articleList; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAname() { return aname; } public void setAname(String aname) { this.aname = aname; } public List<Article> getArticleList() { return articleList; } public void setArticleList(List<Article> articleList) { this.articleList = articleList; } }
2、创建数据访问层
创建名为com.ch.ch6_4repository的包 并在该包中创建名为AuthorRepository的接口
package com.ch.ch6_2.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import com.ch.ch6_2.entity.Author; public interface AuthorRepository extends JpaRepository<Author, Integer>{ /** * 根据文章标题包含的内容,查询作者(关联查询) * 相当于JPQL语句:select a from Author a inner join a.articleList t where t.title like %?1% */ public Author findByArticleList_titleContaining(String title); /** * 根据文章标题包含的内容,查询作者(关联查询) */ @Query("select a from Author a inner join a.articleList t where t.title like %?1%" ) public Author findAuthorByArticleListtitleContaining(String title); }
3、创建业务层
创建名为com.ch.ch6_4.service的包 并在该包中创建名为ArticleAndAuthorService的接口和接口实现类ArticleAndAuthorServiceImpl
接口
package com.ch.ch6_2.service; import java.util.List; import com.ch.ch6_2.entity.Article; import com.ch.ch6_2.entity.Author; public interface AuthorAndArticleService { public void saveAll(); public List<Article> findByAuthor_id(Integer id); public List<Article> findByAuthor_aname(String aname); public Author findByArticleList_titleContaining(String title); public Author findAuthorByArticleListtitleContaining(String title); }
接口实现类
package com.ch.ch6_2.service; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.ch.ch6_2.entity.Article; import com.ch.ch6_2.entity.Author; import com.ch.ch6_2.repository.ArticleRepository; import com.ch.ch6_2.repository.AuthorRepository; @Service public class AuthorAndArticleServiceImpl implements AuthorAndArticleService{ @Autowired private AuthorRepository authorRepository; @Autowired private ArticleRepository articleRepository; @Override public void saveAll() { //保存作者(先保存一的一端) Author a1 = new Author(); a1.setAname("陈恒1"); Author a2 = new Author(); a2.setAname("陈恒2"); ArrayList<Author> allAuthor = new ArrayList<Author>(); allAuthor.add(a1); allAuthor.add(a2); authorRepository.saveAll(allAuthor); //保存文章 Article at1 = new Article(); at1.setTitle("JPA的一对多111"); at1.setContent("其实一对多映射关系很常见111。"); //设置关系 at1.setAuthor(a1); Article at2 = new Article(); at2.setTitle("JPA的一对多222"); at2.setContent("其实一对多映射关系很常见222。"); //设置关系 at2.setAuthor(a1);//文章2与文章1作者相同 Article at3 = new Article(); at3.setTitle("JPA的一对多333"); at3.setContent("其实一对多映射关系很常见333。"); //设置关系 at3.setAuthor(a2); Article at4 = new Article(); at4.setTitle("JPA的一对多444"); at4.setContent("其实一对多映射关系很常见444。"); //设置关系 at4.setAuthor(a2);//文章3与文章4作者相同 ArrayList<Article> allAt = new ArrayList<Article>(); allAt.add(at1); allAt.add(at2); allAt.add(at3); allAt.add(at4); public Author findByArticleList_titleContaining(String title) { return authorRepository.findByArticleList_titleContaining(title); } @Override public Author findAuthorByArticleListtitleContaining(String title) { return authorRepository.findAuthorByArticleListtitleContaining(title); } }
4、创建控制器类
创建名为com.ch,ch6_4.controller的包 并在该包中创建名为TestSortAndPage的控制器类
package com.ch.ch6_4.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.ch.ch6_4.entity.Author; import com.ch.ch6_4.service.ArticleAndAuthorService; @Controller public class TestSortAndPage { @Autowired private ArticleAndAuthorService articleAndAuthorService; @RequestMapping("/findByAnameContaining") @ResponseBody public List<Author> findByAnameContaining(String aname, String sortColum){ return articleAndAuthorService.findByAnameContaining(aname, sortColum); } @RequestMapping("/findAllAuthorByPage") /** * @param page第几页 */ public String findAllAuthorByPage(Integer page, Model model){ return articleAndAuthorService.findAllAuthorByPage(page, model); } }
5、创建View视图页面
创建index.html页面 部分代码如下
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>显示分页查询结果</title> <link rel="stylesheet" th:href="@{css/bootstrap.min.css}" rel="external nofollow" /> <link rel="stylesheet" th:href="@{css/bootstrap-theme.min.css}" rel="external nofollow" /> </head> <body> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">Spring Data JPA分页查询</h3> </div> </tr> <tr> <td colspan="2" align="right"> <ul class="pagination"> <li><a>第<span th:text="${page}"></span>页</a></li> <li><a>共<span th:text="${totalPage}"></span>页</a></li> <li><a>共<span th:text="${totalCount}"></span>条</a></li> <li> <a th:href="@{findAllAuthorByPage(page=${page-1})}" rel="external nofollow" th:if="${page != 1}">上一页</a> </li> <li><a th:href="@{findAllAuthorByPage(page=${page+1})}" rel="external nofollow" th:if="${page != totalPage}">下一页</a> </li> </ul> </td> </tr> </tbody> </table> </div> </div> </div> </div> </body> </html>
6、运行主类 效果如下
到此这篇关于Spring Data JPA实现排序与分页查询超详细流程讲解的文章就介绍到这了,更多相关Spring Data JPA排序与分页查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!