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();
}
}