在我们平时的工作中,查询列表在我们的系统中基本随处可见,那么我们如何使用jpa进行多条件查询以及查询列表分页呢?下面我将介绍两种多条件查询方式。

1、引入起步依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
2、对thymeleaf和jpa进行配置
打开application.yml,添加以下参数,以下配置在之前的文章中介绍过,此处不做过多说明
spring: thymeleaf: cache: true check-template-location: true content-type: text/html enabled: true encoding: utf-8 mode: HTML5 prefix: classpath:/templates/ suffix: .html excluded-view-names: template-resolver-order: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/restful?useUnicode=true&characterEncoding=UTF-8&useSSL=false username: root password: root initialize: true init-db: true jpa: database: mysql show-sql: true hibernate: ddl-auto: update naming: strategy: org.hibernate.cfg.ImprovedNamingStrategy
3、编写实体Bean
@Entity
@Table(name="book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", updatable = false)
private Long id;
@Column(nullable = false,name = "name")
private String name;
@Column(nullable = false,name = "isbn")
private String isbn;
@Column(nullable = false,name = "author")
private String author;
public Book (String name,String isbn,String author){
this.name = name;
this.isbn = isbn;
this.author = author;
}
public Book(){
}
//此处省去get、set方法
}
public class BookQuery {
private String name;
private String isbn;
private String author;
//此处省去get、set方法
}
4、编写Repository接口
@Repository("bookRepository")
public interface BookRepository extends JpaRepository<Book,Long>
,JpaSpecificationExecutor<Book> {
}
此处继承了两个接口,后续会介绍为何会继承这两个接口
5、抽象service层
首先抽象出接口
public interface BookQueryService {
Page<Book> findBookNoCriteria(Integer page,Integer size);
Page<Book> findBookCriteria(Integer page,Integer size,BookQuery bookQuery);
}
实现接口
@Service(value="https://my.oschina.net/wangxincj/blog/bookQueryService")
public class BookQueryServiceImpl implements BookQueryService {
@Resource
BookRepository bookRepository;
@Override
public Page<Book> findBookNoCriteria(Integer page,Integer size) {
Pageable pageable = new PageRequest(page, size, Sort.Direction.ASC, "id");
return bookRepository.findAll(pageable);
}
@Override
public Page<Book> findBookCriteria(Integer page, Integer size, final BookQuery bookQuery) {
Pageable pageable = new PageRequest(page, size, Sort.Direction.ASC, "id");
Page<Book> bookPage = bookRepository.findAll(new Specification<Book>(){
@Override
public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> list = new ArrayList<Predicate>();
if(null!=bookQuery.getName()&&!"".equals(bookQuery.getName())){
list.add(criteriaBuilder.equal(root.get("name").as(String.class), bookQuery.getName()));
}
if(null!=bookQuery.getIsbn()&&!"".equals(bookQuery.getIsbn())){
list.add(criteriaBuilder.equal(root.get("isbn").as(String.class), bookQuery.getIsbn()));
}
if(null!=bookQuery.getAuthor()&&!"".equals(bookQuery.getAuthor())){
list.add(criteriaBuilder.equal(root.get("author").as(String.class), bookQuery.getAuthor()));
}
Predicate[] p = new Predicate[list.size()];
return criteriaBuilder.and(list.toArray(p));
}
},pageable);
return bookPage;
}
}
此处我定义了两个接口,findBookNoCriteria是不带查询条件的,findBookCriteria是带查询条件的。在此处介绍一下上面提到的自定义Repository继承的两个接口,如果你的查询列表是没有查询条件,只是列表展示和分页,只需继承JpaRepository接口即可,但是如果你的查询列表是带有多个查询条件的话则需要继承JpaSpecificationExecutor接口,这个接口里面定义的多条件查询的方法。当然不管继承哪个接口,当你做分页查询时,都是需要调用findAll方法的,这个方法是jap定义好的分页查询方法。
findBookCriteria方法也可以使用以下方法实现,大家可以自行选择
@Override
public Page<Book> findBookCriteria(Integer page, Integer size, final BookQuery bookQuery) {
Pageable pageable = new PageRequest(page, size, Sort.Direction.ASC, "id");
Page<Book> bookPage = bookRepository.findAll(new Specification<Book>(){
@Override
public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
Predicate p1 = criteriaBuilder.equal(root.get("name").as(String.class), bookQuery.getName());
Predicate p2 = criteriaBuilder.equal(root.get("isbn").as(String.class), bookQuery.getIsbn());
Predicate p3 = criteriaBuilder.equal(root.get("author").as(String.class), bookQuery.getAuthor());
query.where(criteriaBuilder.and(p1,p2,p3));
return query.getRestriction();
}
},pageable);
return bookPage;
}
6、编写Controller
针对有查询条件和无查询条件,我们分别编写一个Controller,默认每页显示5条,如下
@Controller
@RequestMapping(value = "https://my.oschina.net/queryBook")
public class BookController {
@Autowired
BookQueryService bookQueryService;
@RequestMapping("/findBookNoQuery")
public String findBookNoQuery(ModelMap modelMap,@RequestParam(value = "https://my.oschina.net/wangxincj/blog/page", defaultValue = "https://my.oschina.net/wangxincj/blog/0") Integer page,
@RequestParam(value = "https://my.oschina.net/wangxincj/blog/size", defaultValue = "https://my.oschina.net/wangxincj/blog/5") Integer size){
Page<Book> datas = bookQueryService.findBookNoCriteria(page, size);
modelMap.addAttribute("datas", datas);
return "index1";
}
@RequestMapping(value = "https://my.oschina.net/findBookQuery",method = {RequestMethod.GET,RequestMethod.POST})
public String findBookQuery(ModelMap modelMap, @RequestParam(value = "https://my.oschina.net/wangxincj/blog/page", defaultValue = "https://my.oschina.net/wangxincj/blog/0") Integer page,
@RequestParam(value = "https://my.oschina.net/wangxincj/blog/size", defaultValue = "https://my.oschina.net/wangxincj/blog/5") Integer size, BookQuery bookQuery){
Page<Book> datas = bookQueryService.findBookCriteria(page, size,bookQuery);
modelMap.addAttribute("datas", datas);
return "index2";
}
}
7、编写页面
首先我们编写一个通用的分页页面,新建一个叫page.html的页面
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="page">
<body>
<div th:fragment="pager">
<div class="text-right" th:with="baseUrl=${#httpServletRequest.getRequestURL().toString()},pars=${#httpServletRequest.getQueryString() eq null ? '' : new String(#httpServletRequest.getQueryString().getBytes('iso8859-1'), 'UTF-8')}">
<ul style="margin:0px;" class="pagination" th:with="newPar=${new Java.lang.String(pars eq null ? '' : pars).replace('page='+(datas.number), '')},
curTmpUrl=${baseUrl+'?'+newPar},
curUrl=${curTmpUrl.endsWith('&') ? curTmpUrl.substring(0, curTmpUrl.length()-1):curTmpUrl}" >
<!--<li th:text="${pars}"></li>-->
<li><a href="https://my.oschina.net/wangxincj/blog/#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:href="https://my.oschina.net/wangxincj/blog/@{${curUrl}(page=0)}" rel="external nofollow" >首页</a></li>
<li th:if="${datas.hasPrevious()}"><a href="https://my.oschina.net/wangxincj/blog/#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:href="https://my.oschina.net/wangxincj/blog/@{${curUrl}(page=${datas.number-1})}" rel="external nofollow" >上一页</a></li>
<!--总页数小于等于10-->
<div th:if="${(datas.totalPages le 10) and (datas.totalPages gt 0)}" th:remove="tag">
<div th:each="pg : ${#numbers.sequence(0, datas.totalPages - 1)}" th:remove="tag">
<span th:if="${pg eq datas.getNumber()}" th:remove="tag">
<li class="active"><span class="current_page line_height" th:text="${pg+1}">${pageNumber}</span></li>
</span>
<span th:unless="${pg eq datas.getNumber()}" th:remove="tag">
<li><a href="https://my.oschina.net/wangxincj/blog/#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:href="https://my.oschina.net/wangxincj/blog/@{${curUrl}(page=${pg})}" rel="external nofollow" th:text="${pg+1}"></a></li>
</span>
</div>
</div>
<!-- 总数数大于10时 -->
<div th:if="${datas.totalPages gt 10}" th:remove="tag">
<li th:if="${datas.number-2 ge 0}"><a href="https://my.oschina.net/wangxincj/blog/#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:href="https://my.oschina.net/wangxincj/blog/@{${curUrl}(page=${datas.number}-2)}" rel="external nofollow" th:text="${datas.number-1}"></a></li>
<li th:if="${datas.number-1 ge 0}"><a href="https://my.oschina.net/wangxincj/blog/#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:href="https://my.oschina.net/wangxincj/blog/@{${curUrl}(page=${datas.number}-1)}" rel="external nofollow" th:text="${datas.number}"></a></li>
<li class="active"><span class="current_page line_height" th:text="${datas.number+1}"></span></li>
<li th:if="${datas.number+1 lt datas.totalPages}"><a href="https://my.oschina.net/wangxincj/blog/#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:href="https://my.oschina.net/wangxincj/blog/@{${curUrl}(page=${datas.number}+1)}" rel="external nofollow" th:text="${datas.number+2}"></a></li>
<li th:if="${datas.number+2 lt datas.totalPages}"><a href="https://my.oschina.net/wangxincj/blog/#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:href="https://my.oschina.net/wangxincj/blog/@{${curUrl}(page=${datas.number}+2)}" rel="external nofollow" th:text="${datas.number+3}"></a></li>
</div>
<li th:if="${datas.hasNext()}"><a href="https://my.oschina.net/wangxincj/blog/#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:href="https://my.oschina.net/wangxincj/blog/@{${curUrl}(page=${datas.number+1})}" rel="external nofollow" >下一页</a></li>
<!--<li><a href="https://my.oschina.net/wangxincj/blog/#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:href="https://my.oschina.net/wangxincj/blog/@{${curUrl}(page=${datas.totalPages-1})}" rel="external nofollow" >尾页</a></li>-->
<li><a href="https://my.oschina.net/wangxincj/blog/#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:href="https://my.oschina.net/wangxincj/blog/${datas.totalPages le 0 ? curUrl+'page=0':curUrl+'&page='+(datas.totalPages-1)}" rel="external nofollow" >尾页</a></li>
<li><span th:utext="'共'+${datas.totalPages}+'页 / '+${datas.totalElements}+' 条'"></span></li>
</ul>
</div>
</div>
</body>
</html>
针对无查询条件的接口,创建一个名为index1.html的页面并引入之前写好的分页页面,如下
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
<script type="text/javascript" th:src="https://my.oschina.net/wangxincj/blog/@{/jquery-1.12.3.min.js}"></script>
<script type="text/javascript" th:src="https://my.oschina.net/wangxincj/blog/@{/bootstrap/js/bootstrap.min.js}"></script>
<link type="text/css" rel="stylesheet" th:href="https://my.oschina.net/wangxincj/blog/@{/bootstrap/css/bootstrap-theme.min.css}" rel="external nofollow" rel="external nofollow" />
<link type="text/css" rel="stylesheet" th:href="https://my.oschina.net/wangxincj/blog/@{/bootstrap/css/bootstrap.css}" rel="external nofollow" rel="external nofollow" />
</head>
<body>
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>name</th>
<th>isbn</th>
<th>author</th>
</tr>
</thead>
<tbody>
<tr th:each="obj : ${datas}">
<td th:text="${obj.id}">${obj.id}</td>
<td th:text="${obj.name}">${obj.name}</td>
<td th:text="${obj.isbn}">${obj.isbn}</td>
<td th:text="${obj.name}">${obj.author}</td>
</tr>
</tbody>
</table>
<div th:include="page :: pager" th:remove="tag"></div>
</body>
</html>
针对有查询条件的接口,创建一个名为index2.html的页面并引入之前写好的分页页面,如下
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
<script type="text/javascript" th:src="https://my.oschina.net/wangxincj/blog/@{/jquery-1.12.3.min.js}"></script>
<script type="text/javascript" th:src="https://my.oschina.net/wangxincj/blog/@{/bootstrap/js/bootstrap.min.js}"></script>
<link type="text/css" rel="stylesheet" th:href="https://my.oschina.net/wangxincj/blog/@{/bootstrap/css/bootstrap-theme.min.css}" rel="external nofollow" rel="external nofollow" />
<link type="text/css" rel="stylesheet" th:href="https://my.oschina.net/wangxincj/blog/@{/bootstrap/css/bootstrap.css}" rel="external nofollow" rel="external nofollow" />
</head>
<body>
<form th:action="@{/queryBook/findBookQuery}" th:object="${bookQuery}" th:method="get">
<div class="form-group">
<label class="col-sm-2 control-label" >name</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="name" placeholder="请输入名称" th:field="*{name}"/>
</div>
<label class="col-sm-2 control-label">isbn</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="isbn" placeholder="请输ISBN" th:field="*{isbn}"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" >author</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="author" placeholder="请输author" th:field="*{author}"/>
</div>
<div class="col-sm-4">
<button class="btn btn-default" type="submit" placeholder="查询">查询</button>
</div>
</div>
</form>
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>name</th>
<th>isbn</th>
<th>author</th>
</tr>
</thead>
<tbody>
<tr th:each="obj : ${datas}">
<td th:text="${obj.id}">${obj.id}</td>
<td th:text="${obj.name}">${obj.name}</td>
<td th:text="${obj.isbn}">${obj.isbn}</td>
<td th:text="${obj.name}">${obj.author}</td>
</tr>
</tbody>
</table>
<div th:include="page :: pager" th:remove="tag"></div>
</body>
</html>
ok!代码都已经完成,我们将项目启动起来,看一下效果。大家可以往数据库中批量插入一些数据,访问
http://localhost:8080/queryBook/findBookNoQuery,显示如下页面
访问http://localhost:8080/queryBook/findBookQuery,显示页面如下,可以输入查询条件进行带条件的分页查询:
总结
以上所述是小编给大家介绍的在Spring Boot中使用Spring-data-jpa实现分页查询,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
# spring
# boot
# data
# jpa
# 分页
# SpringBoot+MySQL+Jpa实现对数据库的增删改查和分页详解
# SpringBoot Jpa分页查询配置方式解析
# IDEA+maven+SpringBoot+JPA+Thymeleaf实现Crud及分页
# SpringBoot JPA实现增删改查、分页、排序、事务操作等功能示例
# SpringBoot整合JPA数据源方法及配置解析
# SpringBoot2.3.0配置JPA的实现示例
# SpringBoot整合spring-data-jpa的方法
# Spring Boot2.x集成JPA快速开发的示例代码
# Spring boot JPA实现分页和枚举转换代码示例
# 多条
# 尾页
# 创建一个
# 小编
# 写好
# 都是
# 多个
# 下一页
# 在此
# 上一页
# 两种
# 只需
# 每页
# 这两个
# 给大家
# 请输入
# 数数
# 自定义
# 我将
相关文章:
如何在阿里云ECS服务器部署织梦CMS网站?
西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?
我的世界制作壁纸网站下载,手机怎么换我的世界壁纸?
如何在云主机快速搭建网站站点?
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
如何在Golang中使用encoding/gob序列化对象_存储和传输数据
建站之星如何快速解决建站难题?
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
建站主机如何选?性能与价格怎样平衡?
如何安全更换建站之星模板并保留数据?
Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解
教学网站制作软件,学习*后期制作的网站有哪些?
如何在服务器上配置二级域名建站?
大连网站制作公司哪家好一点,大连买房网站哪个好?
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
网站网页制作电话怎么打,怎样安装和使用钉钉软件免费打电话?
音响网站制作视频教程,隆霸音响官方网站?
测试制作网站有哪些,测试性取向的权威测试或者网站?
如何优化Golang Web性能_Golang HTTP服务器性能提升方法
网站制作服务平台,有什么网站可以发布本地服务信息?
如何在Ubuntu系统下快速搭建WordPress个人网站?
相亲简历制作网站推荐大全,新相亲大会主持人小萍萍资料?
建站VPS能否同时实现高效与安全翻墙?
如何快速查询网址的建站时间与历史轨迹?
建站主机SSH密钥生成步骤及常见问题解答?
建站之星代理如何获取技术支持?
如何选择香港主机高效搭建外贸独立站?
如何选择高效可靠的多用户建站源码资源?
Android自定义listview布局实现上拉加载下拉刷新功能
如何续费美橙建站之星域名及服务?
香港网站服务器数量如何影响SEO优化效果?
家庭建站与云服务器建站,如何选择更优?
建站之星展会模板:智能建站与自助搭建高效解决方案
建站之星如何通过成品分离优化网站效率?
建站之星免费版是否永久可用?
上海网站制作开发公司,上海买房比较好的网站有哪些?
如何在宝塔面板中修改默认建站目录?
北京网站制作的公司有哪些,北京白云观官方网站?
如何用花生壳三步快速搭建专属网站?
如何解决VPS建站LNMP环境配置常见问题?
如何通过WDCP绑定主域名及创建子域名站点?
建站之星后台管理系统如何操作?
如何在万网自助建站中设置域名及备案?
高性能网站服务器配置指南:安全稳定与高效建站核心方案
较简单的网站制作软件有哪些,手机版网页制作用什么软件?
如何在宝塔面板创建新站点?
建站之星如何修改网站生成路径?
小程序网站制作需要准备什么资料,如何制作小程序?
如何解决ASP生成WAP建站中文乱码问题?
建站OpenVZ教程与优化策略:配置指南与性能提升
*请认真填写需求信息,我们会在24小时内与您取得联系。