dongtu1789 2015-05-25 16:53
浏览 152
已采纳

Yii2 GridView分页只有next和prev链接,没有TotalCount

There is a huge DB table with millions of rows and it needs to be outputed in a GridView with only prev and next links in the paginator.

I don't want to use 'select count(*)' on such tables, so there's no TotalCount. Also I want to prevent users from setting huge offset and degrade MySQL performance.

Can anyone help me?

  • 写回答

2条回答 默认 最新

  • dqknycyt92288 2015-06-01 21:10
    关注

    I've waited several days to make sure I wasn't missing some obvious solution, but now need to hardcode it on my own. The quickest way I've found is to extend DataProvider and rewrite methods: prepareTotalCount(), prepareModels():

    namespace common;
    use yii\data\ActiveDataProvider;
    use yii\base\InvalidConfigException;
    use yii\db\QueryInterface;
    
    class BigActiveDataProvider extends ActiveDataProvider
    {
        protected function prepareTotalCount() {
            return 0;
        }
    
        protected function prepareModels()
        {
            if (!$this->query instanceof QueryInterface) {
                throw new InvalidConfigException('The "query" property must be an instance of a class that implements the QueryInterface e.g. yii\db\Query or its subclasses.');
            }
            $query = clone $this->query;
    
            if (($pagination = $this->getPagination()) !== false) {
                $pagination->validatePage = false;
                $page = $pagination->getPage(true) + 1;
                $offset = $page*$pagination->getPageSize();
    
                $query->limit($pagination->getLimit() + 1)->offset($offset);
            }
            if (($sort = $this->getSort()) !== false) {
                $query->addOrderBy($sort->getOrders());
            }
    
            $res = $query->all($this->db);
    
            if (($pagination = $this->getPagination()) !== false) {
                $pagination->totalCount = ($page)*$pagination->getPageSize();
                if (count($res) > $pagination->getPageSize()) {
                    unset($res[count($res)-1]);
                    $pagination->totalCount++;
                }
            }
    
            return $res;
        }
    }
    

    I don't think that this is the best solution, but it works as planned and it doesn't limit ActiveDataProvider capabilities. It only makes sure that count(*) query won't be executed and there is no need to set totalCount.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?