Web API分页

阅读更多
(一)分页类型
逻辑分页(客户端分页):从数据库将所有记录查询出来,客户端截取当前页的数据。
物理分页(数据库端分页):只从数据库中查询当前页的数据。

MyBatis默认的RowBounds采用的是逻辑分页。

  private void skipRows(ResultSet rs, RowBounds rowBounds) throws SQLException {  
    if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {  
      if (rowBounds.getOffset() != RowBounds.NO_ROW_OFFSET) {  
        rs.absolute(rowBounds.getOffset());                      // skip rows by rowBounds.offset
      }  
    } else {  
      for (int i = 0; i < rowBounds.getOffset(); i++) {          // skip row one by one till we hit rowBounds.offset
        rs.next(); 
      }  
    }  
  }


但由于性能的问题,大多数系统都会采用物理分页。

(二)物理分页方式

(1)Offset Pagination
访问API时传递参数limit/offset或pageNumber/pageSize
GET /elements?limit=100&offset=100
  => the client receives the next 100 element.

OFFSET 语句在数据量大的情况下会很慢。
由于排序及数据被修改删除会产生各页结果变化。

Spring Data
/users?size=10&page=2&sort=id,desc

org.springframework.data.web.PageableHandlerMethodArgumentResolver
org.springframework.data.web.SortHandlerMethodArgumentResolver

(2)Keyset Pagination

GET /elements?pageSize=100&uuid=45678

需要额外字段

记录时间字段,date_created或date_modified
GET /elements?pageSize=100&modifiedSince=1504224000
  => the client receives the 100 elements since 1504224000. The last element of the page was modified on 1506816000.

And so on.

同一批登录的大量数据无法比较难实现(时间需要精确到毫秒才行)

(3)Continuation Tokens (aka Cursors)

Timestamp_Offset_Checksum

SELECT * FROM elementTable
WHERE (
  timestampColumn > T 
  OR (timestampColumn = T AND idColumn > I)
)
AND timestampColumn < now()
ORDER BY timestampColumn asc, idColumn asc;


Timestamp + ID,参考:
https://blog.philipphauer.de/web-api-pagination-timestamp-id-continuation-token/

你可能感兴趣的:(Web API分页)