1.逻辑分页
1.逻辑分页主要是指,查询所有的数据,然后我们从内存中,筛选对应的分页信息;
2.MyBatis 里面有一个逻辑分页对象 RowBounds,里面主要有两个属性,offset 和limit(从第几条开始,查询多少条)。
3.可以在 Mapper 接口的方法上加上这个参数,不需要修改 xml 里面的 SQL 语句,如下selectBlogList方法。
如:
BlogMapper.java方法
public List<Blog> selectBlogList(RowBounds rowBounds);
BlogMapper.xml
<select id="selectBlogList" resultMap="BaseResultMap" >
select bid, name, author_id authorId from blog
</select>
数据库申诉局

@Test
public void testSelectByRowBounds() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
try {
BlogMapper mapper = session.getMapper(BlogMapper.class);
int start = 0; // offset 从第几行开始查询
int pageSize = 5; // limit 查询多少条
RowBounds rb = new RowBounds(start, pageSize);
List<Blog> list = mapper.selectBlogList(rb); // 使用逻辑分页
for(Blog b :list){
System.out.println(b);
}
} finally {
session.close();
}
}
原理
DefaultResultSetHandler.handleRowValuesForSimpleResultMap
private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping)
throws SQLException {
DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
ResultSet resultSet = rsw.getResultSet();
skipRows(resultSet, rowBounds);
while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) {
ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
Object rowValue = getRowValue(rsw, discriminatedResultMap, null);
storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
}
}
1.它的底层其实是对 ResultSet 的处理。 它会舍弃掉前面 offset 条数据,然后再取剩下的数据的 limit 条;
2.很明显,如果数据量大的话,这种翻页方式效率会很低(跟查询到内存中再使用subList(start,end)没什么区别)。 所以我们要用到物理翻页
2.物理分页
2.1.方式一:手动在SQL中编写
1.传入参数(或者包装一个 page 对象),在 SQL 语句中翻页。
<select id="selectBlogPage" parameterType="map" resultMap="BaseResultMap">
select * from blog limit #{curIndex} , #{pageSize}
</select>
1.起止序列号需要java程序计算;
2.每个需要翻页的 Statement 都要编写 limit 语句,会造成 Mapper 映射器里面很多代码冗余。
2.2.方式二:插件-pageHelper
2.2.1.pom.xml中引入pageHelper的版本
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
2.2.2.mybatis-config.xml配置pageHelper的plugin拦截器
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 使用下面的方式配置参数,后面会有所有的参数介绍
详细配置参考
https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md
-->
<!-- <property name="param1" value="value1"/>-->
</plugin>
</plugins>
2.2.3.BlogMapper.xml
<select id="selectBlogAll" resultMap="BaseResultMap" >
select bid, name, author_id authorId from blog
</select>
2.2.4.BlogMapper.java
public List<Blog> selectBlogAll();
2.2.5.单元测试
@Test
public void testSelectByPageHelper() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
try {
PageHelper.startPage(1,3);//第1行开始,前三行
BlogMapper mapper = session.getMapper(BlogMapper.class);
List<Blog> list = mapper.selectBlogAll();
for(Blog b :list){
System.out.println(b);
}
} finally {
session.close();
}
}