您的位置:首页 > 其它

Mybatis的pageHelper插件实现分页

2017-05-18 20:47 716 查看

1.场景分析

     近期的项目中屡次遇到分页的需求,今天笔者就mybatis的pageHelper插件实现分页且结合前端展示界面详细给大家讲解下,望能够帮助更多的朋友!

2.pageHelper的配置

①添加pageHelper插件依赖

<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.4</version>
</dependency>


 ②在mybatis-config.xml配置pageHelper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--配置全局属性-->
<settings>
<!--使用jdbc的getGeneratekeys获取自增主键值-->
<setting name="useGeneratedKeys" value="true"/>
<!--使用列别名替换列名  默认值为true
select name as title(实体中的属性名是title) form table;
开启后mybatis会自动帮我们把表中name的值赋到对应实体的title属性中
-->
<setting name="useColumnLabel" value="true"/>

<!--开启驼峰命名转换Table:create_time到 Entity(createTime)-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

<!-- 配置pagehelper -->
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 4.0.0以后版本可以不设置该参数 -->
<property name="dialect" value="mysql"/>
<!-- 该参数默认为false -->
<!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
<!-- 和startPage中的pageNum效果一样-->
<property name="offsetAsPageNum" value="true"/>
<!-- 该参数默认为false -->
<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
<property name="rowBoundsWithCount" value="true"/>
<!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
<!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型)-->
<property name="pageSizeZero" value="true"/>
<!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
<!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
<!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
<property name="reasonable" value="true"/>
<!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
<!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
<!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值 -->
<!-- 不理解该含义的前提下,不要随便复制该配置 -->
<property name="params" value="pageNum=start;pageSize=limit;"/>
<!-- 支持通过Mapper接口参数来传递分页参数 -->
<property name="supportMethodsArguments" value="true"/>
<!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
<property name="returnPageInfo" value="check"/>
</plugin>
</plugins>

</configuration>


特别注意:

<property name="dialect" value="mysql"/>


后台数据库是什么value就写什么,对号入座。

③在spring-dao中对mybatis-config.xml进行申明

<!--3.配置SqlSessionFactory对象-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--往下才是mybatis和spring真正整合的配置-->
<!--注入数据库连接池-->
<property name="dataSource" ref="dataSource"/>
<!--配置mybatis全局配置文件:mybatis-config.xml-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--扫描entity包,使用别名,多个用;隔开-->
<property name="typeAliasesPackage" value="com.cckj.bean"/>
<!--扫描sql配置文件:mapper需要的xml文件-->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>

3.实现方案

前端代码:
①分页插件主代码:

<link href="css/simple.css" type="text/css" rel="stylesheet"/>
<script src="js/jquery-1.8.3.min.js"></script>
<script src="js/jquery.page.js"></script>
<script>

var page=localStorage.getItem("total");

$(".tcdPageCode").createPage({
pageCount:localStorage.getItem("total"),
current:1,
backFn:function(p){
initdata(p);//触发逻辑
}
});
</script>


②jquery.page.js代码

