PageHelper是一款开源的MyBatis插件,它提供了对MySQL、Oracle、DB2等主流数据库的支持,极大地简化了后端处理分页查询的过程,使用PageHelper对后端开发有很大帮助
PageHelper 使用的注意点
1. 只有紧跟在 PageHelper.startPage 方法后的第一个 Mybatis 的查询(Select)方法会被分页。
2. 不能同时配置多个分页插件
3. 分页插件不支持带有 for update 语句的分页,需要手动分页
4. 不支持一对一和一对多结果映射的分页查询,如果分页显示20条数据,这20条数据中每一个包含30条子数据,则子数据只能显示20条,其余会丢失。
一:在 pom.xml 中添加如下依赖:
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.8</version>
</dependency>
二:配置pageHelper
在Spring核心配置文件application.xml 中,配置org.mybatis.spring.SqlSessionFactoryBean时添加属性
<!-- 配置SqlSessionFactory这是mybatis工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property><!-- 注入数据源 -->
<property name="mapperLocations" value="classpath:com/aaa/dao/*.xml"></property><!--自动扫描dao映射文件 -->
<!-- <property name="typeAliases" value="com.aaa.entity"></property> --><!--类型别名 dao映射可以直接返回实体对象-->
<!-- pagrHelper分页插件 -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<!--使用下面的方式配置参数,一行配置一个 分页参数参考官方-->
<!-- <value>
helperDialect=mysql
reasonable=true
supportMethodsArguments=true
params=count=countSql
autoRuntimeDialect=true
</value> -->
<props>
<!--数据库类型-->
<prop key="helperDialect">mysql</prop>
<!--页码超出范围自动修正-->
<prop key="reasonable">true</prop>
</props>
</property>
</bean>
</array>
</property>
</bean>
三:在要分页的方法上添加分页插件拦截器
PageHelper 常用类信息
有三个主要类需要了解:
Page 分页对象:继承 ArrayList,对查询结果进行进一步的封装处理
主要属性:
pageNum : 起始页码
pageSize : 每页显示条数
startRow : 起始行
endRow : 结束行
total : 总记录数
pages : 总页数
reasonable : 分页合理化,布尔值,是否对超出范围的页码自动优化处理
PageHelper 通用分页拦截器常用方法:
Page < E > startPage(int pageNum,int pageSize):根据起始页和每页条数查询,返回一个Page结果集;
Page < E > offsetPage(int offset,int limit):根据起始索引和查询条数查询,返回一个Page结果集;
PageInfo 响应给前端的分页对象:对Page结果进行包装
主要属性:
pageNum : 当前页
pageSize : 每页的数量
size : 当前页的数量(最后一页不足每页条数)
startRow : 当前页面第一个元素在数据库中的行号
endRow : 当前页面最后一个元素在数据库中的行号
pages : 总页数
prePage: 上一页的页码
nextPage: 下一页的页码
构造方法:
public PageInfo(List list) {
this(list, 8);
}
1.controller采用异步返回JSON
先执行startPage()或offsetPage()方法,将返回的分页信息通过 PageInfo 的构造方法进行封装
@RequestMapping("/queryTbGoods")
@ResponseBody
public PageInfo queryTbGoods(@RequestParam(required=true,defaultValue="1") Integer pageNum,@RequestParam(required=false,defaultValue="3") Integer pageSize,@RequestParam Map map){
//System.out.println(map.get("goodsName")+":参数:"+map.get("typeName"));
/*开启分页插件拦截器*/
PageHelper.startPage(pageNum, pageSize);
List<Map<String,Object>> list=ts.queryTbGoods(map);
/*封装结果集返回当前页信息(页码, 条数等)*/
PageInfo page= new PageInfo(list);
//System.out.println(page.getTotal()+":"+page.getPages());
return page;
}
2.前端页面JSP采用BootsStrop前端布局
1.引入依赖
<!-- 使用模态窗口引入bootstrap -->
<link rel="stylesheet" type="text/css"
href="${pageContext.request.contextPath}/resouces/js/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css"
href="${pageContext.request.contextPath}/resouces/js/bootstrap/css/bootstrap-theme.min.css">
<script src="${pageContext.request.contextPath}/resouces/js/jquery.min.js"></script>
<script src="${pageContext.request.contextPath}/resouces/js/bootstrap/js/bootstrap.min.js"></script>
<!--最基础jQuery.js都是基于这个 -->
<script type="text/javascript" src="resouces/jquery-1.11.3.min.js"></script>
<!-- 异步转换参数js -->
<script type="text/javascript" src="resouces/jqueryExt.js"></script>
<!-- 上传文件js -->
<script type="text/javascript" src="resouces/jquery.form.js"></script>
2.分页按钮排版代码
<ul class="pager" >
<li>
当前页:<span id="curPage"></span>总页数:<span id="totalPages"></span>总共:<span id="totals"></span>条记录
</li>
<li><a id="first" onclick="changePage(this)">首页</a></li>
<li><a id="prev" onclick="changePage(this)">上一页</a></li>
<li><a id="next" onclick="changePage(this)">下一页</a></li>
<li><a id="last" onclick="changePage(this)">尾页</a></li>
<li><input type="number" id="txtCurPage" min="1" max="10"></input><input type="button" class="btn btn-default" value="go" onclick="gotoPage()"/></li>
</ul>
2.Ajax异步
/* 查询商品表 */
function queryTbGoods(page){
var name=$("#goodsNames").val();
var tyName=$("#typeNames").val();
/* alert(name+":参数:"+tyName); */
$.ajax({
url:"goods/queryTbGoods",
type:"post",
data:{"goodsName":name,"typeName":tyName,"pageNum":page,"pageSize":3},
dataType:"json",
success:function(data){
alert(data.pages);
$("#tbody").empty();
$.each(data.list,function(key,obj){
/* alert(obj.typeId.typeName); */
var tr="<tr>";
tr+="<td>"+obj.goodsId+"</td>";
tr+="<td>"+obj.goodsName+"</td>";
tr+="<td>"+obj.typeName+"</td>";
tr+="<td>"+obj.goodsDesc+"</td>";
tr+="<td>"+obj.goodsUnitPrice+"</td>";
/* tr+="<td><img style=' width:80px; height:80px;' src='"+obj.goodsImageName+"'/></td>"; */
tr+="<td>"+obj.sellCount+"</td>";
tr+="<td>"+obj.goodsDate+"</td>";
tr+="<td><input type='button' id="+obj.goodsId+" data-toggle='modal' data-target='#myModal' title="+obj.goodsId+" class='findById btn btn-default' value='修改'></td>";
tr+="<td><input type='button' id="+obj.goodsId+" class='delete btn btn-default' value='删除'></td>";
tr+="</tr>";
$("#tbody").append(tr);
//重新初始化分页链接
$("#curPage").html(data.pageNum);//当前页
$("#totalPages").html(data.pages);//总页数
$("#totals").html(data.total);//总条数
$("#first").attr("data",1);//首页
$("#prev").attr("data",data.prePage);//上一页
$("#next").attr("data",data.nextPage);//下一页
$("#last").attr("data",data.pages);//尾页
$("#txtCurPage").val(data.pageNum).attr("max",data.pages);
});
}
});
}
//改变页面
function changePage(obj){
var page=$(obj).attr("data");//取出data属性值
queryTbGoods(page);
}
//跳转到指定页面
function gotoPage(page){
var page=$("#txtCurPage").val();
queryTbGoods(page);
}
3.jsp全部代码
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" isELIgnored="false"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<!-- 使用模态窗口引入bootstrap -->
<link rel="stylesheet" type="text/css"
href="${pageContext.request.contextPath}/resouces/js/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css"
href="${pageContext.request.contextPath}/resouces/js/bootstrap/css/bootstrap-theme.min.css">
<script src="${pageContext.request.contextPath}/resouces/js/jquery.min.js"></script>
<script src="${pageContext.request.contextPath}/resouces/js/bootstrap/js/bootstrap.min.js"></script>
<!--最基础jQuery.js都是基于这个 -->
<script type="text/javascript" src="resouces/jquery-1.11.3.min.js"></script>
<!-- 异步转换参数js -->
<script type="text/javascript" src="resouces/jqueryExt.js"></script>
<!-- 上传文件js -->
<script type="text/javascript" src="resouces/jquery.form.js"></script>
</head>
<body>
<table class="table table-hover">
<thead >
<tr class="success">
<th>商品编号</th>
<th>商品名称</th>
<th>商品类型</th>
<th>商品Desc</th>
<th>商品价格</th>
<!-- <th>商品图片</th> -->
<th>商品数量</th>
<th>日期</th>
<!-- <th>操作</th> -->
<th colspan="3">查询
<input type="text" onblur="queryTbGoods()" size="6" class="goodsName" id="goodsNames" placeholder="请输入名称" name="goodsName">
<input type="text" onblur="queryTbGoods()" size="6" class="goodsName" id="typeNames" placeholder="请输入类型" name="typeName">
<input type="button" data-toggle="modal" data-target="#myModal" class="emptys btn btn-default" value="添加">
</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
</table>
<!-- 模态框弹出录入内容 -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog"
aria-labelledby="modalTitle1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">
×
<!-- 关闭按钮 -->
</button>
<h4 class="modal-title" id="modalTitle1">录入商品</h4>
</div>
<div class="modal-body">
<!--form提交表单 -->
<form class="form-horizontal" id="form1" enctype="multipart/form-data">
<div class="form-group">
<label for="roleName" class="col-sm-2 control-label">商品名</label>
<div class="col-sm-4">
<input type="hidden" id="goodsId" name="goodsId" class="form-control" placeholder="请输入">
<input type="text" id="goodsName" name="goodsName" class="form-control" placeholder="请输入商品名">
</div>
</div>
<div class="form-group">
<label for="description" class="col-sm-2 control-label">商品类型</label>
<div class="col-sm-4">
<select class="sele form-control" name="typeId">
</select>
</div>
</div>
<div class="form-group">
<label for="description" class="col-sm-2 control-label">商品Desc</label>
<div class="col-sm-4">
<input type="text" id="goodsDesc" class="form-control" name="goodsDesc"
placeholder="请输入">
</div>
</div>
<div class="form-group">
<label for="description" class="col-sm-2 control-label">商品价格</label>
<div class="col-sm-4">
<input type="text" id="goodsUnitPrice" class="form-control" name="goodsUnitPrice"
placeholder="请输入">
</div>
</div>
<!-- <div class="form-group">
<label for="description" class="col-sm-2 control-label">商品图片</label>
<div class="col-sm-4">
<input type="file" name="goodsImage"/>
</div>
</div> -->
<div class="form-group">
<label for="description" class="col-sm-2 control-label">数量</label>
<div class="col-sm-4">
<input type="text" id="sellCount" class="form-control" name="sellCount"
placeholder="请输入">
</div>
</div>
<div class="form-group">
<label for="description" class="col-sm-2 control-label">日期</label>
<div class="col-sm-4">
<input type="date" id="goodsDate" class="form-control" name="goodsDate"
placeholder="请输入">
</div>
</div>
<input type="button" id="saveUploadOrUpdate" data-toggle='modal' data-target='#myModal' class="btn btn-primary" value="保存">
</form>
</div>
<div class="modal-footer">
<button type="button" class="up btn btn-default" data-dismiss="modal">关闭
</button>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal -->
</div>
<ul class="pager" >
<li>
当前页:<span id="curPage"></span>总页数:<span id="totalPages"></span>总共:<span id="totals"></span>条记录
</li>
<li><a id="first" onclick="changePage(this)">首页</a></li>
<li><a id="prev" onclick="changePage(this)">上一页</a></li>
<li><a id="next" onclick="changePage(this)">下一页</a></li>
<li><a id="last" onclick="changePage(this)">尾页</a></li>
<li><input type="number" id="txtCurPage" min="1" max="10"></input><input type="button" class="btn btn-default" value="go" onclick="gotoPage()"/></li>
</ul>
</body>
</html>
<script>
$(function(){
queryTbGoods();
queryTbGoodsType();
});
/* 查询商品表 */
function queryTbGoods(page){
var name=$("#goodsNames").val();
var tyName=$("#typeNames").val();
/* alert(name+":参数:"+tyName); */
$.ajax({
url:"goods/queryTbGoods",
type:"post",
data:{"goodsName":name,"typeName":tyName,"pageNum":page,"pageSize":3},
dataType:"json",
success:function(data){
alert(data.pages);
$("#tbody").empty();
$.each(data.list,function(key,obj){
/* alert(obj.typeId.typeName); */
var tr="<tr>";
tr+="<td>"+obj.goodsId+"</td>";
tr+="<td>"+obj.goodsName+"</td>";
tr+="<td>"+obj.typeName+"</td>";
tr+="<td>"+obj.goodsDesc+"</td>";
tr+="<td>"+obj.goodsUnitPrice+"</td>";
/* tr+="<td><img style=' width:80px; height:80px;' src='"+obj.goodsImageName+"'/></td>"; */
tr+="<td>"+obj.sellCount+"</td>";
tr+="<td>"+obj.goodsDate+"</td>";
tr+="<td><input type='button' id="+obj.goodsId+" data-toggle='modal' data-target='#myModal' title="+obj.goodsId+" class='findById btn btn-default' value='修改'></td>";
tr+="<td><input type='button' id="+obj.goodsId+" class='delete btn btn-default' value='删除'></td>";
tr+="</tr>";
$("#tbody").append(tr);
//重新初始化分页链接
$("#curPage").html(data.pageNum);//当前页
$("#totalPages").html(data.pages);//总页数
$("#totals").html(data.total);//总条数
$("#first").attr("data",1);//首页
$("#prev").attr("data",data.prePage);//上一页
$("#next").attr("data",data.nextPage);//下一页
$("#last").attr("data",data.pages);//尾页
$("#txtCurPage").val(data.pageNum).attr("max",data.pages);
});
}
});
}
//改变页面
function changePage(obj){
var page=$(obj).attr("data");//取出data属性值
queryTbGoods(page);
}
//跳转到指定页面
function gotoPage(page){
var page=$("#txtCurPage").val();
queryTbGoods(page);
}
/*查询商品类型 */
function queryTbGoodsType(){
$.ajax({
url:"goods/queryTbGoodsType",
type:"post",
data:"",
dataType:"json",
success:function(data){
for(var i=0;i<data.length;i++){
var obj=data[i];
$(".sele").append("<option value='"+obj.typeId+"'>"+obj.typeName+"</option>");
}
}
});
}
/* 添加修改之前清空form表单 */
$(document).on("click",".emptys",function(){
$("#goodsId").val("");
$("#goodsName").val("");
$("#goodsDesc").val("");
$("#goodsUnitPrice").val("");
$("#sellCount").val("");
$("#goodsDate").val("");
});
/*添加修改 */
$(document).on("click","#saveUploadOrUpdate",function(){
/* alert($("#form1").serialize()); */
$.ajax({
url:"goods/saveOrUpdateTbgoods",
type:"post",
data:$("#form1").serialize(),
dataType:"text",
success:function(data){
alert(data);
queryTbGoods();
}
});
});
/*修改前查询 */
$(document).on("click",".findById",function(){
var id=this.id;
$.ajax({
url:"goods/findByIdTbGoods",
type:"post",
data:{"goodsId":id},
dataType:"json",
success:function(data){
$("#goodsId").val(data.goodsId);
$("#goodsName").val(data.goodsName);
$("#goodsDesc").val(data.goodsDesc);
$("#goodsUnitPrice").val(data.goodsUnitPrice);
$("#sellCount").val(data.sellCount);
$("#goodsDate").val(data.goodsDate);
}
});
});
$(document).on("click",".delete",function(){
var id=this.id;
if (confirm("您确定要删除此信息吗?")){
$.ajax({
url:"goods/deleteGoods",
type:"post",
data:{"goodsId":id},
dataType:"text",
success:function(data){
alert(data);
queryTbGoods();
}
});
}else{
return false;
}
});
</script>
4.效果图