美文网首页JavaJava 杂谈Java学习笔记
MyBatis 分页插件 PageHelper 入门介绍

MyBatis 分页插件 PageHelper 入门介绍

作者: 老亨瑞炸酱面 | 来源:发表于2019-06-13 08:07 被阅读22次

    1.简介

    官网:https://pagehelper.github.io/
    PageHelper可以说是目前最流行的MyBatis分页插件了,它使用起来非常简单且提供一整套的解决方案。以下,我们以传统Spring项目为例,介绍如何进行使用。SpringBoot的配置十分简单,可以直接参照项目:https://github.com/abel533/MyBatis-Spring-Boot

    2.配置

    以下内容摘自 https://pagehelper.github.io/docs/howtouse/

    2.1.jar

    如果项目不使用maven,可以下载下面的jar添加到classpath中:

    https://oss.sonatype.org/content/repositories/releases/com/github/pagehelper/pagehelper/
    http://repo1.maven.org/maven2/com/github/pagehelper/pagehelper/
    http://repo1.maven.org/maven2/com/github/jsqlparser/jsqlparser/0.9.5/

    如果使用 Maven,则可以使用下面的方式:

    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>5.1.4</version>
    </dependency>
    

    注意:SpringBoot 项目不是引用这个依赖,具体请参照我上面给出的参照项目。

    2.2.配置拦截器插件

    2.2.1.在 MyBatis 配置 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 配置文件中配置拦截器插件

    我们可以使用 spring 的属性配置方式,其官网示例中这样配置:

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations">
            <array>
                <value>classpath:mapper/*.xml</value>
            </array>
        </property>
        <property name="typeAliasesPackage" value="com.isea533.mybatis.model"/>
        <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>
                    </property>
                </bean>
            </array>
        </property>
    </bean>
    

    各项配置的含义可以参照:
    https://pagehelper.github.io/docs/howtouse/#3-%E5%88%86%E9%A1%B5%E6%8F%92%E4%BB%B6%E5%8F%82%E6%95%B0%E4%BB%8B%E7%BB%8D

    3.使用方式

    3.1.service层分页

    PageHelper的最大优势就在于其使用方便,在需要分页的时候,我们只需要在调用mapper层前面这样写即可:

    //分页查询

    PageHelper.startPage(pageNum, pageSize);
    return mapper.selectByExample(example);
    

    建议只使用startPage的方式,不使用其他方式。这个函数的源码如下:

    /**
     * 开始分页
     *
     * @param pageNum  页码
     * @param pageSize 每页显示数量
     */
    public static <E> Page<E> startPage(int pageNum, int pageSize) {
        return startPage(pageNum, pageSize, DEFAULT_COUNT);
    }
    

    3.2.controller层分页对象

    当我们返回分页结果给前台时,不能只返回结果,需要使用PageHelper提供的包装类。具体使用的方式如下:

    List<Country> countryList = countryService.selectByCountry(country, page, rows);
    result.addObject("pageInfo", new PageInfo<Country>(countryList));
    

    这里提到了PageInfo对象,准确说是泛型。它有哪些属性呢?源码中给出了以下可以使用的属性:

    //当前页
    private int pageNum;
    //每页的数量
    private int pageSize;
    //当前页的数量
    private int size;
    
    //由于startRow和endRow不常用,这里说个具体的用法
    //可以在页面中"显示startRow到endRow 共size条数据"
    
    //当前页面第一个元素在数据库中的行号
    private int startRow;
    //当前页面最后一个元素在数据库中的行号
    private int endRow;
    //总页数
    private int pages;
    
    //前一页
    private int prePage;
    //下一页
    private int nextPage;
    
    //是否为第一页
    private boolean isFirstPage = false;
    //是否为最后一页
    private boolean isLastPage = false;
    //是否有前一页
    private boolean hasPreviousPage = false;
    //是否有下一页
    private boolean hasNextPage = false;
    //导航页码数
    private int navigatePages;
    //所有导航页号
    private int[] navigatepageNums;
    //导航条上的第一页
    private int navigateFirstPage;
    //导航条上的最后一页
    private int navigateLastPage;
    

    由于这里面的属性已经很全了,所以基本上我们不需要添加。如果需要其中的某些值,只需要调用相应的get方法即可。

    4.安全提醒

    某些操作可能导致该插件无法正常使用,请认证阅读以下重要提示:
    · 只有紧跟在PageHelper.startPage方法后的第一个Mybatis的查询(Select)方法会被分页。
    · 请不要在系统中配置多个分页插件(使用Spring时,mybatis-config.xml和Spring<bean>配置方式,请选择其中一种,不要同时配置多个分页插件)!
    · 分页插件不支持带有for update语句的分页。对于带有for update的sql,会抛出运行时异常,对于这样的sql建议手动分页,毕竟这样的sql需要重视。可能大部分人和我一样不懂是什么语句,类似这样的句子: select * from shortlink where long_url = 'long2' for update; 这类语句是为了给某些行上锁的。
    · 由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。啥是嵌套结果呢?下面有个例子:

    <resultMap type="Goods" id="goodsMap">
                <id column="g_id" property="id"/>
                <result column="goodsName" property="goodsName"/>
                <result column="goodsNumber" property="goodsNumber"/>
                <result column="user_id" property="user_id"/>
    </resultMap>
             
     <resultMap type="User"  id="userMap">
                <id column="u_id" property="id" />
                <result column="username" property="username" />
                <result column="age" property="age" />
                <result column="address" property="address" />
                <collection property="goodsList" ofType="Goods" resultMap="goodsMap" />        
    </resultMap>
    
            <select id="getUserinfoById" parameterType="int" resultMap="userMap">
                select
                    u.id as u_id,
                    u.username,
                    u.age,
                    u.address,
                    g.id as g_id,
                    g.goodsName,
                    g.goodsNumber,
                    g.user_id
                 from
                    user u
                    inner join goods g on u.id = g.user_id
                 where
                    u.id =${value};
            </select> 
    

    相关文章

      网友评论

        本文标题:MyBatis 分页插件 PageHelper 入门介绍

        本文链接:https://www.haomeiwen.com/subject/gindfctx.html