(function($){
var ms = {
init:function(obj,args){
return (function(){
ms.fillHtml(obj,args);
ms.bindEvent(obj,args);
})();
},
//填充html
fillHtml:function(obj,args){
return (function(){
obj.empty();
//上一页
if(args.current > 1){
obj.append('<a href="javascript:;" class="prevPage">上一页</a>');
}else{
obj.remove('.prevPage');
obj.append('<span class="disabled">上一页</span>');
}
//中间页码
if(args.current != 1 && args.current >= 4 && args.pageCount != 4){
obj.append('<a href="javascript:;" class="tcdNumber">'+1+'</a>');
}
if(args.current-2 > 2 && args.current <= args.pageCount && args.pageCount > 5){
obj.append('<span>...</span>');
}
var start = args.current -2,end = args.current+2;
if((start > 1 && args.current < 4)||args.current == 1){
end++;
}
if(args.current > args.pageCount-4 && args.current >= args.pageCount){
start--;
}
for (;start <= end; start++) {
if(start <= args.pageCount && start >= 1){
if(start != args.current){
obj.append('<a href="javascript:;" class="tcdNumber">'+ start +'</a>');
}else{
obj.append('<span class="current">'+ start +'</span>');
}
}
}
if(args.current + 2 < args.pageCount - 1 && args.current >= 1 && args.pageCount > 5){
obj.append('<span>...</span>');
}
if(args.current != args.pageCount && args.current < args.pageCount -2  && args.pageCount != 4){
obj.append('<a href="javascript:;" class="tcdNumber">'+args.pageCount+'</a>');
}
//下一页
if(args.current < args.pageCount){
obj.append('<a href="javascript:;" class="nextPage">下一页</a>');
}else{
obj.remove('.nextPage');
obj.append('<span class="disabled">下一页</span>');
}
})();
},
//绑定事件
bindEvent:function(obj,args){
return (function(){
obj.on("click","a.tcdNumber",function(){
var current = parseInt($(this).text());
ms.fillHtml(obj,{"current":current,"pageCount":args.pageCount});
if(typeof(args.backFn)=="function"){
args.backFn(current);
}
});
//上一页
obj.on("click","a.prevPage",function(){
var current = parseInt(obj.children("span.current").text());
ms.fillHtml(obj,{"current":current-1,"pageCount":args.pageCount});
if(typeof(args.backFn)=="function"){
args.backFn(current-1);
}
});
//下一页
obj.on("click","a.nextPage",function(){
var current = parseInt(obj.children("span.current").text());
ms.fillHtml(obj,{"current":current+1,"pageCount":args.pageCount});
if(typeof(args.backFn)=="function"){
args.backFn(current+1);
}
});
})();
}
}
$.fn.createPage = function(options){
var args = $.extend({
pageCount : 15,
current : 1,
backFn : function(){}
},options);
ms.init(this,args);
}
})(jQuery);

③simple.css样式代码

