天天看點

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