MyBatis分页插件-PageHelper的配置与应用

学习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>
   
发布了162 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_39088066/article/details/103348867