前言
在实际开发场景中,排序与分页查询是必须的,幸运的是Spring Data JPA充分考虑了排序与分页查询的场景,为我们提供Sort类 Page接口 Pageable接口 下面通过一个实战来阐明
1、创建持久化实体类
创建名为com.ch.ch6_4.entity的包 并在该包中创建名为Article和Author的持久化实体类
代码如下
Article
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 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; } }</article></article></article> |
2、创建数据访问层
创建名为com.ch.ch6_4repository的包 并在该包中创建名为AuthorRepository的接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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{ /** * 根据文章标题包含的内容,查询作者(关联查询) * 相当于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
接口
1 2 3 4 5 6 7 8 9 10 11 | 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); }</article></article> |
接口实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 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 allAuthor = new ArrayList(); 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); } }</article></article> |
4、创建控制器类
创建名为com.ch,ch6_4.controller的包 并在该包中创建名为TestSortAndPage的控制器类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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 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页面 部分代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | < title >显示分页查询结果</ title >< div class = "panel panel-primary" > < div class = "panel-heading" > < h3 class = "panel-title" >Spring Data JPA分页查询</ h3 > </ div > < ul class = "pagination" > < li >< a >第< span ></ span >页</ a ></ li > < li >< a >共< span ></ span >页</ a ></ li > < li >< a >共< span ></ span >条</ a ></ li > < li > < a rel = "external nofollow" >上一页</ a > </ li > < li > < a rel = "external nofollow" >下一页</ a > </ li > </ ul > </ div > |