您的位置:首页 > 编程语言

MyBatis代码实例系列-10:MyBatis通过PageHelper插件实现分页查询

2018-02-04 19:40 1316 查看
超级通道:MyBatis代码实例系列-绪论

本章主要记录MyBatis通过PageHelper插件实现分页查询,涉及到的技术点有:

- com.github.pagehelper:开源的MyBatis分页插件

com.github.pagehelper是一款开源的MyBatis分页插件,地址是:https://github.com/pagehelper/Mybatis-PageHelper

1.SQL

drop table apple;
create table `apple`(
`id` int(4) unsigned auto_increment not null comment '苹果种类id',
`name` varchar(20) not null comment '苹果种类名称',
`price` int(3) not null comment '价格',
primary key(id)
)engine=InnoDB comment='苹果种类' auto_increment=1001 default charset=utf8;
insert into `apple`(name,price) values('红富士',10);
insert into `apple`(name,price) values('赤富士',10);
insert into `apple`(name,price) values('橙富士',10);
insert into `apple`(name,price) values('蓝富士',10);
insert into `apple`(name,price) values('绿富士',10);
insert into `apple`(name,price) values('青富士',10);
insert into `apple`(name,price) values('靛富士',10);
insert into `apple`(name,price) values('紫富士',10);
insert into `apple`(name,price) values('黄元帅',20);
insert into `apple`(name,price) values('红元帅',20);
insert into `apple`(name,price) values('橙元帅',20);
insert into `apple`(name,price) values('蓝元帅',20);
insert into `apple`(name,price) values('青元帅',20);
insert into `apple`(name,price) values('紫元帅',20);
insert into `apple`(name,price) values('靛元帅',20);
insert into `apple`(name,price) values('绿元帅',20);
insert into `apple`(name,price) values('紫元帅',20);
insert into `apple`(name,price) values('黑元帅',20);
insert into `apple`(name,price) values('红将军',30);
insert into `apple`(name,price) values('赤将军',30);
insert into `apple`(name,price) values('橙将军',30);
insert into `apple`(name,price) values('蓝将军',30);
insert into `apple`(name,price) values('绿将军',30);
insert into `apple`(name,price) values('青将军',30);
insert into `apple`(name,price) values('靛将军',30);
insert into `apple`(name,price) values('紫将军',30);
select count(*) from `apple`;
select * from `apple`;


2.配置PageHelper插件

2.1.引入jar包

我使用的是Maven方式,pom.xml如下:

<pagehelper.version>5.1.2</pagehelper.version>

<!--分页插件-->
<!--https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency>


2.2.配置拦截器:PageInterceptor

目前有两种方式:

在 MyBatis 配置文件中配置拦截器插件

<!--
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>


在 Spring 配置文件中配置拦截器插件

<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>


详细的参数有很多,如果感兴趣可以自己参考:

https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

我采用的是第一种方式,我的配置如下:

<plugins>
<!--https://github.com/pagehelper/Mybatis-PageHelper-->
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!--指定数据库连接类型,此属性可以自动检测,不配置也可以-->
<property name="helperDialect" value="mysql"/>
<!--pageSize=0时,是否查询出全部结果,默认为false-->
<property name="pageSizeZero" value="true"/>
<!--分页合理化参数,默认文false;pageNum<=0,查询第一页;pageNum>总页数,查询最后一页-->
<property name="reasonable" value="true"/>
</plugin>
</plugins>


3.使用PageHelper插件

3.1.通过MyBatis Generator生成代码

可以参考:

MyBatis代码实例系列-08:通过Maven运行 MyBatis Generator,以及MyBatis Generator的扩展用法—生成中文注释和Mapper重命名为Dao

生成结果如下:

AppleEntity.java

package pers.hanchao.himybatis.page.entity;

public class AppleEntity {
/**
* <pre>
* 苹果种类id
* 表字段 : apple.id
* </pre>
*/
private Integer id;

//other field

//setter getter toString hashCode equals
}


AppleDao.java

package pers.hanchao.himybatis.page.dao;

import java.util.List;
import pers.hanchao.himybatis.page.entity.AppleEntity;

public interface AppleDao {
/**
* 根据主键删除数据库的记录
*
* @param id
*/
int deleteByPrimaryKey(Integer id);

//int insert(Apple apple);
//Topic selectByPrimaryKey(Integer id);
//List<Topic> selectAll();
//int updateByPrimaryKey(Apple apple);
}


