Mybatis分页插件PageHelper的使用

两种分页方式

物理分页是当今常用的方式,当数据量较小的时候也可以采用逻辑分页

  • 物理分页:例如如MySQL数据库提供了limit关键字,程序员只需要编写带有limit关键字的SQL语句,数据库返回的就是分页结果。
  • 逻辑分页:一次性将数据全部查询出来,用List存储起来,因为List集合有序,在根据索引获取指定范围的数据。

分页插件的必要性

展示数据基本就涉及到分页,若追求效率采用物理分页则每次查询数据都涉及到count查询总数和limit分页,这无疑增加了大量的工作量。对于这种大量的、相似的、非业务逻辑的代码,抽象出公共插件是势在必行的。

Mybatis的分页插件PageHelper

maven依赖

<!-- 分页插件 -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.0.0</version>
</dependency>

在Mybatis的配置文件中配置拦截器插件

特别注意,新版拦截器是 com.github.pagehelper.PageInterceptor。

<?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">
<!-- mybatis的主配置文件 -->
<configuration>
    <!-- 配置分页插件 -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库-->
            <!--<property name="dialect" value="mysql"/>-->
        </plugin>
    </plugins>
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的4个基本信息 -->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis?useUnicode=true&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 配置映射文件的位置 -->
    <mappers>
        <package name="com.dao"></package>
    </mappers>
</configuration>

若为与Spring整合,则如此配置

    <!--配置Mybatis的SessionFactory-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="typeAliasesPackage" value="com.zcc.pojo"/>
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
        <!--配置分页插件的拦截器-->
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <value>
                        </value>
                    </property>
                </bean>
            </array>
        </property>
    </bean>

测试类

public class TEST4 {
    private InputStream in;
    private SqlSession sqlSession;
    private userDao userDao;
    @Before//用于在测试方法执行之前执行
    public void init() throws Exception {
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.获取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取SqlSession对象
        sqlSession = factory.openSession();
        //4.获取dao的代理对象
        userDao = sqlSession.getMapper(userDao.class);
    }
    @After//用于在测试方法执行之后执行
    public void destroy() throws Exception {
        //提交事务
        sqlSession.commit();
        //6.释放资源
        sqlSession.close();
        in.close();
    }
    @Test
    public void save() {
        //额外在保存50个用户
        for (int i = 0; i < 50; i++) {
            User user = new User();
            user.setUsername("TEST" + i);
            user.setAddress("北京市");
            user.setSex("男");
            user.setBirthday(new Date());
            //执行方法
            userDao.saveUser(user);
        }
    }
    @Test
    public void demo1() {
        //分页查询,拦截器进行拦截
        //第三种,Mapper接口方式的调用,推荐这种使用方式。
        PageHelper.offsetPage(0, 5);
        List<User> users = userDao.listUser();
        PageInfo page = new PageInfo(users);
        for (User u : users) {
            System.out.println(u.toString());
        }
        //获取总页数
        System.out.println(page.getPages());
        //判断是否还有下一页
        System.out.println(page.isHasNextPage());
    }
}

PageHelper是一个拦截器,在需要的地方使用PageHelper后,Mybatis会在原SQL语句的基础上去执行count和分页操作,如上例的demo1()。运行结果如下

PageHelper执行分页的方式有多种,可以去官方文档中查看,除此之外还有一个类PageInfo很重要,PageInfo包含了非常全面关于数据的分页信息。

public class PageInfo<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    //当前页
    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 int nextPage;
    //最后一页
    private int lastPage;
    //是否为第一页
    private boolean isFirstPage = false;
    //是否为最后一页
    private boolean isLastPage = false;
    //是否有前一页
    private boolean hasPreviousPage = false;
    //是否有下一页
    private boolean hasNextPage = false;
    //导航页码数
    private int navigatePages;
    //所有导航页号
    private int[] navigatepageNums; 
    ...
}

相关链接:

PageHelper的开源地址:
https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

其他
http://www.360doc.com/content/15/0728/15/12642656_487954693.shtml
http://www.ciphermagic.cn/mybatis-page-2.html

https://juejin.im/post/5e36b3395188254dbf1d6a12

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论