分页分页
学习SSM框架时用的
1.导包
<!-- pagehelper :分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
<!-- pagehelper的依赖包:jsqlparser -->
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.5</version>
</dependency>
1.1相关配置
不一定全用,可以起个名字 我这叫 SqlMapConfig.xml
<?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>
<!-- 使全局的映射器启用或禁用缓存。 -->
<setting name="cacheEnabled" value="true"/>
<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 -->
<setting name="aggressiveLazyLoading" value="true"/>
<!-- 是否允许单条sql 返回多个数据集 (取决于驱动的兼容性) default:true -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
<setting name="useColumnLabel" value="true"/>
<!-- 允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。 default:false -->
<setting name="useGeneratedKeys" value="true"/>
<!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不隐射 PARTIAL:部分 FULL:全部 -->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!-- 这是默认的执行类型 (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句;BATCH: 执行器可以重复执行语句和批量更新) -->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 使用驼峰命名法转换字段。 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 设置本地缓存范围 session:就会有数据的共享 statement:语句范围 (这样就不会有数据的共享 ) defalut:session -->
<setting name="localCacheScope" value="SESSION"/>
<!-- 设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER,插入空值时不需要指定类型 -->
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
<property name="offsetAsPageNum" value="false"/>
<property name="rowBoundsWithCount" value="false"/>
<property name="pageSizeZero" value="true"/>
<property name="reasonable" value="false"/>
<property name="supportMethodsArguments" value="false"/>
<property name="returnPageInfo" value="none"/>
</plugin>
</plugins>
</configuration>
其他五个参数说明:
1.增加dialect属性,使用时可以指定该属性(不指定的情况下,分页插件会自动判断),可选值为oracle、mysql、mariadb、sqlite、hsqldb、postgresql、db2、sqlserver、informix、h2、sqlserver2012。
2.增加offsetAsPageNum属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。当该参数设置为true时,使用RowBounds分页时,会将offset参数当成pageNum使用,可以用页码和页面大小两个参数进行分页。
3.增加rowBoundsWithCount属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。当该参数设置为true时,使用RowBounds分页会进行count查询。
4.增加pageSizeZero属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。当该参数设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是Page类型)。
5.增加reasonable属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。具体作用请看上面配置文件中的注释内容。
6.为了支持startPage(Object params)方法,增加了一个params参数来配置参数映射,用于从Map或ServletRequest中取值,可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值。
7.supportMethodsArguments支持通过Mapper接口参数来传递分页参数,默认值false,具体用法参考com.github.pagehelper.test.basic包下的ArgumentsMapTest和ArgumentsObjTest测试类。
8.returnPageInfo用来支持直接返回PageInfo类型,默认值none,可选参数always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page(List)类型。用法和配置参考com.github.pagehelper.test.basic包下的PageInfoTest,特别要注意接口的返回值和xml中的resultType类型。
9.增加closeConn属性,当使用动态数据源或没有设置dialect属性自动获取数据库类型时,会自动获取一个数据库连接,通过该属性来设置是否关闭获取的这个连接,默认true关闭。
重要提示:
当offsetAsPageNum=false的时候,由于PageNum问题,RowBounds查询的时候reasonable会强制为false。使用PageHelper.startPage方法不受影响。
另外使用RowBounds在这种情况下返回的Page对象由于没有正确的pageNum属性,所以也不能使用PageInfo处理。
如果你不理解为什么,可以看这样一个例子:查询offset=7,limit=10,这个时候pageNum=?,这种情况没法计算pageNum,没法判断当前是第几页。
如何选择配置这些参数
单独看每个参数的说明可能是一件让人不爽的事情,这里列举一些可能会用到某些参数的情况。
首先dialect属性是必须的,不需要解释。其他的参数一般情况下我们都不必去管,如果想了解何时使用合适,你可以参考以下场景:
场景一
如果你仍然在用类似ibatis式的命名空间调用方式,你也许会用到rowBoundsWithCount,分页插件对RowBounds支持和Mybatis默认的方式是一致,默认情况下不会进行count查询,如果你想在分页查询时进行count查询,以及使用更强大的PageInfo类,你需要设置该参数为true。
场景二
如果你仍然在用类似ibatis式的命名空间调用方式,你觉得RowBounds中的两个参数offset,limit不如pageNum,pageSize容易理解,你可以使用offsetAsPageNum参数,将该参数设置为true后,offset会当成pageNum使用,limit和pageSize含义相同。
场景三
如果觉得某个地方使用分页后,你仍然想通过控制参数查询全部的结果,你可以配置pageSizeZero为true,配置后,如可以通过设置pageSize=0或者RowBounds.limit = 0就会查询出全部的结果。
场景四
如果你分页插件使用于类似分页查看列表式的数据,如新闻列表,软件列表,你希望用户输入的页数不在合法范围(第一页到最后一页之外)时能够正确的响应到正确的结果页面,那么你可以配置reasonable为true,这时如果pageNum<1会查询第一页,如果pageNum>总页数会查询最后一页。
1.2 读取配置文件spring-mybatis.xml
在配置sqlSessionFactory的时候,指定Mybatis核心配置文件和mapper的路径,代码如下
<!-- ========================================针对myBatis的配置项============================== -->
<!-- 配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 实例化sqlSessionFactory时需要使用上述配置好的数据源以及SQL映射文件 -->
<property name="dataSource" ref="dataSource" />
<!-- 加载Mybatis的全局配置文件文件 -->
<property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
<!-- 自动扫描Mybatis的Mapper.xml文件 -->
<property name="mapperLocations" value="classpath:com/gx/mapping/*.xml" />
</bean>
调用方式
1). RowBounds方式的调用
2)PageHelper.startPage静态方法调用
//分页时,实际返回的结果list类型是Page<E>,如果想取出分页信息,需要强制转换为Page<E>,
((Page) list).getTotal()
//或者使用PageInfo类
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectAll();
//用PageInfo对结果进行包装
PageInfo page = new PageInfo(list);
//测试PageInfo全部属性
//PageInfo包含了非常全面的分页属性
assertEquals(1, page.getPageNum());
assertEquals(10, page.getPageSize());
assertEquals(1, page.getStartRow());
assertEquals(10, page.getEndRow());
assertEquals(183, page.getTotal());
assertEquals(19, page.getPages());
assertEquals(1, page.getFirstPage());
assertEquals(8, page.getLastPage());
assertEquals(true, page.isFirstPage());
assertEquals(false, page.isLastPage());
assertEquals(false, page.isHasPreviousPage());
assertEquals(true, page.isHasNextPage());
1.3 控制层
在你需要进行分页的Mybatis方法前调用PageHelper.startPage静态方法即可,紧跟在这个方法后的第一个Mybatis查询方法会被进行分页。
@RequestMapping("/tolist")
public ModelAndView list(@RequestParam(defaultValue="1")Integer page ){
System.out.print("dsfsdf");
ModelAndView mv=null;
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage( page , 8 );
CcSpecificationExample example = new CcSpecificationExample();
List<CcSpecification> list =ccSpecificationService.selectByExample(example);
mv=new ModelAndView("/specification/list");
GridResult result = new GridResult();
result.setRows(list);
//取分页信息,PageInfo。1、总记录数2、总页数 。当前页码
PageInfo<CcSpecification> pageInfo = new PageInfo<>(list);
result.setTotal(pageInfo.getTotal());
mv.addObject("list",result);
return mv;
}
2.参考封装PageInfo类
https://docs.qq.com/doc/DZkhaZWRKc2VGa3l3
3.属性表
当前页
private int pageNum;
每页的数量
private int pageSize;
当前页的数量
private int size;
//由于startRow和endRow不常用,这里说个具体的用法
//可以在页面中"显示startRow到endRow 共size条数据"
当前页面第一个元素在数据库中的行号
private int startRow;
当前页面最后一个元素在数据库中的行号
private int endRow;
总记录数
private long total;
总页数
private int pages;
结果集
private List<T> list;
第一页
private int firstPage;
前一页
private int prePage;
是否为第一页
private boolean isFirstPage = false;
是否为最后一页
private boolean isLastPage = false;
是否有前一页
private boolean hasPreviousPage = false;
是否有下一页
private boolean hasNextPage = false;
导航页码数
private int navigatePages;
所有导航页号
private int[] navigatepageNums;
后台分页
服务器端
service
public PageInfo<T> methodName(int pageNum, int pageSize) {
//1 设置分页
PageHelper.startPage(pageNum, pageSize);
//2 查询
List<T> list =TMapper.mapperMethod();
//3 返回
return new PageInfo<>(list);
}
Web
public @ResponseBody DataGridResultInfo methodName (Vovo){
//1 查询
PageInfo<T> pageInfo = service. methodName (vo.getPage(), vo.getRows());
//2 封装
return new DataGridBean(pageInfo.getTotal() , pageInfo.getList() );
}
浏览器端
Datagrid
$(function(){
//绘制datagrid
//1 准备数据
// 1.1 列列表
var columnArr = [[
{field:'字段名1',title:'标题1',width:80},
{field:'字段名2',title:'标题2',width:80,
formatter:function(value,rows,index){
//filed匹配值(当前的值),当前行,当前行号
return value.info;
}
}
]];
// 1.2 工具条
var toolbarArr = [
{
iconCls: 'icon-add',//按钮图标
text : '添加用户',
handler: showadduser//方法名
}
];
// 1.3 请求路径
var url = "……";
//2 准备参数
var options = {
"columns":columnArr,
"toolbar":toolbarArr,
"striped":true, //隔行换色
"idField":"id", //标识字段
"url":url, //请求路径
"pagination":true,
"rownumbers":true,
"pageSize":2,
"pageList":[2,4,6,8]
};
//3 绘制
$("#id值").datagrid( options );
});
感觉这个很简单,没什么好写的
不用工具
<c:forEach items="${pageInfo.list}" var="p">
<tr>
<td>${p.属性1}</td>
<td>${p.属性2}</td>
<td>${p.属性…}</td>
</tr>
</c:forEach>
方法表
int getOffset()
当前页之前,还应该有多少条记录
int getPageCount() /pageInfo.getPages()
一共有多少页
int getPageNumber()
当前是第几页, 从 1 开始
int getPageSize()
一页可以有多少条记录
int getRecordCount() /pageInfo.getTotal()
整个查询,一共有多少条记录
boolean isFirst()
boolean isLast()
PageInfo setPageNumber(int pageNumber)
设置页码
PageInfo setPageSize(int pageSize) /pageInfo.getPageSize()
设置一页可以有多少条记录
PageInfo setRecordCount(int recordCount)
设置整个查询一共有多少条记录
前端如何写请参考
https://blog.csdn.net/qq_22860341/article/details/82893487
<div class="box">
<div id="pagination" class="page center">
</div>
var pageNum = [[${pageInfo.pageNum}]];
var pages = [[${pageInfo.pages}]];
var pageSize = [[${pageInfo.pageSize}]];
//
$("#pagination").pagination({
currentPage: pageNum,
totalPage: pages,
isShow: true,
count: pageSize,
homePageText: "首页",
endPageText: "尾页",
prevPageText: "上一页",
nextPageText: "下一页",
});
//点击页数
$('.ui-pagination-page-item').on('click', function () {
var pageNum = $(this).attr('data-current');
window.location.href = encodeURI('${ctx}/SpecificationWeb/list.do?pageNum=' + pageNum);
});
<script type="text/javascript">
function addfunction(){
parent.document.getElementById('Mainid').src='${ctx}/Passenger/toadd.do';
}
function updatefunction(){
var chk_value=[];
$('input[name="id"]:checked').each(function(){
chk_value.push($(this).val());
});
if(chk_value!=""){
if(chk_value.toString().indexOf(",")>0){
alert("修改只能选择一条");
}else{
parent.document.getElementById("Mainid").src='${ctx}/Passenger/toupdate.do?id='+chk_value;
}
}else{
alert("请选择一条数据进行修改");
}
}
function deletefunction(){
var chk_value=[];
$('input[name="id"]:checked').each(function(){
chk_value.push($(this).val());
});
if(chk_value!=""){
var flag=window.confirm("注意:您确定要永久删除该信息吗?");
if(flag){
parent.document.getElementById("Mainid").src='${ctx}/Passenger/delete.do?id='+chk_value;
}
}else{
alert("请选择一条或多条数据进行删除");
}
}
<div class="span11">
<div class="row-fluid">
<div class="tcdPageCode" style="text-align:center;"></div>
</div>
</div>
/* 分页要用的 */
$(".tcdPageCode").createPage({
pageCount:${list.totalPage},
current:${list.currentPage},
backFn:function(p){
var txtname=document.getElementById("txtnameid").value;
location.href="${ctx}/Passenger/tolist.do?currentPage="+p+"&txtname="+txtname;
}
});
</script>