一、PageHelper介绍

二、PageHelper使用

2.1 集成(推荐Maven)

  • 在父工程的pom.xml文件中添加依赖:
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.2</version><!--最新版本即可-->
        </dependency>

2.2 配置

2.2.1 在MyBatis配置文件SqlMapConfig.xml进行配置

  • 单独使用MyBatis时,在SqlMapConfig.xml中进行配置
<!--
    plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
    properties?, settings?,
    typeAliases?, typeHandlers?,
    objectFactory?,objectWrapperFactory?,
    plugins?,
    environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
        <property name="param1" value="value1"/>
    </plugin>
</plugins>

2.2.2 在Spring配置文件applicationContext.xml进行配置

  • applicationContext.xml
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 注意其他配置 -->
    <property name="plugins">
        <array>
            <bean class="com.github.pagehelper.PageInterceptor">
                <property name="properties">
                    <!--使用下面的方式配置参数,一行配置一个 -->
                    <value>
                        params=value1
                    </value>
                </property>
            </bean>
        </array>
    </property>
</bean>
  • 完整配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 开启注解扫描,管理dao和service-->
    <context:component-scan base-package="com.ruki.eams.service" />
    <context:component-scan base-package="com.ruki.eams.dao" />

    <!--读取数据库配置文件-->
    <context:property-placeholder location="classpath:db.properties" />

    <!--配置连接池-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!--SqlSessionFactory交给 IOC管理-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <!--PageHelper插件的传入,后续补充(1018)-->
        <!-- 传入PageHelper的插件 -->
        <property name="plugins">
            <array>
                <!-- 传入插件的对象 -->
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <props>
                            <!--数据库方言-->
                            <prop key="helperDialect">mysql</prop>
                            <!--分页合理化,如在第一页,点击上一页还是第一页-->
                            <prop key="reasonable">true</prop>
                        </props>
                    </property>
                </bean>
            </array>
        </property>
    </bean>

    <!-- 扫描dao接口 -->
    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.ruki.eams.dao"/>
    </bean>

    <!--配置Spring声明式事务管理-->
    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--开启对事务的注解支持-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

</beans>

2.3 分页插件参数详解

  1. helperDialect :分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。 你可以配置
    helperDialect 属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:

oracle , mysql , mariadb , sqlite , hsqldb , postgresql , db2 , sqlserver , informix , h2 , sqlserver2012 ,derby
特别注意:使用 SqlServer2012 数据库时,需要手动指定为 sqlserver2012 ,否则会使用 SqlServer2005 的
方式进行分页。你也可以实现 AbstractHelperDialect ,然后配置该属性为实现类的全限定名称即可使用自定义的实现方法。

  1. offsetAsPageNum :默认值为 false ,该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置为
    true 时,会将 RowBounds 中的 offset 参数当成 pageNum 使用,可以用页码和页面大小两个参数进行分页。
  2. rowBoundsWithCount :默认值为false ,该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置
    true 时,使用 RowBounds 分页会进行 count 查询。
  3. pageSizeZero :默认值为 false ,当该参数设置为 true 时,如果 pageSize=0 或者RowBounds.limit =0 就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是 Page 类型)。
  4. reasonable :分页合理化参数,默认值为false 。当该参数设置为 true 时, pageNum<=0 时会查询第一页, pageNum>pages (超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
  5. params :为了支持startPage(Object params) 方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable ,不配置映射的用默认值, 默认值为
    pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero
  6. supportMethodsArguments :支持通过 Mapper 接口参数来传递分页参数,默认值false ,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTestArgumentsObjTest
  7. autoRuntimeDialect :默认值为 false 。设置为 true 时,允许在运行时根据多数据源自动识别对应方言
    的分页 (不支持自动选择sqlserver2012 ,只能使用sqlserver ),用法和注意事项参考下面的场景五。
  8. closeConn :默认值为 true 。当使用运行时动态数据源或没有设置 helperDialect 属性自动获取数据库类型时,会自动获取一个数据库连接, 通过该属性来设置是否关闭获取的这个连接,默认true 关闭,设置为
    false 后,不会关闭获取的连接,这个参数的设置要根据自己选择的数据源来决定。

2.4 基本使用

  • PageHelper的基本使用有6种,最常用的有两种

2.4.1 RowBounds方式的调用(了解)

List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(1, 10));
  • 使用这种调用方式时,你可以使用RowBounds参数进行分页,这种方式侵入性最小,我们可以看到,通过
    RowBounds方式调用只是使用了这个参数,并没有增加其他任何内容。
  • 分页插件检测到使用了RowBounds参数时,就会对该查询进行物理分页
  • 关于这种方式的调用,有两个特殊的参数是针对 RowBounds 的,可以参看上面的分页插件参数介绍
  • 注:不只有命名空间方式可以用RowBounds,使用接口的时候也可以增加RowBounds参数,例如:
//这种情况下也会进行物理分页查询
List<Country> selectAll(RowBounds rowBounds);
  • 注意: 由于默认情况下的 RowBounds 无法获取查询总数,分页插件提供了一个继承自 RowBounds
    PageRowBounds ,这个对象中增加了 total 属性,执行分页查询后,可以从该属性得到查询总数。

2.4.3 PageHelper.startPage 静态方法调用(重点)

  • 需要进行分页的 MyBatis 查询方法前调用PageHelper.startPage 静态方法即可,紧
    跟在这个方法后的第一个MyBatis 查询方法会被进行分页。
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
//紧跟着的第一个select方法会被分页
List<Country> list = countryMapper.selectIf(1);
  • 在业务层面中则是在dao.findAll()前加入静态方法,需要传入两个参数。
    @Override
    public List<Product> findAll(int page, int size) throws Exception {
        PageHelper.startPage(page, size);
        return productDao.findAll();
    }

