cakephp paginate using mysql SQL_CALC_FOUND_ROWS

南笙酒味 提交于 2019-12-12 16:13:53

问题


I'm trying to make Cakephp paginate take advantage of the SQL_CALC_FOUND_ROWS feature in mysql to return a count of total rows while using LIMIT. Hopefully, this can eliminate the double query of paginateCount(), then paginate().

  • http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows

I've put this in my app_model.php, and it basically works, but it could be done better. Can someone help me figure out how to override paginate/paginateCount so it executes only 1 SQL stmt?

/**
 * Overridden paginateCount method, to using SQL_CALC_FOUND_ROWS
 */
public function paginateCount($conditions = null, $recursive = 0, $extra = array()) {
    $options = array_merge(compact('conditions', 'recursive'), $extra);
    $options['fields'] = "SQL_CALC_FOUND_ROWS `{$this->alias}`.*";

Q: how do you get the SAME limit value used in paginate()?

    $options['limit'] = 1;   // ideally, should return same rows as in paginate()     

Q: can we somehow get the query results to paginate directly, without the extra query?

    $cache_results_from_paginateCount = $this->find('all', $options);   
    /*
     * note: we must run the query to get the count, but it will be cached for multiple paginates, so add comment to query
     */
    $found_rows =  $this->query("/* do not cache for {$this->alias} */ SELECT FOUND_ROWS();");
    $count = array_shift($found_rows[0][0]);
    return $count;
}   

/**
 * Overridden paginate method
 */
public function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array()) {
    $options = array_merge(compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive'), $extra);

Q: can we somehow get $cache_results_for_paginate directly from paginateCount()?

    return $cache_results_from_paginateCount;  // paginate in only 1 SQL stmt
    return $this->find('all', $options);   // ideally, we could skip this call entirely
}

回答1:


The way I solve this for paginating results from a web service which returns the results for the current page and the total number of results available in the same response is to copy the paginate property from the controller to the model in your controller action, before you call $this->paginate(); so that my paging settings are available in the model's paginateCount() method. Then in paginateCount() issue the call to the webservice to get the results. Then store the results in a property of the model then return the total number of results available. Then in the model's paginate() method, I return the results I fetched and stored in the paginateCount() method.

Perhaps something along these lines might work for you too?



来源:https://stackoverflow.com/questions/2793231/cakephp-paginate-using-mysql-sql-calc-found-rows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!