MyBatis使用篇(十一)—— MyBatis实现分页
文章目录
- 1、搭建演示环境
- 1.1 创建数据表
- 1.2 创建实体类
- 1.3 创建接口Dao
- 1.4 创建SQL映射文件
- 1.5 创建测试类
- 2、通过List结果集实现分页
- 2.1 添加接口方法
- 2.2 添加SQL标签
- 2.3 添加测试方法
- 3、通过SQL参数实现分页
- 3.1 添加接口方法
- 3.2 添加SQL标签
- 3.3 添加测试方法
- 4、通过RowBounds实现分页
- 4.1 添加接口方法
- 4.2 添加SQL标签
- 4.3 添加测试方法
- 5、通过插件实现分页
- 5.1 添加依赖jar包
- 5.2 配置分页插件
- 5.3 添加接口方法
- 5.4 添加SQL标签
- 5.5 添加测试方法
1、搭建演示环境
1.1 创建数据表
在mybatis数据库中创建名为“course”的数据表,并在数据表中添加测试数据。建表与插入测试语句的代码如下所示:
SET FOREIGN_KEY_CHECKS=0;-- ----------------------------
-- Table structure for `course`
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (`id` int(255) NOT NULL auto_increment,`no` varchar(255) default NULL,`name` varchar(255) default NULL,`score` int(255) default NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('1', 'C001', '数据结构', '3');
INSERT INTO `course` VALUES ('2', 'C002', '操作系统', '3');
INSERT INTO `course` VALUES ('3', 'C003', '计算机网络', '3');
INSERT INTO `course` VALUES ('4', 'C004', '计算机组成原理', '3');
INSERT INTO `course` VALUES ('5', 'C005', '算法设计与分析', '3');
INSERT INTO `course` VALUES ('6', 'C006', 'C语言程序设计', '3');
INSERT INTO `course` VALUES ('7', 'C007', '数据挖掘', '2');
INSERT INTO `course` VALUES ('8', 'C008', '机器学习', '2');
INSERT INTO `course` VALUES ('9', 'C009', 'Linus操作系统', '2');
INSERT INTO `course` VALUES ('10', 'C010', 'Java程序语言设计', '2');
创建完毕后的数据表如下所示:

1.2 创建实体类
在com.ccff.mybatis.model包下创建名为“Course”的实体类,并为成员变量提供get和set方法以及toString方法,具体代码如下:
package com.ccff.mybatis.model;public class Course {private int id;private String no;private String name;private int score;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getNo() {return no;}public void setNo(String no) {this.no = no;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}@Overridepublic String toString() {return "Course{" +"id=" + id +", no='" + no + '\'' +", name='" + name + '\'' +", score=" + score +'}';}
}
1.3 创建接口Dao
在com.ccff.mybatis.dao包下创建名为“ICourseDao”的空的接口Dao文件,具体代码如下所示:
package com.ccff.mybatis.dao;public interface ICourseDao {
}
1.4 创建SQL映射文件
在config/sqlmap文件夹下创建名为“CourseMapper.xml”的空的SQL映射文件,具体代码如下所示:
<mapper namespace="com.ccff.mybatis.dao.ICourseDao" >
mapper>
创建SQL映射文件完毕后,将该SQL映射文件配置到全局配置文件中的mapper加载路径中,具体配置如下:
<mappers><mapper resource="sqlmap/UserMapper.xml"/><mapper resource="sqlmap/StudentMapper.xml"/><mapper resource="sqlmap/BasketballPlayerMapper.xml"/><mapper resource="sqlmap/FinacialMapper.xml"/><mapper resource="sqlmap/NewsLabelMapper.xml" /><mapper resource="sqlmap/LazyLoadingMapper.xml" /><mapper resource="sqlmap/BookMapper.xml" /><mapper resource="sqlmap/GoodsMapper.xml" /><mapper resource="sqlmap/GamePlayerMapper.xml" /><mapper resource="sqlmap/CourseMapper.xml" />
mappers>
1.5 创建测试类
在com.ccff.mybatis.test包下创建名为“CourseTest”的测试类,具体代码如下:
package com.ccff.mybatis.test;import com.ccff.mybatis.dao.ICourseDao;
import com.ccff.mybatis.datasource.DataConnection;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;import java.io.IOException;public class CourseTest {private SqlSession sqlSession;private ICourseDao courseDao;@Beforepublic void init() {DataConnection dataConnection = new DataConnection();try {sqlSession = dataConnection.getSqlSession();courseDao = sqlSession.getMapper(ICourseDao.class);} catch (IOException e) {e.printStackTrace();}}@Afterpublic void tearDown(){if (sqlSession != null)sqlSession.close();}
}
2、通过List结果集实现分页
通过List结果集实现分页的原理是:将需要分页处理的数据先从数据库中全部取出,然后在List结果集中截取需要的部分。
2.1 添加接口方法
在ICourseDao接口文件中创建名为“getPageCourseByList”的方法,具体代码如下所示:
package com.ccff.mybatis.dao;import com.ccff.mybatis.model.Course;import java.util.List;public interface ICourseDao {//通过List结果集实现分页List<Course> getPageCourseByList();
}
2.2 添加SQL标签
在CourseMapper.xml中添加select标签,具体代码如下所示:
<mapper namespace="com.ccff.mybatis.dao.ICourseDao" ><select id="getPageCourseByList" resultType="Course">select * from courseselect>
mapper>
2.3 添加测试方法
在CourseTest测试类中首先创建名为“pageByList”的分页方法,具体代码如下所示:
/** * @param currPage:当前页号* @param pageSize:当前页总共的记录数* @return 该页的记录的List集合*/
private List<Course> pageByList(int currPage, int pageSize){//查询全部数据List<Course> courses = courseDao.getPageCourseByList();//从第几条数据开始int firstIndex = (currPage-1)*pageSize;//到第几条结束int lastIndex = currPage*pageSize;//直接在List中截取return courses.subList(firstIndex,lastIndex);
}
然后在CourseTest测试类中创建名为“TestGetPageCourseByList”的测试方法测试该分页方法,具体代码如下:
@Test
public void TestGetPageCourseByList(){//总记录共10条。假设总共分为4页,每页最多3条记录System.out.println("===========================第二页记录为:=====================");List<Course> secondPage = pageByList(2,3);for (Course course : secondPage){System.out.println(course);}System.out.println("===========================第四页记录为:=====================");List<Course> lastPage = pageByList(4,1);for (Course course : lastPage){System.out.println(course);}
}
最后,运行该测试方法后,查看控制台输出的日志信息如下,说明分页成功!

3、通过SQL参数实现分页
通过SQL参数实现分页的原理为:通过SQL语句中的limit关键字实现分页查询。limit关键字所需要的参数则由方法通过参数传递的方式给出。
3.1 添加接口方法
在ICourseDao接口文件中创建名为“getPageCourseBySQL”的方法,具体代码如下所示:
package com.ccff.mybatis.dao;import com.ccff.mybatis.model.Course;import java.util.List;
import java.util.Map;public interface ICourseDao {//通过List结果集实现分页List<Course> getPageCourseByList();//通过SQL参数实现分页List<Course> getPageCourseBySQL(Map<String,Object> data);
}
3.2 添加SQL标签
在CourseMapper.xml中添加select标签,具体代码如下所示:
<mapper namespace="com.ccff.mybatis.dao.ICourseDao" ><select id="getPageCourseByList" resultType="Course">select * from courseselect><select id="getPageCourseBySQL" parameterType="map" resultType="Course">select * from course limit #{currIndex} , #{pageSize}select>
mapper>
3.3 添加测试方法
然后在CourseTest测试类中创建名为“TestGetPageCourseBySQL”的测试方法测试该分页方法,具体代码如下:
@Test
public void TestGetPageCourseBySQL(){Map<String,Object> data = new HashMap<>();data.put("currIndex",3);data.put("pageSize",3);List<Course> thirdPage = courseDao.getPageCourseBySQL(data);System.out.println("===========================第三页记录为:=====================");for (Course course : thirdPage){System.out.println(course);}
}
运行该测试方法后,查看控制台输出的日志信息如下,说明分页成功!

4、通过RowBounds实现分页
MyBatis框架本身已经对分页进行了一定程度的支持,它内置了一个专门处理分页的类——RowBounds。其源码如下:
package org.apache.ibatis.session;public class RowBounds {public static final int NO_ROW_OFFSET = 0;public static final int NO_ROW_LIMIT = 2147483647;public static final RowBounds DEFAULT = new RowBounds();private int offset;private int limit;public RowBounds() {this.offset = 0;this.limit = 2147483647;}public RowBounds(int offset, int limit) {this.offset = offset;this.limit = limit;}public int getOffset() {return this.offset;}public int getLimit() {return this.limit;}
}
其中,offset属性时偏移量,即从第几行开始读取记录。limit是限制条数,从源码可知,默认值为0和Java的最大整数(2 147 483 647),使用它十分简单,只要给接口增加一个RowBounds参数即可。
4.1 添加接口方法
在ICourseDao接口文件中创建名为“getPageCourseByRowBounds”的方法,具体代码如下所示:
package com.ccff.mybatis.dao;import com.ccff.mybatis.model.Course;
import org.apache.ibatis.session.RowBounds;import java.util.List;
import java.util.Map;public interface ICourseDao {//通过List结果集实现分页List<Course> getPageCourseByList();//通过SQL参数实现分页List<Course> getPageCourseBySQL(Map<String,Object> data);//通过RowBounds实现分页List<Course> getPageCourseByRowBounds(RowBounds rowBounds);
}
4.2 添加SQL标签
在CourseMapper.xml中添加select标签,具体代码如下所示:
<mapper namespace="com.ccff.mybatis.dao.ICourseDao" ><select id="getPageCourseByList" resultType="Course">select * from courseselect><select id="getPageCourseBySQL" parameterType="map" resultType="Course">select * from course limit #{currIndex} , #{pageSize}select><select id="getPageCourseByRowBounds" resultType="Course">select * from courseselect>
mapper>
在上面的select标签中,并没有任何关于RowBounds参数的信息。因为它是MyBatis的一个附加参数,MyBatis会自动识别它,据此分页。
4.3 添加测试方法
然后在CourseTest测试类中创建名为“TestGetPageCourseByRowBounds”的测试方法测试该分页方法,具体代码如下:
@Test
public void TestGetPageCourseByRowBounds(){RowBounds rowBounds = new RowBounds(0,3);List<Course> firstPage = courseDao.getPageCourseByRowBounds(rowBounds);System.out.println("===========================第一页记录为:=====================");for (Course course : firstPage){System.out.println(course);}
}
运行该测试方法后,查看控制台输出的日志信息如下,说明分页成功!

这里需要注意RowBounds分页应用的场景,它只能应用于一些小数据量的查询。RowBounds分页的原理是执行SQL的查询后,按照偏移量和限制条数返回查询结果(即MyBatis对第一小节介绍的方法的一种实现,无需再重复造轮子),所以对于大数据量的数据查询,它的性能并不佳。此时可以通过分页插件去处理,详情参考下一小节。
5、通过插件实现分页
关于MyBatis中插件的介绍在本系列博客的第十篇《MyBatis使用篇(十)—— MyBatis配置文件详解》中已经有了介绍。
为了不重复造轮子,这里使用了PageHelper分页插件。PageHelper分页插件已经在GitHub上开源,PageHelper的GitHub地址。
5.1 添加依赖jar包
为了正确使用PageHelper分页插件,首先需要在WEB-INF/lib下导入其依赖的两个jar包:pagehelper-5.1.8.jar和jsqlparser-0.9.5.jar,并将其Add As Library。

5.2 配置分页插件
想要在项目中使用PageHelper插件,则需要在全局配置文件中进行配置,具体配置如下:
<configuration><properties resource="jdbc.properties" /><settings><setting name="logImpl" value="LOG4J" /><setting name="lazyLoadingEnabled" value="true"/><setting name="aggressiveLazyLoading" value="true"/>settings><typeAliases><package name="com.ccff.mybatis.model"/>typeAliases><objectFactory type="com.ccff.mybatis.objectFactory.CartObjectFactory"/><plugins><plugin interceptor="com.github.pagehelper.PageInterceptor" />plugins><environments default="development"><environment id="development"><transactionManager type="JDBC" /><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/>dataSource>environment>environments><mappers><mapper resource="sqlmap/UserMapper.xml"/><mapper resource="sqlmap/StudentMapper.xml"/><mapper resource="sqlmap/BasketballPlayerMapper.xml"/><mapper resource="sqlmap/FinacialMapper.xml"/><mapper resource="sqlmap/NewsLabelMapper.xml" /><mapper resource="sqlmap/LazyLoadingMapper.xml" /><mapper resource="sqlmap/BookMapper.xml" /><mapper resource="sqlmap/GoodsMapper.xml" /><mapper resource="sqlmap/GamePlayerMapper.xml" /><mapper resource="sqlmap/CourseMapper.xml" />mappers>
configuration>
这里需要注意一个细节问题,就是关于PageHelper分页插件的版本的选择问题。本博客采用的是当前最新版本5.1.8。当使用4.x版本时,关于PageHelper插件的配置稍有不同,具体修改配置如下:
<plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"><property name="helperDialect" value="mysql"/>plugin>
plugins>
如果使用5.x版本和如上配置则会报错,具体原理请参考:《使用MyBatis分页插件PageHelper遇到的问题》
5.3 添加接口方法
在ICourseDao接口文件中创建名为“getPageCorseByPagePlugin”的方法,具体代码如下所示:
package com.ccff.mybatis.dao;import com.ccff.mybatis.model.Course;
import org.apache.ibatis.session.RowBounds;import java.util.List;
import java.util.Map;public interface ICourseDao {//通过List结果集实现分页List<Course> getPageCourseByList();//通过SQL参数实现分页List<Course> getPageCourseBySQL(Map<String,Object> data);//通过RowBounds实现分页List<Course> getPageCourseByRowBounds(RowBounds rowBounds);//通过分页插件实现分页List<Course> getPageCorseByPagePlugin();
}
5.4 添加SQL标签
在CourseMapper.xml中添加select标签,具体代码如下所示:
<mapper namespace="com.ccff.mybatis.dao.ICourseDao" ><select id="getPageCourseByList" resultType="Course">select * from courseselect><select id="getPageCourseBySQL" parameterType="map" resultType="Course">select * from course limit #{currIndex} , #{pageSize}select><select id="getPageCourseByRowBounds" resultType="Course">select * from courseselect><select id="getPageCorseByPagePlugin" resultType="Course">select * from courseselect>
mapper>
5.5 添加测试方法
然后在CourseTest测试类中创建名为“TestGetPageCorseByPagePlugin”的测试方法测试该分页方法,具体代码如下:
@Test
public void TestGetPageCorseByPagePlugin(){PageHelper.startPage(4,3);List<Course> ForthPage = courseDao.getPageCorseByPagePlugin();System.out.println("===========================第四页记录为:=====================");for (Course course : ForthPage){System.out.println(course);}
}
运行该测试方法后,查看控制台输出的日志信息如下,说明分页成功!

这里仅对PageHelper分页插件做了一个很简单的使用,如果感兴趣可自行查阅相关资料。
《(血和泪的成果)使用PageHelper分页插件进行后台分页》
《Mybatis 的分页插件PageHelper-4.1.1的使用》
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