三、订单分页查询案例

3.1 controller

  • OrdersController
package com.ruki.eams.controller;

import com.github.pagehelper.PageInfo;
import com.ruki.eams.domain.Orders;
import com.ruki.eams.service.IOrdersService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

@Controller
@RequestMapping("/orders")
public class OrdersController {
    @Autowired
    private IOrdersService ordersService;

    /**
     * 未分页的查询全部订单
     * @return
     * @throws Exception
     */
    /*@RequestMapping("/findAll.do")
    public ModelAndView findAll() throws Exception {
        ModelAndView mv = new ModelAndView();
        List<Orders> orders = ordersService.findAll();
        mv.addObject("ordersList", orders);
        mv.setViewName("orders-list");
        return mv;
    }*/

    /**
     * 有分页的查询全部订单
     * @param page
     * @param size
     * @return
     * @throws Exception
     */
    @RequestMapping("/findAll.do")
    @Secured("ROLE_ADMIN")// @Secured注解下,前缀不能省略
    public ModelAndView findAll(@RequestParam(name = "page", required = true, defaultValue = "1") Integer page, @RequestParam(name = "size", required = true, defaultValue = "4") Integer size) throws Exception {
        ModelAndView mv = new ModelAndView();
        List<Orders> ordersList = ordersService.findAll(page, size);
        //PageInfo就是一个分页Bean
        PageInfo pageInfo = new PageInfo(ordersList);
        mv.addObject("pageInfo", pageInfo);
        mv.setViewName("orders-page-list");
        return mv;
    }
}

3.2 service

  • IOrdersService
package com.ruki.eams.service;

import com.ruki.eams.domain.Orders;

import java.util.List;


public interface IOrdersService {

    List<Orders> findAll(int page, int size) throws Exception;

    Orders findById(String orderId) throws Exception;
}
  • OrdersServiceImpl
package com.ruki.eams.service.impl;

import com.github.pagehelper.PageHelper;
import com.ruki.eams.dao.IOrdersDao;
import com.ruki.eams.domain.Orders;
import com.ruki.eams.service.IOrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
public class OrdersServiceImpl implements IOrdersService {

    @Autowired
    private IOrdersDao ordersDao;

    @Override
    public List<Orders> findAll(int page, int size) throws Exception {
        //System.out.println("page: "+page+"---"+"size: "+size);
        //pageNum是页码值,pageSize是每页显示条数
        PageHelper.startPage(page,size);
        return ordersDao.findAll();
    }

    @Override
    public Orders findById(String orderId) throws Exception {
        return ordersDao.findById(orderId);
    }
}

3.3 dao

  • IOrdersDao
package com.ruki.eams.dao;

import com.ruki.eams.domain.Member;
import com.ruki.eams.domain.Orders;
import com.ruki.eams.domain.Product;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface IOrdersDao {
    @Select("select * from orders")
    @Results({
            @Result(id = true, property = "id", column = "id"),
            @Result(property = "orderNum", column = "orderNum"),
            @Result(property = "orderTime", column = "orderTime"),
            @Result(property = "peopleCount", column = "peopleCount"),
            @Result(property = "payType", column = "payType"),
            @Result(property = "orderDesc", column = "orderDesc"),
            @Result(property = "orderStatus", column = "orderStatus"),
            @Result(property = "product", column = "productId", javaType = Product.class, one = @One(select = "com.ruki.eams.dao.IProductDao.findById"))
    })
    List<Orders> findAll() throws Exception;
}

3.4 前端页面

  • orders-page-list.jsp
<!-- .box-footer-->
<div class="box-footer">
    <div class="pull-left">
        <div class="form-group form-inline">
            总共 ${pageInfo.pages}页,共${pageInfo.total}条数据。 每页
                <select class="form-control" id="changePageSize" onchange="changePageSize()">
                    <option>1</option>
                        <option>2</option>
                        <option>3</option>
                        <option>4</option>
                        <option>5</option>
                </select> 条
        </div>
    </div>

    <div class="box-tools pull-right">
        <ul class="pagination">
            <li>
                <a href="${pageContext.request.contextPath}/orders/findAll.do?page=1&size=${pageInfo.pageSize}" aria-label="Previous">首页</a>
            </li>
            <li><a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageInfo.pageNum-1}&size=${pageInfo.pageSize}">上一页</a>
            </li>

            <c:forEach begin="1" end="${pageInfo.pages}" var="pageNum">
                <li><a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageNum}&size=${pageInfo.pageSize}">${pageNum}</a>
                </li>
            </c:forEach>

           <li><a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageInfo.pageNum+1}&size=${pageInfo.pageSize}">下一页</a></li>
           <li><a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageInfo.pages}&size=${pageInfo.pageSize}" aria-label="Next">尾页</a>
           </li>
        </ul>
    </div>
</div>
<!-- /.box-footer-->

四、总结

  • 在SSM框架下

    1. pom.xml中导入jar包依赖。(2.1)
    2. applicationContext.xml中,对PageHelper进行配置。(2.2.2)
    3. 在真正调用查询方法前,加入静态方法PageHelper.startPage(page, size);。(2.4.3)
    4. 前端页面中,进行设置.(3.4)
Last modification:October 22nd, 2019 at 04:08 pm