Spring提供的JPA的分页的功能,和动态搜索后进行显示的分页功能的设置

Posted SmallCuteMonkey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring提供的JPA的分页的功能,和动态搜索后进行显示的分页功能的设置相关的知识,希望对你有一定的参考价值。

  1. 在Dao层 中进行实现 JpaRepository<Blog,Long>,进行数据库操作的接口,JpaSpecificationExecutor 进行动态查询的接口
package com.sophomoreblog.blog.dao;

import com.sophomoreblog.blog.po.Blog;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
//JpaSpecificationExecutor 是jpa提供的一个动态查询的接口,我们可以直接拿来使用
public interface BlogRepository extends JpaRepository<Blog,Long>,
        JpaSpecificationExecutor<Blog> {

}

pojo层的查询的实体类的重新的的编写:

package com.sophomoreblog.blog.qu;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//封装的查询的对象
@NoArgsConstructor
@AllArgsConstructor
@Data
public class BlogQuery {
    private String title;
    private Long typeId;
    private boolean recommend;
}

  1. Service层中进行相关的实现:
    BlogService:
public interface BlogService {
	 Page<Blog> listBlog(Pageable pageable, BlogQuery blog);

}
public class BlogServiceimpl  implements BlogService {
    @Autowired
    private BlogRepository blogRepository;

  @Override
    public Page<Blog> listBlog(Pageable pageable, BlogQuery blog) {
         return  blogRepository.findAll(new Specification<Blog>() {
//             root 里面可以进行条件<属性名>的获取
//             criteQuery是查询的容器
//             CriteriaBuilder 可以设置查询的条件
             @Override
             public Predicate toPredicate(Root<Blog> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
//                用list进行条件的封装
                 List<Predicate> predicateList=new ArrayList<>();
                 if(!" ".equals(blog.getTitle()) &&blog.getTitle()!=null){

                     predicateList.add(cb.like(root.<String>get("title"),"%"+blog.getTitle()+"%"));
                 }
//                 构造分类的查询的条件
                 if(blog.getTypeId()!=null){
                     predicateList.add(cb.equal(root.<Type>get("type"),blog.getTypeId()));
                 }
//                是否推荐
                 if(blog.isRecommend()){
                     predicateList.add(cb.equal(root.<Boolean>get("recommend"),blog.isRecommend()));
                 }
//               进行相关的查询
                 cq.where(predicateList.toArray(new Predicate[predicateList.size()]));

                 return null;
             }
         },pageable);
    }


}
  1. 然后可以在从controller层中进行相关的参数的配置
//    通过Ajax请求进行返回一个页面的局部的片段
    @PostMapping("/blogs/search")
//    把查询到的值进行Jpa的分页的设置
//    BlogQuery 把需要查询的对象封装成了一个Entity
    public String blogsSearch(@PageableDefault(size = 5,sort = {"updateTime"},
            direction = Sort.Direction.DESC)
                              Pageable pageable, BlogQuery blog, Model model){

        model.addAttribute("page",blogService.listBlog(pageable,blog));
//       返回 admin/blogs.html 表格进行请求的片段
//        这个是thymeleaf和Ajax进行连接的格式
        return "admin/blogs :: blogList";

    }

  1. @Pagedefault() 这个配置里面可以进行相关的注解的配置size= ,direction=,sort= {" "},可以根据相关的字段进行排序的操作,然后通过Model model进行前端的值的获取,最终可以把值取出。
  2. 前端的页面进行相关的展现
    取到相关的值进行展示

<!--中间内容部分-->
<div class="m-container-small m-panded-tb-big">
	<div class="ui container">
<!--		Secondary segment可以变成浅黑色-->
		<form action="#" class="ui secondary segment form">
<!--隐藏的page进行传值-->
			<input type="hidden" name="page">
<!--			表单加上区域
 加上inline后就成一个短一点的行-->
			<div class="inline fields">
				<div class="field">	<input type="text" name="title" placeholder="标题"></div>

				<div class="field">
					<div class="ui selection dropdown">
						<input type="hidden" name="typeId">
						<i class="dropdown icon"></i>
						<div class="default text">分类</div>
<!--选项里面的内容						-->
						<div class="menu">
							<div th:each="type : ${types}" th:data-value="${type.id}" th:text="${type.name}" class="item" data-value="1">错误日志</div>


						</div>
					</div>
				</div>
				<div class="field">
					<div class="ui checkbox">
<!--						input 和label进行绑定 for 和id的相一致-->
						<input type="checkbox" name="recommend" id="recommend">
						<label for="recommend">推荐</label>
					</div>
				</div>

				<div class="field">
					<button type="ui button" id="search-btn" class="ui mini circular teal basic button">
						<i class="search icon"></i>搜索
					</button>
				</div>

			</div>
		</form>



		<div id="table-container">
			<!--		表格-->
			<!--		celled可以加上网格线 teal 可以把上面的表格变成绿色-->
<!--			thymleaf可以支持Ajax的请求的局部的加载-->
			<table th:fragment="blogList"
				   class="ui teal compact celled table">
				<thead>
				<tr>
					<th></th>
					<th>标题</th>
					<th>类型</th>
					<th>推荐</th>
					<th>更新时间</th>
					<th>操作</th>

				</tr>
				<a href="" class="ui right floated big teal basic circular inline button">新增</a>
				</thead>
				<tbody>
				<tr th:each="blog,iterStat:${page.content}">
					<td th:text="${iterStat.count}">1</td>
					<td th:text="${blog.title}">刻意练习清单</td>
					<td th:text="${blog.type.name}">认知升级</td>
					<td th:text="${blog.recommend} ?'':''"></td>
					<td th:text="${blog.updateTime}">2020-6-24 12:45</td>
					<td>
						<a href="#" class="ui mini teal button">更新</a>
						<a href="#" class="ui mini red basic button">删除</a>
					</td>
				</tr>
				</tbody>
				<tfoot>
				<th colspan="6">
					<div class="ui pagination menu" th:if="${page.totalPages}>1">
						<a href="" class="icon item">
							<i class="left teal chevron icon"></i>
						</a>
						<!--  data-  html定义一个数据域的方法-->
						<!--				自定义的属性使用thymleaf进行相关的解析 th:attr-->
						<a onclick="page(this)" th:attr="data-page=${page.number}-1"  class="item" th:unless="${page.first}">上一页</a>
						<a onclick="page(this)" th:attr="data-page=${page.number}+1"  class="item" th:unless="${page.last}">下一页</a>
						<i class="right teal chevron icon"></i>
						</a>
					</div>

				</th>
				</tfoot>
			</table>
		</div>

	</div>
</div>

这个里面的取值用的是thymleaf模板里面的语法,可以到官网进行观看。

 th:each="type : ${types}"  th:data-value="${type.id}" th:text="${type.name}"
  1. 可以通过这个进行值的获取
<!--隐藏的page进行传值-->
			<input type="hidden" name="page">
  1. 相关的Jquery的实现的功能
<!--动态搜索的加载-->
<script>
	function page(obj){
//	获取到隐藏的page的值
	$("[name='page']").val($(obj).data("page"));
	loaddData();
//	点击搜索的按钮可以进行加载
	$('#search-btn').click(function () {
		loaddData();

	});
	}
//	使用Ajax 请求进行
	function loaddData() {
//	load里面有两个参数,(Controller层里面有Ajax请求的路径,从前端进行获取的值)
		$("#table-container").load(/*[[@{/admin/blogs/
		search}]]*/"/admin/blogs/search",{
//	从name属性中进行值的获取
			titile : $("[name='title']").val(),
			typeId : $("[name='typeId']").val(),
			//选中才进行查询
			recommend : $("[name='recommend']").prop('checked'),
			page : $("[name='page']").val(),

		});



	}
</script>

以上是关于Spring提供的JPA的分页的功能,和动态搜索后进行显示的分页功能的设置的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Data JPA 中使用带有分页的投影接口?

spring data jpa 的分页以及条件查询

ElementUI的分页功能bug

海量数据的分页怎么破?我的方案这样“改良”后,实在太完美!

海量数据的分页怎么破?我的方案这样“改良”后,实在太完美!

Spring Data JPA中的分页问题