GVKun编程网logo

Mybatis分页插件:PageHlper的使用(mybatis分页插件pagehelper)

11

最近很多小伙伴都在问Mybatis分页插件:PageHlper的使用和mybatis分页插件pagehelper这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展MyBaties分页

最近很多小伙伴都在问Mybatis分页插件:PageHlper的使用mybatis分页插件pagehelper这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展MyBaties分页插件PageHelper的简单使用、mybatis pagehelper分页插件使用、MyBatis 分页插件 PageHelper、Mybatis 分页插件 PageHelper 5.0.0 发布等相关知识,下面开始了哦!

本文目录一览:

Mybatis分页插件:PageHlper的使用(mybatis分页插件pagehelper)

Mybatis分页插件:PageHlper的使用(mybatis分页插件pagehelper)

Mybatis分页插件:PageHlper的使用

PageHlper:Mybatis开发的分页插件,简化分页处理,可以把查询数据的一条sql语句自动拦截下来,生成两条分页sql语句
如:

SELECT * FROM 表 WHERE 条件
	Mybatis的PageHlper会拦截上面的sql语句,生成两条sql语句
		SELECT COUNT(*) FROM 表 WHERE 条件
		SELECT * FROM 表 WHERE 条件 LIMIT #{start},#{length}

使用三步骤

一:使用 Pagehlper 设置分页规则

// page:当前页  pageSize:每页大小
pageHelper.startPage(page, pageSize);

二:调用Mapper查询所有用户数据

//根据员工名称查询所有员工信息
List<Employee> employeeList = employeeMapper.findAll(name);

三:实例化PageHlper提供的PageInfo对象,传递所有数据列表

PageInfo<Employee> pageInfo = new PageInfo<>(employeeList);

四、完整代码实现

public R<Page<Employee>> page(Integer page, Integer pageSize, String name) {
	//使用 Pagehlper 设置分页规则
    pageHelper.startPage(page, pageSize);
	//调用Mapper查询所有用户数据
    List<Employee> employeeList = employeeMapper.findAll(name);
	//实例化PageHlper提供的PageInfo对象,传递所有数据列表
    PageInfo<Employee> pageInfo = new PageInfo<>(employeeList);
	//实例化自定义实体类Page对象封装成前端需要的数据类型
    Page<Employee> pageEmployee = new Page<>();
	//封装数据
    pageEmployee.setRecords(pageInfo.getList());
    pageEmployee.setTotal(pageInfo.getTotal());
    pageEmployee.setPage(page);
    pageEmployee.setPageSize(pageSize);
	//返回数据
    return R.success(pageEmployee);
}

MyBaties分页插件PageHelper的简单使用

MyBaties分页插件PageHelper的简单使用

 

抛出问题:

如果想要将现有的select语句改为支持分页功能的查询语句该怎么做呢?
最简单的一种做法就是将所有的select语句都加上limit来实现分页,这种做法有什么问题呢?

有没有一种简便方法实现呢?
Mybatis提供了plugin机制,允许我们在Mybatis的原有处理流程上加入自己逻辑,所有我们就可以使用这种逻辑加上我们的分页逻辑,也就是实现拦截器。
Mybatis支持的拦截的接口有4个,Executor、ParameterHandler、ResultSetHandler、StatementHandler。关于分页拦截器的配置和使用后期我会更新。
 

一、PageHelper的介绍和使用

Mybatis的一个插件,PageHelper,非常方便mybatis分页查询。国内牛人的一个开源项目,有兴趣的可以去看源码。在github上仓库地址为:Mybatis-PageHelper。它支持基本主流与常用的数据库,这可以在它的文档上看到。这里记录一下使用的基本方法。PageHelpe开源地址:
github项目地址:https://github.com/pagehelper/Mybatis-PageHelper
码云 项目地址:http://git.oschina.net/free/Mybatis_PageHelper

 

二、项目配置

首先引入jar包依赖
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>4.1.4</version>
</dependency>

 

在mybatis的全局配置文件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>
    <!-- 配置分页插件 -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库-->        
            <property name="dialect" value="mysql"/>
        </plugin>
    </plugins>
</configuration>

 

三、基本使用

dao层:

public List<User> queryUserListLikeName(@Param("name") String name);

mapper.xml:

<select id="queryUserListLikeName" parameterType="String" resultType="User">
    SELECT * FROM tb_user WHERE name LIKE ''%${name}%''
</select>

service.java
 

public PageInfo<User> testQueryUserListLikeName() {
    //设置分页条件,Parameters:pageNum 页码pageSize 每页显示数量count 是否进行count查询
    PageHelper.startPage(1, 3, true);
    List<User> users = this.userMapper.queryUserListLikeName(null);
    //取分页后结果
    PageInfo<User> pageInfo = new PageInfo<User>(users);
   
    //打印分页信息
    System.out.println("数据总数:" + pageInfo.getTotal());
    System.out.println("数据总页数:" + pageInfo.getPages());
    System.out.println("最后一页:" + pageInfo.getLastPage());
    
    return pageInfo;
}

