`

Cakephp中自定义查询的分页问题,解决方法

阅读更多
转载  Cakephp中自定义查询的分页问题,解决方法 收藏

Cakephp的默认分页功能是基于内置的表关联模型的,所以,如果我们有更多复杂的要求,比如:

    联合两张表的查询分页

这样Cakephp的默认分页就达不到我们的要求,解决的方法是:

使用自定义的查询分页

使用自定义查询分页需要在模型中重载两个方法,paginate()和paginateCount()

1. paginate()

提供分页的数据支持,原型如下:
1. function paginate( $conditions , $fields , $order , $limit , $page = 1, $recursive = null);

参数由Cakephp自定传递,使用方法和find方法是一样的,参数通过在Controller中定义paginate变量传递,例如:
1. $limit = 5;
2. $this ->paginate = array (
3.      'SavedNote' => compact( 'limit' )
4. );

注意:

如果重载paginate()的函数使用参数,请自己格式化参数为自己定义的格式,Cakephp不会自动格式化参数。

2. paginateCount()

提供分页的数据数量统计支持,原型如下:
1. function paginateCount( $conditions = null, $recursive = 0);

带来的问题

通过上述的方法确实能够给我们的自定义查询分页,但是问题是,这样做之后我们无法再使用原有的模型的分页。

解决方法:

使用额外的模型完成我们的自定义查询任务

我们新建一个模型,/models/saved_note.php ,代码如下:
view source
< id="highlighter_464972_clipboard" title="copy to clipboard" type="application/x-shockwave-flash" width="16" height="16" src="http://www.thinkly.cn/wp-content/plugins/syntaxhighlighter/syntaxhighlighter/scripts/clipboard.swf" id="highlighter_464972_clipboard" type="application/x-shockwave-flash" title="copy to clipboard" allowscriptaccess="always" wmode="transparent" flashvars="highlighterId=highlighter_464972" menu="false" src="http://www.thinkly.cn/wp-content/plugins/syntaxhighlighter/syntaxhighlighter/scripts/clipboard.swf" width="16" height="16">
print ?
01. <?php
02. class SavedNote extends AppModel {
03.      var $name = 'SavedNote' ;
04. 
05.      //这个模型不使用任何表,它仅仅为我们提供自定义分页支持
06.      var $useTable = false;
07.      var $user_id = 0;
08. 
09.      /*
10.       * Paginate Function
11.      */
12.      function paginate( $conditions , $fields , $order , $limit , $page = 1, $recursive = null) {
13.          $offset = ((int) $page - 1) * (int) $limit ;
14.          $conditions = "
15.          //这里省略的SQL会在附录中列出
16.          ";
17.          return $this ->query( $conditions );
18.      }
19. 
20.      /*
21.       * Paginate Count Function
22.      */
23.      function paginateCount( $conditions = null, $recursive = 0) {
24.          $conditions = "
25.          //这里省略的SQL会在附录中列出
26.          ";
27.          $result = $this ->query( $conditions );
28.          return (int) $result [0][0][ 'NUMS' ];
29.      }
30. }
31. ?>

我们可以在控制器中使用这个自定义查询了:
view source
< id="highlighter_859578_clipboard" title="copy to clipboard" type="application/x-shockwave-flash" width="16" height="16" src="http://www.thinkly.cn/wp-content/plugins/syntaxhighlighter/syntaxhighlighter/scripts/clipboard.swf" id="highlighter_859578_clipboard" type="application/x-shockwave-flash" title="copy to clipboard" allowscriptaccess="always" wmode="transparent" flashvars="highlighterId=highlighter_859578" menu="false" src="http://www.thinkly.cn/wp-content/plugins/syntaxhighlighter/syntaxhighlighter/scripts/clipboard.swf" width="16" height="16">
print ?
01. class NotesController extends AppController{
02.      var $name = 'Notes' ;
03.      var $layout = 'notes' ;
04. 
05.      //这里引入我们需要的模型
06.      var $uses = array ( 'Note' , 'SavedNote' , 'TrashNote' );
07. 
08.      function saved(){
09.          $user_id = $this ->Auth->User( 'id' );
10.          $limit = 5;
11. 
12.          //这里为我们的自定义查询,传递一些参数
13.          $this ->paginate = array (
14.              'SavedNote' => compact( 'limit' )
15.          );
16.          $this ->SavedNote->user_id = $user_id ;
17. 
18.          //控制器的paginate方法,会自定寻找模型的相应方法,并调用
19.          $notes = $this ->paginate( 'SavedNote' );
20.          $this ->set(compact( 'notes' ));
21.      }
22. 
23. }

最后,希望大家看到的是,自定义模型中的paginate参数的使用是需要自己手动解析和分配的,如果要使用Cakephp的默认查询样式,还需要自己解析一下。

附录:

1. 模型中paginate方法用到的SQL
view source
< id="highlighter_998076_clipboard" title="copy to clipboard" type="application/x-shockwave-flash" width="16" height="16" src="http://www.thinkly.cn/wp-content/plugins/syntaxhighlighter/syntaxhighlighter/scripts/clipboard.swf" id="highlighter_998076_clipboard" type="application/x-shockwave-flash" title="copy to clipboard" allowscriptaccess="always" wmode="transparent" flashvars="highlighterId=highlighter_998076" menu="false" src="http://www.thinkly.cn/wp-content/plugins/syntaxhighlighter/syntaxhighlighter/scripts/clipboard.swf" width="16" height="16">
print ?
01. SELECT
02.      DISTINCT (SavedNote.note_id),
03.      SavedNote.*,
04.      Note.subject,
05.      Note.body,
06.      Note.created,
07.      SentUser. name ,
08.      ReceivedUser. name
09. FROM (
10.      SELECT
11.          ReceivedNote.note_id AS note_id,
12.          ReceivedNote.receive_user_id AS receive_user_id,
13.          ReceivedNote.send_user_id AS send_user_id,
14.          ReceivedNote.is_deleted AS is_deleted,
15.          ReceivedNote.is_saved AS is_saved,
16.          ReceivedNote.read_date AS read_date,
17.          'received' as src
18.      FROM
19.          received_notes AS ReceivedNote
20.      WHERE
21.          receive_user_id = {$this->user_id}
22.      UNION ALL
23.      SELECT
24.          SentNote.note_id AS note_id,
25.          SentNote.receive_user_id AS receive_user_id,
26.          SentNote.send_user_id AS send_user_id,
27.          SentNote.is_deleted AS is_deleted,
28.          SentNote.is_saved AS is_deleted,
29.          SentNote.read_date AS read_date,
30.          'sent' as src
31.      FROM
32.          sent_notes AS SentNote
33.      WHERE
34.          send_user_id = {$this->user_id}
35. ) as SavedNote
36. LEFT JOIN notes AS Note ON Note.id = SavedNote.note_id
37. LEFT JOIN users AS SentUser ON SentUser.id = SavedNote.send_user_id
38. LEFT JOIN users AS ReceivedUser ON ReceivedUser.id = SavedNote.receive_user_id
39. WHERE
40. SavedNote.is_saved = 1
41. ORDER BY
42. Note.created DESC
43. LIMIT {$offset},{$limit}

2. 模型中paginateCount方法用到的SQL
view source
< id="highlighter_96965_clipboard" title="copy to clipboard" type="application/x-shockwave-flash" width="16" height="16" src="http://www.thinkly.cn/wp-content/plugins/syntaxhighlighter/syntaxhighlighter/scripts/clipboard.swf" id="highlighter_96965_clipboard" type="application/x-shockwave-flash" title="copy to clipboard" allowscriptaccess="always" wmode="transparent" flashvars="highlighterId=highlighter_96965" menu="false" src="http://www.thinkly.cn/wp-content/plugins/syntaxhighlighter/syntaxhighlighter/scripts/clipboard.swf" width="16" height="16">
print ?
01. SELECT
02.      COUNT ( DISTINCT (SavedNote.note_id)) AS NUMS
03. FROM (
04.      SELECT
05.          ReceivedNote.note_id AS note_id,
06.          ReceivedNote.receive_user_id AS receive_user_id,
07.          ReceivedNote.send_user_id AS send_user_id,
08.          ReceivedNote.is_saved AS is_saved,
09.          'received' as src
10.      FROM
11.          received_notes AS ReceivedNote
12.      WHERE
13.          receive_user_id = {$this->user_id}
14.      UNION ALL
15.      SELECT
16.          SentNote.note_id AS note_id,
17.          SentNote.receive_user_id AS receive_user_id,
18.          SentNote.send_user_id AS send_user_id,
19.          SentNote.is_saved AS is_saved,
20.          'received' as src
21.      FROM
22.          sent_notes AS SentNote
23.      WHERE
24.          send_user_id = {$this->user_id}
25. ) as SavedNote
26. WHERE
27. SavedNote.is_saved = 1
分享到:
评论

相关推荐

    cakephp分页.docx

    除了基本的分页配置外,开发者还可以使用自定义的查找器方法来进一步细化查询条件。这种方式可以让代码更加整洁且易于维护。下面是一个简单的例子: ```php public $paginate = [ 'finder' =&gt; 'published', ]; ```...

    CakePHP中PageHelper的分页应用

    为了进一步自定义分页行为,你可以配置Paginator组件。例如,如果你想改变默认的每页记录数,可以在`beforeFilter()`方法中设置: ```php public function beforeFilter(Event $event) { parent::beforeFilter($...

    cakephp的CMS教程

    `index()`方法使用了`Paginator`组件来分页显示文章,并将查询结果传递给视图。 ### 创建文章列表模板 视图(Views)是控制器操作的结果展示部分。在`ArticlesController`的`index`操作中,我们创建了一个名为`...

    CAKEPHP CMS教程.pdf

    在CAKEPHP框架中开发内容管理系统(CMS)是一个深入的教程,旨在帮助学习者掌握如何使用CAKEPHP来构建一个完整的CMS系统。以下是从【标题】、【描述】和【部分内容】中提炼出来的详细知识点: 1. CAKEPHP框架概述:...

    CakePHP框架Session设置方法分析

    在本文中,我们将深入探讨CakePHP框架Session的设置方法及其核心组件的功能。 首先, CakePHP提供了三种不同的Session数据保存方式: 1. ** CakePHP 安装目录下的临时文件**:当`define('CAKE_SESSION_SAVE', '...

    CakePHP-1.2-Cheatsheet

    在CakePHP 1.2中,提供了多种自定义查询类型,包括: - **all**: 返回所有匹配记录。 - **first**: 返回第一条匹配记录。 - **count**: 返回匹配记录的数量。 - **list**: 将结果转换为数组形式返回。 - **threaded...

    CakePHP框架Model函数定义方法示例

    - `find()`方法是Model中最常用的函数,用于执行数据库查询。在示例中,`getBlogsByCon()`函数就使用了`find()`。它接受两个参数:查询类型(默认为'all',意味着获取所有记录)和查询选项。 - 查询条件通过`'...

    cake-php-files.zip

    4. **Routing**:路由机制是CakePHP中的一大亮点,它允许开发者自定义URL模式,以更友好的方式展示页面地址,同时也能方便地处理不同请求类型。 5. ** Bake 工具**:Bake是一个命令行工具,用于快速生成模型、控制...

    cakephp-orm-notes:只是一个“ CakePHP ORM”食谱

    4. **Sous Chef**:作为副厨师长,你对ORM的使用更为熟练,能够处理复杂的关联查询和自定义行为(Behaviors),并懂得如何利用Finder方法进行数据筛选和定制化。 5. **行政总厨**:最高级别意味着你具备了全面而...

    CakePHPCRUDCakePHP的快速应用程序开发RAD插件

    5. **添加额外功能**:根据项目需求,可能需要添加自定义控制器方法、行为或模型逻辑。 ### 四、与CakePHP框架的集成 CakePHP CRUD插件很好地融入了CakePHP框架,利用其MVC(Model-View-Controller)架构和ORM...

    PHP开发框架比较

    - **数据库对象**: 提供了多种数据库操作工具,简化了SQL查询的过程。 - **模板引擎**: 内置模板引擎,有助于快速生成动态网页内容。 - **缓存机制**: 支持缓存机制,可以提高应用程序的性能。 - **校验/过滤组件**:...

    零基础学习PHP编程的学习路线及建议.docx

    6. 优化SQL查询,尽量减少`INSERT`和`UPDATE`操作,更多地利用`SELECT`。 7. 尽可能减少文件操作,因为它们相对较慢。 8. 优先使用PHP内置函数,而非自定义或第三方函数。 9. 在处理字符串时,如果可能,用PHP内置...

    Datical_KeyManager

    【Datical KeyManager】是一款基于CakePHP框架构建的许可证管理应用程序,主要负责处理与软件授权相关的事务。在深入探讨这个项目之前,让我们首先了解一下它的核心组成部分。 **CakePHP框架** CakePHP是基于Model...

Global site tag (gtag.js) - Google Analytics