как использовать Zend Paginate без загрузки всех результатов базы данных - PullRequest
5 голосов
/ 11 ноября 2010

Итак, я вижу, как работает Zend Paginate:

$paginator = Zend_Paginator::factory($results);
$paginator->setItemCountPerPage($itemCount);
$paginator->setPageRange($pageRange);

Где $ results - это результат загрузки группы элементов из базы данных в виде

"SELECT * FROM table WHERE etc"

Тогда Zend Paginate посчитает количество результатов и автоматически сгенерирует диапазоны страниц ...

Но если вы сделаете это, вам придется получить все результаты базы данных, которую я вижу какпустая трата времени, поскольку за один раз отображается только одна страница, и поэтому вам нужно только выбрать элементы для этой страницы ...

как заставить Zend paginate рассчитывать правильные диапазоны и числа страниц безприбегать к получению всех результатов всей таблицы?

Ответы [ 5 ]

4 голосов
/ 11 ноября 2010

Используя фабричный метод, вы можете отправить экземпляр Zend_Db_Select или Zend_Db_Table_Select.Если ваш класс расширяет Zend_Db_Table_Abstract, вы можете просто создать из него запрос на выборку и затем отправить его.Если нет, вы можете создать экземпляр и отправить его, см. Пример из документации:

    $adapter = new Zend_Paginator_Adapter_DbSelect($db->select()->from('posts'));
    $adapter->setRowCount(
        $db->select()
           ->from(
                'item_counts',
                array(
                   Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN => 'post_count'
                )
             )
    );

$paginator = new Zend_Paginator($adapter)

http://framework.zend.com/manual/en/zend.paginator.usage.html#zend.paginator.usage.dbselect

0 голосов
/ 20 ноября 2010

Zend_Db_Select и Zend_Db_Table_Select - отличные способы решения вашей проблемы, с которой мне также пришлось столкнуться всего шесть месяцев назад.

Давайте предположим, что в моей базе данных есть таблица книг, и я определил функцию поискачтобы разрешить мне выполнять полнотекстовый поиск по полям таблицы:

Default_Model_DbTable_Books.php:

public class Default_Model_DbTable_Books extends Zend_Db_Table_Abstract {

    // Other variables and methods here...

    public function search($query) {
        // Initialize Zend_Db_Table_Select object
        $select = $this->select(true);

        if (isset($query) && is_string($query)) {
            // Logic for search (don't actually do this, it's horrible for performance)
            $db = $this->getAdapter();
            $where = $db->quoteInto('isbn LIKE ? OR name LIKE ? OR author LIKE ?', $query);
            $search->where($where)
                   ->order('date_published DESC')
                   ->group('author');
        }

        return $select;
    }
}

Default_Model_Mapper_Book.php:

public class Default_Model_Mapper_Book {

    // Defined functions as per Zend Quickstart Mapper classes...

    public function search($query) {
        // Returns Zend_Db_Table_Select object
        return $this->getDbTable()->search($query);
    }
}

Default_BooksController.php:

public function listAction() {
    $mapper = new Default_Model_Mapper_Book();
    $select = $mapper->search($this->_getParam("query"));
    $paginator = Zend_Paginator::factory($select);
}
0 голосов
/ 12 ноября 2010

Это зависит от того, какой адаптер вы используете. Если вы используете Zend_Paginator_Adapter_Array, Zend Paginator будет вычислять диапазон страниц и т. Д. По длине массива. Но если вы используете Zend_Paginator_Adapter_DbSelect, zend paginator автоматически создаст запрос select count(*) ...... as zend_paginator_row_count на основе вашего запроса для расчета количества строк и не загрузит все результаты вашей базы данных.

0 голосов
/ 11 ноября 2010

Вы должны использовать Zend Paginator по-другому. Пожалуйста, посмотрите на документацию для этой функции. Перейдите в раздел «Адаптер DbSelect и DbTableSelect», где приведен пример выбора количества записей вместо извлечения всех записей.

0 голосов
/ 11 ноября 2010

Вы не можете сделать это с Zend_Paginator, вы должны сделать это сами, но это очень просто, измените запрос на эту форму: SELECT * FROM table WHERE etc LIMIT 0, 30, например, в этом случае вы получите первые 30 строк, если вы будетебыть следующим, затем использовать SELECT * FROM table WHERE etc LIMIT 30, 60

Другими словами, помните, что функция, которую вы получите для фреймворка, всегда не оптимальна и работает с простейшими для реализации сложностью, потому что для самых быстрых решений вы должны использовать более трудоемкий код (Это означает, что вы не можете использовать этот код во многих случаях (не как в коде с наихудшей сложностью), решения более посвящены проблеме, например, вы посвящаете mysql, Paginator, а не работаете на уровне базы данных, тогда он работаетэтот код не может сделать это быстрее только на основе ввода, где на входе находятся все строки.

...