*{ margin:0; padding:0; list-style:none;}
a{ text-decoration:none;}
a:hover{ text-decoration:none;}
.tcdPageCode{padding: 15px 20px;text-align: left;color: #ccc;text-align:left;}
.tcdPageCode a{display: inline-block;color: #428bca;display: inline-block;height: 25px;    line-height: 25px; padding: 0 10px;border: 1px solid #ddd;    margin: 0 2px;border-radius: 4px;vertical-align: middle;}
.tcdPageCode a:hover{text-decoration: none;border: 1px solid #428bca;}
.tcdPageCode span.current{display: inline-block;height: 25px;line-height: 25px;padding: 0 10px;margin: 0 2px;color: #fff;background-color: #428bca;    border: 1px solid #428bca;border-radius: 4px;vertical-align: middle;}
.tcdPageCode span.disabled{    display: inline-block;height: 25px;line-height: 25px;padding: 0 10px;margin: 0 2px;    color: #bfbfbf;background: #f2f2f2;border: 1px solid #bfbfbf;border-radius: 4px;vertical-align: middle;}

④主界面前端代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入 echarts.js -->
<link rel="stylesheet" href="css/gongchang-style.css" />
<link href="css/page.css" type="text/css" rel="stylesheet"/>
<link href="css/simple.css" type="text/css" rel="stylesheet"/>
<script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script type="text/javascript" src="js/page.js"></script>
<script type="text/javascript" src="js/jQuery.js"></script>
<script src="js/echarts.js"></script>

</head>
<body onload="initdata(1)">
<div>

<div class="grid-wrap">
<div>
<input type="text" id="nicheng" placeholder="搜索">
<input type="button" onclick="search()" value="搜索">

</div>
<div class="grid"  id="grid1">
<div class="grid-header" id="grid1">
<span class="row-1">姓名</span>
<span class="row-1">年龄</span>
<span class="row-1">性别</span>
<span class="row-1">手机号码</span>
<span class="row-1">居住地址</span>
</div>
<div class="grid-body">
<!-- <div class="grid-item">
<span class="row-1">zhangxing</span>
<span class="row-1">24</span>
<span class="row-1">男</span>
<span class="row-1">18772351259</span>
<span class="row-1">浙江西湖</span>
</div>

<div class="grid-item">
<span class="row-1">lisishan</span>
<span class="row-1">23</span>
<span class="row-1">女</span>
<span class="row-1">17682317584</span>
<span class="row-1">浙江余杭</span>
</div> -->

</div>
</div>

</div>
<!--分页插件-->
<div class="tcdPageCode"></div>

</div>

<script type="text/javascript">
var options;
/**初始函数
* [initdata description]
* @return {[type]} [description]
*/
function initdata(page){

$.ajax({
type: "get",
url: "http://localhost:8080/userInfo/getUserInfoByPage?pageNum="+page,
success: function(data, textStatus){
if(data.status == 1){
var result = data.userInfoList;
var total = data.totalPage;
localStorage.setItem("total",total);
/* alert(totalPage);
alert(result);*/
var cHtml="";
for(var i=0;i<result.length;i++){
cHtml+='<div class="grid-item">\
<span class="row-1">'+result[i].username+'</span>\
<span class="row-1">'+result[i].age+'</span>\
<span class="row-1">'+result[i].sex+'</span>\
<span class="row-1">'+result[i].phone+'</span>\
<span class="row-1">'+result[i].address+'</span>\
</div>'

}
$(".grid-body").html(cHtml);
}

},
complete: function(XMLHttpRequest, textStatus){

},
error: function(){
alert("请求网络失败!。。。。。。");
}
});
}

/**模糊搜索
* [search description]
* @return {[type]} [description]
*/
function search(){
var nicheng =document.getElementById("nicheng").value;
$('.grid-item').remove();

$.ajax({
type: "get",
url: "http://localhost:8080/userInfo/getUserInfoByName?username="+nicheng,
success: function(data, textStatus){
if(data.status == 1){
var addHtml = "";
var result = data.userlist;
for (var j =0;j<data.userlist.length;j++) {

addHtml+='<div class="grid-item">\
<span class="row-1">'+result[j].username+'</span>\
<span class="row-1">'+result[j].age+'</span>\
<span class="row-1">'+result[j].sex+'</span>\
<span class="row-1">'+result[j].phone+'</span>\
<span class="row-1">'+result[j].address+'</span>\
</div>'

}
$(".grid-body").html(addHtml);
}

},
complete: function(XMLHttpRequest, textStatus){

},
error: function(){
alert("请求网络失败!。。。。。。");
}
});
}

</script>
<script src="js/jquery-1.8.3.min.js"></script>
<script src="js/jquery.page.js"></script>
<script>

var page=localStorage.getItem("total");

$(".tcdPageCode").createPage({
pageCount:localStorage.getItem("total"),
current:1,
backFn:function(p){
initdata(p);//触发逻辑
}
});
</script>
</body>
</html>

其中运用了localStorage的缓存技术以及 jQuery的动态数据渲染的详细的实现步骤;
后台代码:

①mapper定义接口

<select id="getUserInfo" resultType="com.cckj.bean.UserInfo">
select * from userinfo
</select>

②controller实现分页逻辑

@RequestMapping(value = "/getUserInfoByPage", produces = "application/json;charset=utf-8")
public Map<String,Object> getUserInfoByPage(HttpServletResponse response ,
@RequestParam(required=false,defaultValue="1") Integer pageNum,
@RequestParam(required=false,defaultValue="3") Integer pageSize){
response.setHeader("Access-Control-Allow-Origin","*");
PageHelper.startPage(pageNum, pageSize); // 核心分页代码
List<UserInfo> userList = userInfoService.getUserInfo();
PageInfo pageInfo = new PageInfo(userList);
int pageCount = pageInfo.getPages();//总页数
Map<String,Object> map = new HashMap<>();
map.put("userInfoList",userList);
map.put("status",1);
map.put("totalPage",pageCount);
return map;
}


默认展示第1页,且每页数据为3条;

核心分页代码

PageHelper.startPage(pageNum, pageSize); // 核心分页代码

通过实例化 PageInfo得到分页后的总页数

PageInfo pageInfo = new PageInfo(userList);
int pageCount = pageInfo.getPages();

③分页后的json样本:



4.测试效果

第1页数据:



第2页数据:



第5页数据



好了,后台的分页逻辑与前端的分页显示结合的恰到好处;需要源码的朋友,及时私信我!我是张星,欢迎加入博主技术交流群,群号:313145288
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息