AppleDao.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pers.hanchao.himybatis.page.dao.AppleDao">
<resultMap id="BaseResultMap" type="pers.hanchao.himybatis.page.entity.AppleEntity">
<!--
@mbggenerated
-->
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="price" jdbcType="INTEGER" property="price" />
</resultMap>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
<!--
@mbggenerated
-->
delete from apple
where id = #{id,jdbcType=INTEGER}
</delete>
<!--
<insert id="insert" ...
<update id="updateByPrimaryKey" ...
<select id="selectByPrimaryKey" ...
<select id="selectAll" ...
-->
</mapper>


3.2.业务代码AppleApp.java

直接进行查询,则查询结果不是分页的,是全部结果

在原来的查询之前,添加
PageHelper.startPage(1,5);
即可完成分页。

AppleApp.java

package pers.hanchao.himybatis.page;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;
import pers.hanchao.himybatis.page.dao.AppleDao;
import pers.hanchao.himybatis.page.entity.AppleEntity;

import java.io.IOException;
import java.io.Reader;
import java.util.List;

/**
* <p>分页组件PageHelper实例</p>
* @author hanchao 2018/2/4 18:23
**/
public class AppleApp {
/** 日志 */
private static final Logger LOGGER = Logger.getLogger(AppleApp.class);
/** 配置文件读取器 */
private static Reader reader;
/** 会话工厂 */
private static SqlSessionFactory sqlSessionFactory;

static {
try {
reader = Resources.getResourceAsReader("mybatis-config-page.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("读取MyBatis配置文件失败!");
}
}
/**
* <p>分页组件PageHelper实例</p>
* @author hanchao 2018/2/4 18:22
**/
public static void main(String[] args) {
SqlSession sqlSession =  sqlSessionFactory.openSession();
try {
AppleDao appleDao = sqlSession.getMapper(AppleDao.class);
LOGGER.info("不加分页的查询:");
LOGGER.info(appleDao.selectAll());

System.out.println();
LOGGER.info("添加分页的查询:");
LOGGER.info("第1页,共5条");
PageHelper.startPage(1,5);
//打印Page<E>本身的信息
LOGGER.info(appleDao.selectAll());
//打印Page<E>的元素信息
LOGGER.info((List<AppleEntity>)appleDao.selectAll());

System.out.println();
LOGGER.info("第2页,共5条");
PageHelper.startPage(2,5);
//打印Page<E>本身的信息
LOGGER.info(appleDao.selectAll());
//打印Page<E>的元素信息
LOGGER.info((List<AppleEntity>)appleDao.selectAll());

System.out.println();
LOGGER.info("第1页,共2条");
PageHelper.startPage(1,2);
//打印Page<E>本身的信息
LOGGER.info(appleDao.selectAll());
//打印Page<E>的元素信息
LOGGER.info((List<AppleEntity>)appleDao.selectAll());

//sqlSession.commit();
}catch (Exception e){
sqlSession.rollback();
e.printStackTrace();
LOGGER.error("数据库操作失败!");
}finally {
sqlSession.close();
}

}
}


3.3.result

2018-02-04 18:39:07 INFO  AppleApp:46 - 不加分页的查询:
2018-02-04 18:39:07 DEBUG JdbcTransaction:137 - Opening JDBC Connection
2018-02-04 18:39:08 DEBUG PooledDataSource:406 - Created connection 1752203484.
2018-02-04 18:39:08 DEBUG JdbcTransaction:101 - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@687080dc]
2018-02-04 18:39:08 DEBUG selectAll:159 - ==>  Preparing: select id, name, price from apple
2018-02-04 18:39:08 DEBUG selectAll:159 - ==> Parameters:
2018-02-04 18:39:08 DEBUG selectAll:159 - <==      Total: 26
2018-02-04 18:39:08 INFO  AppleApp:47 - [AppleEntity [Hash = 990045553, id=1001, name=红富士, price=10], AppleEntity [Hash = 1102596912, id=1002, name=赤富士, price=10], AppleEntity [Hash = 835342812, id=1003, name=橙富士, price=10], AppleEntity [Hash = 1037565081, id=1004, name=蓝富士, price=10], AppleEntity [Hash = 992819960, id=1005, name=绿富士, price=10], AppleEntity [Hash = 1178329478, id=1006, name=青富士, price=10], AppleEntity [Hash = 1178598558, id=1007, name=靛富士, price=10], AppleEntity [Hash = 978880655, id=1008, name=紫富士, price=10], AppleEntity [Hash = 1232562686, id=1009, name=黄元帅, price=20], AppleEntity [Hash = 987502881, id=1010, name=红元帅, price=20], AppleEntity [Hash = 832799179, id=1011, name=橙元帅, price=20], AppleEntity [Hash = 1035021448, id=1012, name=蓝元帅, price=20], AppleEntity [Hash = 1175784884, id=1013, name=青元帅, price=20], AppleEntity [Hash = 976335100, id=1014, name=紫元帅, price=20], AppleEntity [Hash = 1176054925, id=1015, name=靛元帅, price=20], AppleEntity [Hash = 990279210, id=1016, name=绿元帅, price=20], AppleEntity [Hash = 976337983, id=1017, name=紫元帅, price=20], AppleEntity [Hash = 1232958618, id=1018, name=黑元帅, price=20], AppleEntity [Hash = 990060577, id=1019, name=红将军, price=30], AppleEntity [Hash = 1102611936, id=1020, name=赤将军, price=30], AppleEntity [Hash = 835357836, id=1021, name=橙将军, price=30], AppleEntity [Hash = 1037580105, id=1022, name=蓝将军, price=30], AppleEntity [Hash = 992834984, id=1023, name=绿将军, price=30], AppleEntity [Hash = 1178344502, id=1024, name=青将军, price=30], AppleEntity [Hash = 1178613582, id=1025, name=靛将军, price=30], AppleEntity [Hash = 978895679, id=1026, name=紫将军, price=30]]

