分页获取数据

php 版本——未经测试,仅做参考

  • 使用时,继承此类并实现对应方法

      <?php
      /**
       *
       * 适用于redis + db 的存储形式,存储数据为按一定规则排序的id列表,适用于:
       * 缓存中的key使用sorted set, 且设置过期时间而非持久化存储
       * 分页获取数据时按排序的值, 即cursor->score来获取:获取比cursor->score小【或大】的length条数据
       *
       * 使用场景如:
       * 文章按发布时间排序,按评论数排序,按点赞数排序
       *
       * User: xjyin
       * Date: 15/11/5
       * Time: 下午7:45
       */
    
      class Cursor {
    
          private $member;
    
          private $score;
      }
    
      abstract class CursorTimelineGetter {
    
          private $cursor;
    
          private $length;
    
          function _construct($cursor, $length) {
              $this->cursor = $cursor;
              $this->length = $length;
          }
    
          // 返回数据为cursor的array, 长度可能会小于$length
          abstract protected function getFromCache($cursor, $length);
    
          // 返回数据为cursor的array, 长度可能会小于$length
          abstract protected function getFromDB($cursor, $length);
    
          // 将从数据库中获取到的数据放到缓存, dbResults 为cursor 的array
          abstract protected function saveToCache($dbResults);
    
          // 将不够的数据补到缓存中,否则将会造成数据丢失
          // 在实现此方法时用zAdd(key, map)的方式,避免循环调用单个member 的zAdd
          abstract protected function patchToCache($cursor);
    
          public function exec() {
              $cacheResults = $this->getFromCache($this->cursor, $this->length);
              if(!$cacheResults) {
                  $cacheResults = array();
              }
              // 若缓存中已经获取到所有分页数据,则直接返回
              if(count($cacheResults) >= $this->length) {
                  return $cacheResults;
              }
              // 缓存中数据不全时,从数据库中获取不够的
              $lengthFromDB = $this->length - count($cacheResults);
              $cursorFromDb = null;
              // 从缓存中获取到的数据为空时,需要将cursor之前的数据从db拉到cache中,否则会丢数据
              // 只要从缓存中获取的数据非空,则不存在此情况,不需要调用patchToCache
              if (count($cacheResults) <= 0) {
                  $this->patchToCache($this->cursor);
                  $cursorFromDb = $this->cursor;
              }
              else {
                  $cursorFromDb = $cacheResults[count($cacheResults) - 1];
              }
              $dbResults = $this->getFromDB($cursorFromDb, $lengthFromDB);
              if(!$dbResults or count($dbResults) == 0) {
                  return $cacheResults;
              }
              $this->saveToCache($dbResults);
              return array_merge($cacheResults, $dbResults);
          }
      }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容