pageInfo.java


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 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;
 
    public PageInfo() {
    }
 
    /**
     * 包装Page对象
     *
     * @param list
     */
    public PageInfo(List<T> list) {
        this(list, 8);
    }
 
    /**
     * 包装Page对象
     *
     * @param list          page结果
     * @param navigatePages 页码数量
     */
    public PageInfo(List<T> list, int navigatePages) {
        if (list instanceof Page) {
            Page page = (Page) list;
            this.pageNum = page.getPageNum();
            this.pageSize = page.getPageSize();
 
            this.pages = page.getPages();
            this.list = page;
            this.size = page.size();
            this.total = page.getTotal();
            //由于结果是>startRow的,所以实际的需要+1
            if (this.size == 0) {
                this.startRow = 0;
                this.endRow = 0;
            } else {
                this.startRow = page.getStartRow() + 1;
                //计算实际的endRow(最后一页的时候特殊)
                this.endRow = this.startRow - 1 + this.size;
            }
        } else if (list instanceof Collection) {
            this.pageNum = 1;
            this.pageSize = list.size();
 
            this.pages = this.pageSize > 0 ? 1 : 0;
            this.list = list;
            this.size = list.size();
            this.total = list.size();
            this.startRow = 0;
            this.endRow = list.size() > 0 ? list.size() - 1 : 0;
        }
        if (list instanceof Collection) {
            this.navigatePages = navigatePages;
            //计算导航页
            calcNavigatepageNums();
            //计算前后页,第一页,最后一页
            calcPage();
            //判断页面边界
            judgePageBoudary();
        }
    }
 
 
.......
}

注意:

PageHelper 方法使用了静态的 ThreadLocal 参数,分页参数和线程是绑定的。只要你可以保证在 PageHelper 方法调用后紧跟 MyBatis 查询方法,这就是安全的。因为 PageHelper 在 finally 代码段中自动清除了 ThreadLocal 存储的对象。如果代码在进入 Executor 前发生异常,就会导致线程不可用,这属于人为的 Bug(例如接口方法和 XML 中的不匹配,导致找不到 MappedStatement 时), 这种情况由于线程不可用,也不会导致 ThreadLocal 参数被错误的使用。
但是如果你写出下面这样的代码,就是不安全的用法:
PageHelper.startPage(1, 10);
List<Country> list;
if(param1 != null){
    list = countryMapper.selectIf(param1);
} else {
    list = new ArrayList<Country>();
}
这种情况下由于 param1 存在 null 的情况,就会导致 PageHelper 生产了一个分页参数,但是没有被消费,这个参数就会一直保留在这个线程上。当这个线程再次被使用时,就可能导致不该分页的方法去消费这个分页参数,这就产生了莫名其妙的分页。上面这个代码,应该写成下面这个样子:
List<Country> list;
if(param1 != null){
    PageHelper.startPage(1, 10);
    list = countryMapper.selectIf(param1);
} else {
    list = new ArrayList<Country>();
}
这种写法就能保证安全。
如果你对此不放心,你可以手动清理 ThreadLocal 存储的分页参数,可以像下面这样使用:

List<Country> list;
if(param1 != null){
    PageHelper.startPage(1, 10);
    try{
        list = countryMapper.selectAll();
    } finally {
        PageHelper.clearPage();
    }
} else {
    list = new ArrayList<Country>();
}

以上就是PageHelper的基本使用,简单方便的分页插件。

mybatis pagehelper分页插件使用

mybatis pagehelper分页插件使用

使用过mybatis的人都知道,mybatis本身就很小且简单,sql写在xml里,统一管理和优化。缺点当然也有,比如我们使用过程中,要使用到分页,如果用最原始的方式的话,1.查询分页数据,2.获取分页长度,也就是说要使用到两个方法才能完成分页。有没有更更好的分页方式的,pagehelper分页插件因此而诞生,他的原理是利用mybatis拦截器,在查询数据库的时候,拦截下SQL,然后进行修改,从而实现分页(如果你硬是想知道原理,mybatis拦截器,学习过后你就知道什么回事了)。

这篇博客先向大家展示怎么使用,过后有时间再讲他的实现原理。

1.添加maven依赖

1 <dependency>
2   <groupId>com.github.pagehelper</groupId>
3   <artifactId>pagehelper</artifactId>
4   <version>5.0.0</version>
5 </dependency>

2.在 Spring 配置文件中配置拦截器插件,也可以在mybatis的xml里面配置,但是两种配置不能同时出现,否则容易出现com.github.pagehelper.PageInterceptor插件出现空指针问题