2018-02-04 18:39:08 INFO  AppleApp:50 - 添加分页的查询:
2018-02-04 18:39:08 INFO  AppleApp:51 - 第1页,共5条
2018-02-04 18:39:08 DEBUG SQL_CACHE:54 - Cache Hit Ratio [SQL_CACHE]: 0.0
2018-02-04 18:39:08 DEBUG selectAll_COUNT:159 - ==>  Preparing: SELECT count(0) FROM apple
2018-02-04 18:39:08 DEBUG selectAll_COUNT:159 - ==> Parameters:
2018-02-04 18:39:08 DEBUG selectAll_COUNT:159 - <==      Total: 1
2018-02-04 18:39:08 DEBUG selectAll:159 - ==>  Preparing: select id, name, price from apple LIMIT ?
2018-02-04 18:39:08 DEBUG selectAll:159 - ==> Parameters: 5(Integer)
2018-02-04 18:39:08 DEBUG selectAll:159 - <==      Total: 5
2018-02-04 18:39:08 INFO  AppleApp:54 - Page{count=true, pageNum=1, pageSize=5, startRow=0, endRow=5, total=26, pages=6, reasonable=true, pageSizeZero=true}
2018-02-04 18:39:08 INFO  AppleApp:56 - [AppleEntity [Hash = 990045553, id=1001, name=红富士, price=10], AppleEntity [Hash = 1102596912, id=1002, name=赤富士, price=10], AppleEntity [Hash = 835342812, id=1003, name=橙富士, price=10], AppleEntity [Hash = 1037565081, id=1004, name=蓝富士, price=10], AppleEntity [Hash = 992819960, id=1005, name=绿富士, price=10], AppleEntity [Hash = 1178329478, id=1006, name=青富士, price=10], AppleEntity [Hash = 1178598558, id=1007, name=靛富士, price=10], AppleEntity [Hash = 978880655, id=1008, name=紫富士, price=10], AppleEntity [Hash = 1232562686, id=1009, name=黄元帅, price=20], AppleEntity [Hash = 987502881, id=1010, name=红元帅, price=20], AppleEntity [Hash = 832799179, id=1011, name=橙元帅, price=20], AppleEntity [Hash = 1035021448, id=1012, name=蓝元帅, price=20], AppleEntity [Hash = 1175784884, id=1013, name=青元帅, price=20], AppleEntity [Hash = 976335100, id=1014, name=紫元帅, price=20], AppleEntity [Hash = 1176054925, id=1015, name=靛元帅, price=20], AppleEntity [Hash = 990279210, id=1016, name=绿元帅, price=20], AppleEntity [Hash = 976337983, id=1017, name=紫元帅, price=20], AppleEntity [Hash = 1232958618, id=1018, name=黑元帅, price=20], AppleEntity [Hash = 990060577, id=1019, name=红将军, price=30], AppleEntity [Hash = 1102611936, id=1020, name=赤将军, price=30], AppleEntity [Hash = 835357836, id=1021, name=橙将军, price=30], AppleEntity [Hash = 1037580105, id=1022, name=蓝将军, price=30], AppleEntity [Hash = 992834984, id=1023, name=绿将军, price=30], AppleEntity [Hash = 1178344502, id=1024, name=青将军, price=30], AppleEntity [Hash = 1178613582, id=1025, name=靛将军, price=30], AppleEntity [Hash = 978895679, id=1026, name=紫将军, price=30]]

