天天看点

MyBatis之分页查询

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>      

数据库申诉局

MyBatis之分页查询
@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();
        }
    }      
MyBatis之分页查询

原理

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();
        }
    }      
上一篇: 排序与分页