在spring.xml中定义:

 1 <!--配置SqlSessionFactory对象 -->
 2     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
 3         <property name="dataSource" ref="dataSource" />
 4         <property name="configLocation" value="classpath:mybatis-config.xml" />
 5         <property name="typeAliasesPackage" value="com.aoChine.model.entity" />
 6         <property name="mapperLocations" value="classpath:mapper/*.xml" />
 7 
 8         <!-- 配置mybatis分页插件PageHelper -->
 9         <property name="plugins">
10             <array>
11                 <bean class="com.github.pagehelper.PageInterceptor">
12                     <property name="properties">
13                         <!-- 什么都不配,使用默认的配置 -->
14                         <value></value>
15                     </property>
16                 </bean>
17             </array>
18         </property>
19     </bean>

在mybatis-config.xml中定义

<plugins>
        <!-- com.github.pagehelper为PageHelper类所在包名 -->
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!-- 使用MySQL方言的分页 -->
            <property name="helperDialect" value="sqlserver"/><!--如果使用mysql,这里value为mysql-->
            <property name="pageSizeZero" value="true"/>
        </plugin>
 </plugins>

3.使用

a)写正常查询语句的接口

接口:

b)在service层调用接口,实现分页。

分页插件使用这样就使用完毕了,博客只是介绍了最简单的使用方法,如果需要了解更多内容

这个是开源社区上面的插件库地址:
https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md
---------------------
作者:我爱奔跑的浮云
来源:CSDN
原文:https://blog.csdn.net/qq_26790807/article/details/62429290

MyBatis 分页插件 PageHelper

MyBatis 分页插件 PageHelper

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">
    <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>
                <!-- 这里的几个配置主要演示如何使用,如果不理解,一定要去掉下面的配置 -->
                <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 5.0.0 发布

Mybatis 分页插件 PageHelper 5.0.0 发布

Mybatis分页插件 - PageHelper PageHelper 5.0.0 发布了。如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件。分页插件支持任何复杂的单表、多表分页,部分特殊情况请看重要提示。想要使用分页插件?请看如何使用分页插件。

该插件目前支持以下数据库的物理分页:

  1. Oracle

  2.  Mysql

  3. MariaDB

  4. SQLite

  5.  Hsqldb

  6. PostgreSQL

  7. DB2

  8. SqlServer(2005,2008)

  9. Informix

  10. H2

  11. SqlServer2012

  12. Derby

使用 PageHelper 你只需要在 classpath 中包含 pagehelper-x.x.x.jar 和 jsqlparser-0.9.5.jar。

如果你使用 Maven,你只需要在 pom.xml 中添加下面的依赖:

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

与分页插件 PageHelper 5.0.0 同时发布的还有 pagehelper-spring-boot-starter。

如果你使用 Spring Boot,你只需要在 pom.xml 中添加下面的依赖:

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

有关 pagehelper-spring-boot-starter 的用法可以参考集成示例 MyBatis-Spring-Boot。

新版分页插件 使用 [QueryInterceptor 规范](https://github.com/pagehelper/Mybatis-PageHelper/blob/master/src/main/java/com/github/pagehelper/QueryInterceptor.java) 处理分页逻辑,与 4.x 版本相比有很大不同,新版逻辑更简单,更方便实现自己的分页逻辑。

5.0.0 更新日志:

  1. 使用 [QueryInterceptor 规范](https://github.com/pagehelper/Mybatis-PageHelper/blob/master/src/main/java/com/github/pagehelper/QueryInterceptor.java) 处理分页逻辑

  2. 新的分页插件拦截器为 `com.github.pagehelper.PageInterceptor`

  3. 新的 `PageHelper` 是一个特殊的 `Dialect` 实现类,以更友好的方式实现了以前的功能

  4. 新的分页插件仅有 `dialect` 一个参数,默认的 `dialect` 实现类为 `PageHelper` 

  5. PageHelper` 仍然支持以前提供的参数,在最新的使用文档中已经全部更新

  6. `PageHelper` 的 `helperDialect` 参数和以前的 `dialect` 功能一样,具体可以看文档的参数说明

  7. 增加了基于纯 `RowBounds` 和 `PageRowBounds` 的分页实现,在 `com.github.pagehelper.dialect.rowbounds` 包中,这是用于作为 `dialect` 参数示例的实现,后面会补充更详细的文档

  8. 去掉了不适合出现在分页插件中的 orderby 功能,以后会提供单独的排序插件

  9. 去掉了 `PageHelper` 中不常用的方法

  10. 新的文档,更新历来更新日志中提到的重要内容,提供英文版本文档

  11. 解决 bug [#149](http://git.oschina.net/free/Mybatis_PageHelper/issues/149)

  12. 所有分页插件抛出的异常改为 PageException

今天关于Mybatis分页插件:PageHlper的使用mybatis分页插件pagehelper的讲解已经结束,谢谢您的阅读,如果想了解更多关于MyBaties分页插件PageHelper的简单使用、mybatis pagehelper分页插件使用、MyBatis 分页插件 PageHelper、Mybatis 分页插件 PageHelper 5.0.0 发布的相关知识,请在本站搜索。

本文标签: