Codeigniter Pagination: выполнить запрос дважды? - PullRequest
4 голосов
/ 30 апреля 2010

Я использую codeigniter и класс нумерации страниц.Это такой основной вопрос, но мне нужно убедиться, что я ничего не пропустил.Чтобы получить элементы конфигурации, необходимые для разбиения на страницы результатов, получая их из базы данных MySQL, в основном необходимо выполнить запрос дважды, верно?

Другими словами, вам нужно выполнить запрос, чтобы определить общее числозаписей, прежде чем вы можете разбить на страницы.Поэтому я делаю это следующим образом:

Выполните этот запрос, чтобы получить количество результатов

$this->db->where('something', $something);
$query = $this->db->get('the_table_name');
$num_rows = $query->num_rows();

Затем мне придется сделать это снова, чтобы получить результаты с ограничением и смещением.Что-то вроде:

$this->db->where('something', $something);
$this->db->limit($limit, $offset);
$query = $this->db->get('the_table_name');
if($query->num_rows()){

    foreach($query->result_array() as $row){

         ## get the results here
    }
}

Мне просто интересно, действительно ли я делаю это правильно в том смысле, что запрос всегда должен выполняться дважды?Запросы, которые я использую, намного сложнее, чем показано выше.

Ответы [ 3 ]

1 голос
/ 01 мая 2010

Да, вам нужно выполнить два запроса, но $this->db->count_all('table_name'); - это один, а строка намного чище.

1 голос
/ 01 мая 2010

К сожалению, для разбивки на страницы вы должны знать, сколько элементов вы разбиваете на страницы.

Вы всегда можете кэшировать результат для общего количества элементов, если он слишком дорог для вычислений.

0 голосов
/ 20 декабря 2013

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

  1. Один раз прочитать весь набор, чтобы он мог сосчитать общее количество записей
  2. Затем прочитать окно записей для отображения

Вот пример, который я использовал для проекта. В таблице 'banner' есть список баннеров, которые я хочу показать на разбитом на страницы:

  • Использование свойства открытого класса для хранения итоговых записей (public $ total_records)
  • Использование закрытой функции для построения запроса (что является общим для обеих операций). Параметр ($ isCount), который мы передаем этой функции, уменьшает объем данных, генерируемых запросом, поскольку для подсчета строк нам нужно только одно поле, но когда мы читаем окно данных, нам нужны все обязательные поля.
  • Функция get_list () сначала вызывает базу данных, чтобы найти сумму и сохраняет ее в $ total_records, а затем читает окно данных, чтобы вернуться к вызывающей стороне.
  • Помните, что мы не можем получить доступ к $ total_records без предварительного вызова метода get_list ()!

class Banner_model extends CI_Model {

public $total_records; //holds total records for get_list()

public function get_list($count = 10, $start = 0) {
    $this->build_query();
    $query = $this->db->get();
    $result = $query->result();
    $this->total_records = count($result); //store the count

    $this->build_query();
    $this->db->limit($count, $start);
    $query = $this->db->get();
    $result = $query->result();

    return $result;
}

private function build_query($isCount = FALSE) {
    $this->db->select('*, b.id as banner_id, b.status as banner_status');
    if ($isCount) {
        $this->db->select('b.id');
    }
    $this->db->from('banner b');
    $this->db->join('company c', 'c.id = b.company_id');
    $this->db->order_by("b.id", "desc"); //latest ones first
}

А теперь с контроллера звоним:

$data['banner_list'] = $this->banner_model->get_list();
$config['total_rows'] = $this->banner_model->total_records;

Ситуация усложняется, когда вы начинаете использовать JOIN, как в моем примере, где вы хотите показывать баннеры определенной компании! Вы можете прочитать мой пост в блоге по этому вопросу далее:

http://www.azmeer.info/pagination-hitting-the-database-twise/

...