2018-02-04 18:39:08 INFO  AppleApp:60 - 第2页,共5条
2018-02-04 18:39:08 DEBUG SQL_CACHE:54 - Cache Hit Ratio [SQL_CACHE]: 0.5
2018-02-04 18:39:08 DEBUG selectAll:159 - ==>  Preparing: select id, name, price from apple LIMIT ?, ?
2018-02-04 18:39:08 DEBUG selectAll:159 - ==> Parameters: 5(Integer), 5(Integer)
2018-02-04 18:39:08 DEBUG selectAll:159 - <==      Total: 5
2018-02-04 18:39:08 INFO  AppleApp:63 - Page{count=true, pageNum=2, pageSize=5, startRow=5, endRow=10, total=26, pages=6, reasonable=true, pageSizeZero=true}
2018-02-04 18:39:08 INFO  AppleApp:65 - [AppleEntity [Hash = 990045553, id=1001, name=红富士, price=10], AppleEntity [Hash = 1102596912, id=1002, name=赤富士, price=10], AppleEntity [Hash = 835342812, id=1003, name=橙富士, price=10], AppleEntity [Hash = 1037565081, id=1004, name=蓝富士, price=10], AppleEntity [Hash = 992819960, id=1005, name=绿富士, price=10], AppleEntity [Hash = 1178329478, id=1006, name=青富士, price=10], AppleEntity [Hash = 1178598558, id=1007, name=靛富士, price=10], AppleEntity [Hash = 978880655, id=1008, name=紫富士, price=10], AppleEntity [Hash = 1232562686, id=1009, name=黄元帅, price=20], AppleEntity [Hash = 987502881, id=1010, name=红元帅, price=20], AppleEntity [Hash = 832799179, id=1011, name=橙元帅, price=20], AppleEntity [Hash = 1035021448, id=1012, name=蓝元帅, price=20], AppleEntity [Hash = 1175784884, id=1013, name=青元帅, price=20], AppleEntity [Hash = 976335100, id=1014, name=紫元帅, price=20], AppleEntity [Hash = 1176054925, id=1015, name=靛元帅, price=20], AppleEntity [Hash = 990279210, id=1016, name=绿元帅, price=20], AppleEntity [Hash = 976337983, id=1017, name=紫元帅, price=20], AppleEntity [Hash = 1232958618, id=1018, name=黑元帅, price=20], AppleEntity [Hash = 990060577, id=1019, name=红将军, price=30], AppleEntity [Hash = 1102611936, id=1020, name=赤将军, price=30], AppleEntity [Hash = 835357836, id=1021, name=橙将军, price=30], AppleEntity [Hash = 1037580105, id=1022, name=蓝将军, price=30], AppleEntity [Hash = 992834984, id=1023, name=绿将军, price=30], AppleEntity [Hash = 1178344502, id=1024, name=青将军, price=30], AppleEntity [Hash = 1178613582, id=1025, name=靛将军, price=30], AppleEntity [Hash = 978895679, id=1026, name=紫将军, price=30]]

