做了太多无用功,心情复杂
1. SpringBoot 中的 PageHelper
如果你也在用 MyBatis,建议尝试该分页插件,这一定是最方便使用的分页插件。分页插件支持任何复杂的单表、多表分页。
这不是我说的,官方是这么介绍来着。但是使用过程中也确实有特别方便的地方。也有我学艺不精,暗自头疼的时候。
最近可能是很闲,我看到室友的博客项目后,自己也想造轮子。其实自己之前也有计划写,但是我的懒惰还是打败了行动。最近一段时间开始用SpringBoot搭建一个博客项目。其中在后端展示留言信息时涉及分页。我之前也用过PageHelper寻思很方便这次也就直接上了。
1. 配置PageHelper
*1. *pomx.xml引入依赖
<dependency> |
2. application.properties 配置
#分页插件 |
简单赋值一下官网的解释
helperDialect
:分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。配置时,可以使用下面的缩写值:oracle
,mysql
,mariadb
,sqlite
,hsqldb
,postgresql
,db2
,sqlserver
,informix
,h2
,sqlserver2012
,derby
特别注意:使用 SqlServer2012 数据库时,需要手动指定为 sqlserver2012
,否则会使用 SqlServer2005 的方式进行分页。
2. params
:为了支持startPage(Object params)
方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值
3. reasonable
:分页合理化参数,默认值为false
。当该参数设置为 true
时,pageNum<=0
时会查询第一页, pageNum>pages
(超过总数时),会查询最后一页。
4. supportMethodsArguments
:支持通过 Mapper 接口参数来传递分页参数,默认值false
,分页插件会从查询方法的参数值中,自动根据上面 params
配置的字段中取值,查找到合适的值时就会自动分页。
*3. * 操作代码
- Service
public interface CommentService {
List<Comment> listAllComment();
}
//实现接口类中方法 |
- Controller这里我用了参数来表示获取哪一页的数据
/**
* 获取所有留言(留言板)
* */
@ApiOperation("获取所有留言")
@GetMapping("comments/list/{page}")
public PageInfo listAllComment(@PathVariable("page") Integer pageNum){
//第一个参数表述页数,第二个表示获取数量
PageHelper.startPage(pageNum,5);
List<Comment> commentList = commentService.listAllComment();
PageInfo<Comment> pageInfo = new PageInfo<>(commentList);
return pageInfo;
}
前端调用接口查看一下返回的数据
获取第一页的5条数据
前端获取的数据如下
好了,前端想要的数据都有了,真的是很方便。前端通过js获取数据再向网页中填充渲染就可以了。
前端的操作就引人而异了自己前端太菜
我这里是用art-template模板插件和 jquery ajax 请求数据
具体如下
<!-- 引入模板引擎js -->
<script src='../js/template-web.js'></script>
<!--制定卡片模板 -->
<script type="text/html" id="commentTemplate">
<tr>
<td>{{index}}</td>
<td>{{nickName}}</td>
<td>{{email}}</td>
<td width="30%">{{comment}}</td>
<td>{{date}}</td>
<td>{{address}}</td>
<td>
<button type="button" class="mb-2 btn btn-sm btn-danger mr-1" data-toggle="modal" data-target="#deleteModal" onclick="getCommentId(this)">删除</button>
<p hidden>{{commentId}}</p>
<button type="button" class="mb-2 btn btn-sm btn-primary mr-1">回复</button>
</td>
</tr>
</script>
<script type="text/html" id="page-distribution-template">
<nav class="pagination-lg" aria-label="Page navigation" style=" margin-left: 35%;margin-top: 40px!important;">
<ul class="pagination">
<li class="page-item ">
<a href="#" class="page-link first-page" aria-label="Previous" onclick="jumpPage(this)">
<p hidden class="p-hidden">{{firstPage}}</p>
<span aria-hidden="true">«</span>
</a>
</li>
<li class="page-item ">
<a href="#" class="page-link pre-page" onclick="jumpPage(this)">
<p hidden class="p-hidden">{{prePage}}</p>
<span aria-hidden="true"><</span>
</a>
</li>
<li class="page-item "><a href="#" class="page-link">{{pageNum}}</a>
</li>
<li class="page-item ">
<a href="#" class="page-link next-page" onclick="jumpPage(this)">
<p hidden class="p-hidden">{{nextPage}}</p>
<span aria-hidden="true">></span>
</a>
</li>
<li class="page-item">
<a href="#" class="page-link last-page" aria-label="Next" onclick="jumpPage(this)">
<p hidden class="p-hidden">{{lastPage}}</p>
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</script>
这里我制定了两个模板,一个是表格中数据的载体模板,一个是分页Bar的模板
- ajax 请求数据
<script type="text/javascript">
$(document).ready(function(){
//默认初始化第一页
listComments(1);
});
function listComments(page) {
$.ajax({
type:"get",
url:"/api/comments/list/"+page,
dataType:"json",
async: true,
success:function (result) {
var json = result; //数组
var pageList = json.list;
//渲染填充表格数据
$.each(pageList,function (index,item) {
var data = {
index:"",
commentId:"",
nickName:"",
email:"",
comment:"",
date:"",
address:""
};
data.index = index+1;
data.commentId=pageList[index].id;
data.nickName=pageList[index].name;
data.email = pageList[index].email;
data.comment = pageList[index].content;
data.date = pageList[index].create_by;
data.address = pageList[index].ip;
var res = template("commentTemplate", data);
document.getElementById("comment_container").innerHTML += res;
});
//渲染填充分页数据
//总页数,也是最后一页 向下取整加1
var pages=json.pages;
var pageNum = json.pageNum;//当前页
var prePage;
var nextPage;
//前一页判断
if(pageNum-1>=1){
prePage = json.prePage;
}else{
prePage =1;
}
//后一页判断
if(pageNum+1<=pages){
nextPage = json.pageNum+1;
}else{
nextPage = pages;
}
var pageData ={
firstPage:1,
prePage:prePage,
pageNum:pageNum,
nextPage:nextPage,
lastPage:pages
}
var res = template("page-distribution-template", pageData);
document.getElementById("page-distribution").innerHTML += res;
},
error:function (error) {
console.log(error);
}
});
}
function jumpPage(ob) {
var pageNum =$(ob).children('p:first-child').text();
$('.comment_container').empty();
$('.page-distribution').empty();
listComments(pageNum);
}
</script>
换页请求发送就清空原来模板位置的数据,重新请求填充。
写的比较杂乱,很多地方也有可以优化的之处。但是现在先把功能做出来再说。
效果图
大概就是这样。
其中有个体验非常不好的地方就是,由于留言内容长短不一样,在请求渲染过后就会很明显感到页面刷新闪动一下。感觉就比较恶心。我这里也还没想到怎么解决
2. 遇到的坑
上面是成功做出来了的时候,看着还比较简单。一开始我不是这个方案的。
其中遇到了两个比较突出的问题,都是涉及到了数据库设计这种最初的问题
- 其一
我在数据库中储存的时间是 Date 类型,那当然我项目中对应的 entity 也是 Date 类型属性参数了。然后在返回前端的数据中时就出问题了。
JavaDate数据返回到前端变成了数字
后台在返回json数据的时候,用自身的序列化机制把时间变成一段很长的数字。类似图中(网上找的)
解决方法
利用 @JsonFormat 注解对Date 属性参数进行注解就解决了。
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") |
- 其二
我遇到最大的问题就返回给前端的数据不完整,或者说是不正确
如下图中
除了list中的数据是对的,其他PageInfo属性均不对。
再贴一下正确的对比。
我一开始始终没想到问题在哪。获取的留言信息都正确,为什么其他的属性不匹配
后来搜寻了半天,也去PageInfo看官网文档
常见问题 和 重要提示
在官方的FQA中我看到这样一条
为什么不支持一对一和一对多结果映射的分页查询? |
这里说的在经过嵌套处理后会出现问题。
我想到一开始我的List 中对象不是对应的数据库中 entity,因为数据库中有这里不需要的字段,所以我重新封装了一个对象,只含有自己需要的字段。
在 Service 中我先将数据库中的 Comment list 全部取出来,然后再循环填充到我新封装的对象集合中去。
那么问题就在这里了,这里我用的是Comment对应的SQL 语句进行查询的,只是将返回的数据进行了转移填充。
实际上新对象是没有对应的SQL的,我是这样理解的。所以后面我用 PageInfo 进行接受时也仅仅只含有填充的数据,**其他需要Page Helper需要向数据库索取的数据都不含有,也就导致了数据的缺失。**
后面我直接用数据库对应的 entity 就正常了。总之还是自己在设计数据库的时候没有更多的考虑到这些问题。
坑就先留到这里,后面在有什么问题再继续补充。