2018-02-04 18:39:08 INFO  AppleApp:69 - 第1页,共2条
2018-02-04 18:39:08 DEBUG SQL_CACHE:54 - Cache Hit Ratio [SQL_CACHE]: 0.6666666666666666
2018-02-04 18:39:08 DEBUG selectAll:159 - ==>  Preparing: select id, name, price from apple LIMIT ?
2018-02-04 18:39:08 DEBUG selectAll:159 - ==> Parameters: 2(Integer)
2018-02-04 18:39:08 DEBUG selectAll:159 - <==      Total: 2
2018-02-04 18:39:08 INFO  AppleApp:72 - Page{count=true, pageNum=1, pageSize=2, startRow=0, endRow=2, total=26, pages=13, reasonable=true, pageSizeZero=true}
2018-02-04 18:39:08 INFO  AppleApp:74 - [AppleEntity [Hash = 990045553, id=1001, name=红富士, price=10], AppleEntity [Hash = 1102596912, id=1002, name=赤富士, price=10], AppleEntity [Hash = 835342812, id=1003, name=橙富士, price=10], AppleEntity [Hash = 1037565081, id=1004, name=蓝富士, price=10], AppleEntity [Hash = 992819960, id=1005, name=绿富士, price=10], AppleEntity [Hash = 1178329478, id=1006, name=青富士, price=10], AppleEntity [Hash = 1178598558, id=1007, name=靛富士, price=10], AppleEntity [Hash = 978880655, id=1008, name=紫富士, price=10], AppleEntity [Hash = 1232562686, id=1009, name=黄元帅, price=20], AppleEntity [Hash = 987502881, id=1010, name=红元帅, price=20], AppleEntity [Hash = 832799179, id=1011, name=橙元帅, price=20], AppleEntity [Hash = 1035021448, id=1012, name=蓝元帅, price=20], AppleEntity [Hash = 1175784884, id=1013, name=青元帅, price=20], AppleEntity [Hash = 976335100, id=1014, name=紫元帅, price=20], AppleEntity [Hash = 1176054925, id=1015, name=靛元帅, price=20], AppleEntity [Hash = 990279210, id=1016, name=绿元帅, price=20], AppleEntity [Hash = 976337983, id=1017, name=紫元帅, price=20], AppleEntity [Hash = 1232958618, id=1018, name=黑元帅, price=20], AppleEntity [Hash = 990060577, id=1019, name=红将军, price=30], AppleEntity [Hash = 1102611936, id=1020, name=赤将军, price=30], AppleEntity [Hash = 835357836, id=1021, name=橙将军, price=30], AppleEntity [Hash = 1037580105, id=1022, name=蓝将军, price=30], AppleEntity [Hash = 992834984, id=1023, name=绿将军, price=30], AppleEntity [Hash = 1178344502, id=1024, name=青将军, price=30], AppleEntity [Hash = 1178613582, id=1025, name=靛将军, price=30], AppleEntity [Hash = 978895679, id=1026, name=紫将军, price=30]]
2018-02-04 18:39:08 DEBUG JdbcTransaction:123 - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@687080dc]
2018-02-04 18:39:08 DEBUG JdbcTransaction:91 - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@687080dc]
2018-02-04 18:39:08 DEBUG PooledDataSource:363 - Returned connection 1752203484 to pool.


4.关于PageHelper插件

4.1.配置与使用三部曲

pom.xml引入jar包:com.github.pagehelper.pagehelper

MyBatis配置文件配置分页拦截器:com.github.pagehelper.PageInterceptor

业务代码中,在需要分页的查询前,开启分页:PageHelper.startPage(1,5)

4.2.PageHelper安全调用

PageHelper 方法使用了静态的 ThreadLocal 参数,分页参数和线程是绑定的。

只要你可以保证在 PageHelper 方法调用后紧跟 MyBatis 查询方法,就是安全的,因为PageHelper 在 finally 代码段中自动清除了 ThreadLocal 存储的对象。

如果只是调用PageHelper分页方法,而不执行MyBatis查询,则不安全。

不安全做法

//这里设置了分页参数
PageHelper.startPage(1, 10);
List<Country> list;
//如果param1 == null,则后面代码不会进行MyBatis查询,这是不安全的!
if(param1 != null){
list = countryMapper.selectIf(param1);
} else {
list = new ArrayList<Country>();
}


安全做法

List<Country> list;
//将分页参数设置和MyBatis查询放在同一逻辑分支中,这是安全的!
if(param1 != null){
PageHelper.startPage(1, 10);
list = countryMapper.selectIf(param1);
} else {
list = new ArrayList<Country>();
}


4.3.PageHelper其他注意事项

PageHelper查询的结果都是
Page<E>
,需要手动进行类型转换。

只有紧跟在PageHelper.startPage方法后的第一个Mybatis的查询(Select)方法会被分页。

PageHelper插件不支持带有for update语句的分页。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  MyBatis PageHelper Page