찾다
백엔드 개발PHP 튜토리얼CakePHP 2.x CookBook 中文版 第七章 模型 之 检索数据_PHP教程

检索数据

如前所述,模型层的一个角色是从多种存储中获取数据。 CakePHP 模型类带有很多功能,帮助你搜索这些数据,排序,分页并且进行过滤。你将要使用的很多功能集成于模型的 Model::find()
 
find
find(string $type = 'first', array $params = array())
 
Find 是所有模型数据检索功能的主力。 $type 可以是 'all', 'first', 'count', 'list', 'neighbors', 'threaded'或者任何自定义查找类型。 切记,$type 是区分大小写的。 使用大写字母(例如 All)将得不到期望的结果。
 
$params 用于向不同的 find 传递所有的参数,其默认有如下的键值 - 每一个都是可选的:
 
 1 array(
 2     'conditions' => array('Model.field' => $thisValue), //array of conditions
 3     'recursive' => 1, //int
 4     'fields' => array('Model.field1', 'DISTINCT Model.field2'), //array of field names
 5     'order' => array('Model.created', 'Model.field3 DESC'), //string or array defining order
 6     'group' => array('Model.field'), //fields to GROUP BY
 7     'limit' => n, //int
 8     'page' => n, //int
 9     'offset' => n, //int
10     'callbacks' => true //other possible values are false, 'before', 'after'
11 )
也可以添加和使用其它的参数,提供给一些查找类型、行为以及你自己的模型方法。
 
find(‘first’)
find('first', $params) 返回一个结果,你可以在任何期望获得一个结果的情况下使用它。 下面是几个简单的(控制器代码)示例:
 
 1 public function some_function() {
 2     // ...
 3     $semiRandomArticle = $this->Article->find('first');
 4     $lastCreated = $this->Article->find('first', array(
 5         'order' => array('Article.created' => 'desc')
 6     ));
 7     $specificallyThisOne = $this->Article->find('first', array(
 8         'conditions' => array('Article.id' => 1)
 9     ));
10     // ...
11 }
在第一个示例中,没有向 find 传递任何参数 - 所以没有任何条件和排序。这种形式的 find('first') 调用返回的格式如下:
 
 1 Array
 2 (
 3     [ModelName] => Array
 4         (
 5             [id] => 83
 6             [field1] => value1
 7             [field2] => value2
 8             [field3] => value3
 9         )
10 
11     [AssociatedModelName] => Array
12         (
13             [id] => 1
14             [field1] => value1
15             [field2] => value2
16             [field3] => value3
17         )
18 )
find(‘count’)
 
find('count', $params) 返回一个整数值。下面是几个简单的(控制器代码)示例:
 
 1 public function some_function() {
 2     // ...
 3     $total = $this->Article->find('count');
 4     $pending = $this->Article->find('count', array(
 5         'conditions' => array('Article.status' => 'pending')
 6     ));
 7     $authors = $this->Article->User->find('count');
 8     $publishedAuthors = $this->Article->find('count', array(
 9        'fields' => 'DISTINCT Article.user_id',
10        'conditions' => array('Article.status !=' => 'pending')
11     ));
12     // ...
13 }
注解
 
不要向 find('count') 传递 fields 数组。你只能为 DISTINCE count 指定列(其它情况下,计数结果总是相同的 - 仅取决于条件)。
 
find(‘all’)
find('all', $params) 返回一个数组(可能有多个)结果。
 
实际上,它是全部 find() 的变体(包括分页)。下面是几个简单的(控制器代码)示例:
 
 1 public function some_function() {
 2     // ...
 3     $allArticles = $this->Article->find('all');
 4     $pending = $this->Article->find('all', array(
 5         'conditions' => array('Article.status' => 'pending')
 6     ));
 7     $allAuthors = $this->Article->User->find('all');
 8     $allPublishedAuthors = $this->Article->User->find('all', array(
 9         'conditions' => array('Article.status !=' => 'pending')
10     ));
11     // ...
12 }
注解
 
上面的例子中, $allAuthors 将包含 users 表的每个用户。没有要应用的条件被传递给那个 find。
 
调用 find('all') 的结果格式如下:
 
 1 Array
 2 (
 3     [0] => Array
 4         (
 5             [ModelName] => Array
 6                 (
 7                     [id] => 83
 8                     [field1] => value1
 9                     [field2] => value2
10                     [field3] => value3
11                 )
12 
13             [AssociatedModelName] => Array
14                 (
15                     [id] => 1
16                     [field1] => value1
17                     [field2] => value2
18                     [field3] => value3
19                 )
20 
21         )
22 )
find(‘list’)
 
find('list', $params) 返回一个索引数组,用在想要一个用于类似 HTML 输入表单中的 select 元素所需的列表的场合。下面是几个简单的(控制器代码)示例:
 
 1 public function some_function() {
 2     // ...
 3     $allArticles = $this->Article->find('list');
 4     $pending = $this->Article->find('list', array(
 5         'conditions' => array('Article.status' => 'pending')
 6     ));
 7     $allAuthors = $this->Article->User->find('list');
 8     $allPublishedAuthors = $this->Article->find('list', array(
 9         'fields' => array('User.id', 'User.name'),
10         'conditions' => array('Article.status !=' => 'pending'),
11         'recursive' => 0
12     ));
13     // ...
14 }
注解
 
上面的例子中, $allAuthors 将包含 users 表的每个用户。没有要应用的条件被传递给那个 find。
 
调用 find('list') 的结果格式如下:
 
 1 Array
 2 (
 3     //[id] => 'displayValue',
 4     [1] => 'displayValue1',
 5     [2] => 'displayValue2',
 6     [4] => 'displayValue4',
 7     [5] => 'displayValue5',
 8     [6] => 'displayValue6',
 9     [3] => 'displayValue3',
10 )
当调用 find('list') 时,传递的 fields 参数用于决定使用什么做数组的键、值和(可选的)结果的分组。默认情况下,模型的主键被当作键,显示列用作值(可以用模型的 displayField) 属性配置)
 
一些清晰的示例:
 
 1 public function some_function() {
 2     // ...
 3     $justusernames = $this->Article->User->find('list', array(
 4         'fields' => array('User.username')
 5     ));
 6     $usernameMap = $this->Article->User->find('list', array(
 7         'fields' => array('User.username', 'User.first_name')
 8     ));
 9     $usernameGroups = $this->Article->User->find('list', array(
10         'fields' => array('User.username', 'User.first_name', 'User.group')
11     ));
12     // ...
13 }
在上面的例子中,结果变量类似下面这样:
 
 1 $justusernames = Array
 2 (
 3     //[id] => 'username',
 4     [213] => 'AD7six',
 5     [25] => '_psychic_',
 6     [1] => 'PHPNut',
 7     [2] => 'gwoo',
 8     [400] => 'jperras',
 9 )
10 
11 $usernameMap = Array
12 (
13     //[username] => 'firstname',
14     ['AD7six'] => 'Andy',
15     ['_psychic_'] => 'John',
16     ['PHPNut'] => 'Larry',
17     ['gwoo'] => 'Gwoo',
18     ['jperras'] => 'Joël',
19 )
20 
21 $usernameGroups = Array
22 (
23     ['User'] => Array
24     (
25         ['PHPNut'] => 'Larry',
26         ['gwoo'] => 'Gwoo',
27     )
28 
29     ['Admin'] => Array
30     (
31         ['_psychic_'] => 'John',
32         ['AD7six'] => 'Andy',
33         ['jperras'] => 'Joël',
34     )
35 
36 )
find(‘threaded’)
 
find('threaded', $params) 返回一个嵌套数组,如果你想使用模型数据的 parent_id 列建立相应的嵌套结果。下面是几个简单的(控制器代码)示例:
 
1 public function some_function() {
2     // ...
3     $allCategories = $this->Category->find('threaded');
4     $comments = $this->Comment->find('threaded', array(
5         'conditions' => array('article_id' => 50)
6     ));
7     // ...
8 }
小技巧
 
处理嵌套数据的更好的方法是使用 树 行为
 
在上面的例子中,$allCategories 将包含一个呈现整个分类结构的嵌套数组。调用 find('threaded') 的结果格式如下:
 
 1 Array
 2 (
 3     [0] => Array
 4     (
 5         [ModelName] => Array
 6         (
 7             [id] => 83
 8             [parent_id] => null
 9             [field1] => value1
10             [field2] => value2
11             [field3] => value3
12         )
13 
14         [AssociatedModelName] => Array
15         (
16             [id] => 1
17             [field1] => value1
18             [field2] => value2
19             [field3] => value3
20         )
21 
22         [children] => Array
23         (
24             [0] => Array
25             (
26                 [ModelName] => Array
27                 (
28                     [id] => 42
29                     [parent_id] => 83
30                     [field1] => value1
31                     [field2] => value2
32                     [field3] => value3
33                 )
34 
35                 [AssociatedModelName] => Array
36                 (
37                     [id] => 2
38                     [field1] => value1
39                     [field2] => value2
40                     [field3] => value3
41                 )
42 
43                 [children] => Array
44                 (
45                 )
46             )
47             ...
48         )
49     )
50 )
结果呈现的顺序是可以改变的,因为它受 order 处理的影响。如果将 'order' => 'name ASC' 作为参数传递给find('threaded'),其结果将按 name 排序。类似于此的所有 order 都能被使用,此方法没有内置的首次返回的顶层结果的顺序。
 
警告
 
如果指定了 fields,就必须包含 parent_id (或者它的当前别名):
 
1 public function some_function() {
2     $categories = $this->Category->find('threaded', array(
3         'fields' => array('id', 'name', 'parent_id')
4     ));
5 }
否则,上面例子中返回的数组将不是预期的嵌套结构。
 
find(‘neighbors’)
find('neighbors', $params) 执行与 ‘first’ 相同的查找,但返回的是所请求的前一行和后一行。下面是一个简单的(控制器代码)示例: :
 
1 public function some_function() {
2    $neighbors = $this->Article->find('neighbors', array('field' => 'id', 'value' => 3));
3 }
本例中 $params 数组包含两个元素:field 和 value。所有的 find 中的其它元素仍然可用(例如:如果模型可包含,可以在 $params 指定 ‘包含’)。调用 find('neighbors') 的结果格式如下:
 
 1 Array
 2 (
 3     [prev] => Array
 4     (
 5         [ModelName] => Array
 6         (
 7             [id] => 2
 8             [field1] => value1
 9             [field2] => value2
10             ...
11         )
12         [AssociatedModelName] => Array
13         (
14             [id] => 151
15             [field1] => value1
16             [field2] => value2
17             ...
18         )
19     )
20     [next] => Array
21     (
22         [ModelName] => Array
23         (
24             [id] => 4
25             [field1] => value1
26             [field2] => value2
27             ...
28         )
29         [AssociatedModelName] => Array
30         (
31             [id] => 122
32             [field1] => value1
33             [field2] => value2
34             ...
35         )
36     )
37 )
注解
 
注意,结果总是只包含两个根元素: prev 和 next。此功能不兑现模型默认的递归变量。递归设置必须以参数形式传递给每个需要的调用。
 
创建自定义 find 类型
find 方法很灵活,能够接受自定义查找,这是通过在模型变量中定义自己的类型并在模型类中实现特定的函数完成的。
 
模型的 find 类型是 find 选项的快捷方式。例如,如下两种查找是相同的:
 
1 $this->User->find('first');
1 $this->User->find('all', array('limit' => 1));
以下是内核中预定义的类型:
 
first
all
count
list
threaded
neighbors
那么其它的类型呢?以在数据库中查找所有的发布文章为例。每一个改变是在模型中的 Model::$findMethods 变量中添加类型:
 
1 class Article extends AppModel {
2     public $findMethods = array('available' =>  true);
3 }
这是在通知 CakePHP 接受值 available 作为 find 函数的第一个参数。 第二步是实现 _findAvailable 函数。 这是一个约定,如果想实现一个叫做 myFancySearch 的查找就需要实现一个叫做 _findMyFancySearch 方法。
 
 1 class Article extends AppModel {
 2     public $findMethods = array('available' =>  true);
 3 
 4     protected function _findAvailable($state, $query, $results = array()) {
 5         if ($state == 'before') {
 6             $query['conditions']['Article.published'] = true;
 7             return $query;
 8         }
 9         return $results;
10     }
11 }
下面是完整的示例(控制器代码):
 
 1 class ArticlesController extends AppController {
 2 
 3     // Will find all published articles and order them by the created column
 4     public function index() {
 5         $articles = $this->Article->find('available', array(
 6             'order' => array('created' => 'desc')
 7         ));
 8     }
 9 
10 }
上面展示的代码中特定的 _find[Type] 方法接收3个参数。第一个意指查询执行在什么处于状态时执行,可以是before 或 after。 这是因为此函数是这样一种回调函数:有能力在完成前编辑查询,或者在获取结果后对结果进行编辑。
 
通常第一件事是检查 find 函数的查询状态。 before 状态是编辑查询、绑定新的关联、应用更多的行为、解释传递给find 的第二个参数的那些特殊键的时候。此状态需要返回 $query 参数(修改或不修改)。
 
after 状态是检查结果、注入新数据、计算并以另一种格式返回它,或者在最近返回的数据上做任何你爱做的事。此状态需要返回 $result 数组(修改或不修改)。
 
可以创建任意多你喜欢的自定义查找,这也是在应用程序中跨越模型征用代码的好办法。
 
还可以通过如下类型的自定义对查找进行分页:
 
 1 class ArticlesController extends AppController {
 2 
 3     // 将对全部发表的文章进行分页
 4     public function index() {
 5         $this->paginate = array('available');
 6         $articles = $this->paginate();
 7         $this->set(compact('articles'));
 8     }
 9 
10 }
像上面这样设置控制器中的 $this->paginate 属性将导致 find 的 type 变成 available,并且还允许你继续修改查找的结果。
 
如果分页计数出现错误,可能需要向 AppModel 添加如下代码,它可以纠正分页计数:
 
 1 class AppModel extends Model {
 2 
 3 /**
 4  * 如果自定义查找的计数查询中的 'fields' 键是一个数组的话,就删除它,
 5  * 因为它将彻底破坏 Model::_findCount() 调用
 6  *
 7  * @param string $state Either "before" or "after"
 8  * @param array $query
 9  * @param array $results
10  * @return int The number of records found, or false
11  * @access protected
12  * @see Model::find()
13  */
14     protected function _findCount($state, $query, $results = array()) {
15         if ($state === 'before') {
16             if (isset($query['type']) && isset($this->findMethods[$query['type']])) {
17                 $query = $this->{'_find' . ucfirst($query['type'])}('before', $query);
18                 if (!empty($query['fields']) && is_array($query['fields'])) {
19                     if (!preg_match('/^count/i', current($query['fields']))) {
20                         unset($query['fields']);
21                     }
22                 }
23             }
24         }
25         return parent::_findCount($state, $query, $results);
26     }
27 
28 }
29 ?>
在 2.2 版更改.
 
不再需要为纠正计数结果的错误而覆写 _findCount 了。 自定义查找的 'before' 状态现在将带有 $query[‘operation’] = ‘count’ 重新进行调用。返回的 $query 将用在 _findCount() 中。 如果有需要你可以通过检查 'operation' 键来辨别并返回不同的 $query:
 
 1 protected function _findAvailable($state, $query, $results = array()) {
 2     if ($state == 'before') {
 3         $query['conditions']['Article.published'] = true;
 4         if (!empty($query['operation']) && $query['operation'] == 'count') {
 5             return $query;
 6         }
 7         $query['joins'] = array(
 8             //array of required joins
 9         );
10         return $query;
11     }
12     return $results;
13 }
魔术查找类型
 
这些魔术函数是依据特定的列搜索表的快捷方式来使用的。只要向这些函数的末尾添加列名(按照驼峰命名格式), 并提供这些列的规则作为其第一个参数。
 
findAllBy() 函数返回类似于 find('all') 的返回格式的结果, 而 findBy 返回的格式与 find('first') 相同。
 
findAllBy
findAllBy(string $value, array $fields, array $order, int $limit, int $page, int $recursive)
 
findAllBy 示例 相应的 SQL 片段
$this->Product->findAllByOrderStatus('3'); Product.order_status = 3
$this->Recipe->findAllByType('Cookie'); Recipe.type = 'Cookie'
$this->User->findAllByLastName('Anderson'); User.last_name = 'Anderson'
$this->Cake->findAllById(7); Cake.id = 7
$this->User->findAllByEmailOrUsername('jhon'); User.email = 'jhon' OR User.username ='jhon';
$this->User->findAllByUsernameAndPassword('jhon', '123'); User.username = 'jhon' ANDUser.password = '123';
$this->User->findAllByLastName('psychic', array(),array('User.user_name => 'asc')); User.last_name = 'psychic' ORDER BYUser.user_name ASC
返回结果数组的格式类似于 find('all') 的返回值格式。
 
findBy
findBy(string $value);
 
findBy 魔术函数也接受一些可选参数:
 
findBy(string $value[, mixed $fields[, mixed $order]]);
 
findBy 示例 相应的 SQL 片段
$this->Product->findByOrderStatus('3'); Product.order_status = 3
$this->Recipe->findByType('Cookie'); Recipe.type = 'Cookie'
$this->User->findByLastName('Anderson'); User.last_name = 'Anderson';
$this->User->findByEmailOrUsername('jhon'); User.email = 'jhon' OR User.username = 'jhon';
$this->User->findByUsernameAndPassword('jhon','123'); User.username = 'jhon' AND User.password ='123';
$this->Cake->findById(7); Cake.id = 7
findBy() 函数返回的结果类似于 find('first')。
 
Model::query()
query(string $query)
 
虽然很少有必要,但如果你不能或不想通过其它方法调用 SQL,就可以直接使用模型的 query() 方法。
 
如果你真想在应用程序中使用这种方法,请确保你已经阅读过 CakePHP 的 数据清洁,这有助于清理用户提供的数据,以防止注入和跨站点脚本攻击。
 
注解
 
query() 不理会 $Model->cacheQueries,因为其功能本质上与调用的模型不相关。为避免缓存调用查询,需要将第二个参数设置为 false,例如: query($query, $cachequeries = false)。
 
query() 在查询中使用表名作为返回数据的数组键,而不是模型名。例如:
 
1 $this->Picture->query("SELECT * FROM pictures LIMIT 2;");
可能返回如下数组:
 
 1 Array
 2 (
 3     [0] => Array
 4     (
 5         [pictures] => Array
 6         (
 7             [id] => 1304
 8             [user_id] => 759
 9         )
10     )
11 
12     [1] => Array
13     (
14         [pictures] => Array
15         (
16             [id] => 1305
17             [user_id] => 759
18         )
19     )
20 )
要使用模型名作为数组键,以与 find 方法的返回结果一致,可以将查询写成:
 
1 $this->Picture->query("SELECT * FROM pictures AS Picture LIMIT 2;");
将返回:
 
 1 Array
 2 (
 3     [0] => Array
 4     (
 5         [Picture] => Array
 6         (
 7             [id] => 1304
 8             [user_id] => 759
 9         )
10     )
11 
12     [1] => Array
13     (
14         [Picture] => Array
15         (
16             [id] => 1305
17             [user_id] => 759
18         )
19     )
20 )
注解
 
此语法及关联数组结构仅在 MySQL 中有效。在手动运行查询时,Cake 不提供任何抽象数据,所以其结果在不同的数据库中有所不同。
 
Model::field()
field(string $name, array $conditions = null, string $order = null)
 
返回值只有与 $order 指定的排序条件相匹配的第一条记录中由 $name 指定的单个列。如果没有传递条件并且模型设置了 id,将返回当前模型结果的列的值。如果没有匹配的记录,查找将返回 false。
 
1 $this->Post->id = 22;
2 echo $this->Post->field('name'); // echo the name for row id 22
4 echo $this->Post->field('name', array('created date('Y-m-d H:i:s')), 'created DESC');
5 // 显示最后创建的实例的 'name' 列。
Model::read()
 
read($fields, $id)
 
read() 是一个用于设置当前模型数据(Model::$data)的方法 – 例如在编辑过程中 – 但是不能用在从数据库中获取单条记录的其它情况中
 
$fields 用于传递单个列的名字,可以是字符串或者列名数组;如果为空(empty),则获取所有列。
 
$id 指定要读取的记录的 ID。默认是由 Model::$id 指定的当前选择的记录。 传递不同的值给 $id 将引起记录被选择。
 
read() 总是返回一个数组(即使仅包含了一个列名)。使用 field 来获取单个列的值。
 
警告
 
由于 read 方法覆写任何存储在模型的 data 和 id 属性中的任何信息,使用此功能是要非常小心,尤其在类似 beforeValidata 和 beforeSave 等模型回调函数中使用的时候。通常 find 方法比 read 方法提供了更强大和易用的 API。
 
复杂的查找条件
多数模型的 find 调用需要传递条件集。通常,CakePHP 使用数组来组合需要放在 SQL 查询的 WHERE 子句中的条件。
 
使用数组很整洁且易读,构建查询也非常容易。这种语法还打散了查询中的元素(列、值、操作,等等)。它使 CakePHP 有可能生成更高效的查询,确保 SQL 语法正确,正确分解查询的每个独立的部分。使用数组语法还使 CakePHP 能够确保查询避免 SQL 注入攻击。
 
基于数组的最基础的查询类似于:
 
1 $conditions = array("Post.title" => "This is a post", "Post.author_id" => 1);
2 // 带有模型的示例
3 $this->Post->find('first', array('conditions' => $conditions));
此结构非常简单:它将查找标题等于 “This is a post” 的帖子。注意,我们可以使用 “title” 作为列的名字,但是在构建查询时,最好总是指定模型名,因为它提高了代码的清晰度,有助于在你选择改变架构时防范冲突。
 
其它的匹配类型呢?同样简单。假设你要查找所有的 title 不是 This is a post 的帖子:
 
1 array("Post.title !=" => "This is a post")
注意,’!=’ 跟在列的名称之后。CakePHP 能解析任何有效的 SQL 比较操作符,包括使用 LIKE、BETWEEN、REGEX 的匹配表达式,只要你用空格分隔开列名和操作符。IN(...) 风格的匹配例外。假设你想查找 title 包含在给定的值集合之内的帖子:
 
1 array(
2     "Post.title" => array("First post", "Second post", "Third post")
3 )
要执行 NOT IN(...) 匹配查找 title 不在给定的值集之内的帖子:
 
1 array(
2     "NOT" => array("Post.title" => array("First post", "Second post", "Third post"))
3 )
为条件添加附加的过滤与向数组添加附加的键/值对一样简单:
 
1 array (
2     "Post.title" => array("First post", "Second post", "Third post"),
3     "Post.created >" => date('Y-m-d', strtotime("-2 weeks"))
4 )
还可以创建对比数据库中两个列的查找:
 
1 array("Post.created = Post.modified")
上面的例子将返回创建时间和编辑时间相同的帖子(就是指那些从来没被编辑过的帖子)。
 
记住,如果你发现自己不能在一个方法中生成 WHERE 子句(例如 逻辑运算),你总能用字符串来指定它:
 
1 array(
2     'Model.field & 8 = 1',
3     // 其它常用条件
4 )
默认情况下,CakePHP 使用逻辑 AND 连接多个条件;也就是说,上面的代码片段仅匹配两星期前创建的并且标题与给定的集中的某一个匹配的帖子。但是我们也能很容易的找到符合任一条件的帖子:
 
1 array("OR" => array(
2     "Post.title" => array("First post", "Second post", "Third post"),
3     "Post.created >" => date('Y-m-d', strtotime("-2 weeks"))
4 ))
CakePHP 接受所有有效的 SQL 逻辑运算,包括 AND、OR、NOT、XOR 等等,而且不区分大小写。这些条件还能无限制嵌套。假设 Posts 和 Authors 间有 belongsTo 关系,想要找到所有包含特定关键词(”magic”)或者两星期前建立的,但仅限于由 Bob 发布的帖子:
 
1 array(
2     "Author.name" => "Bob",
3     "OR" => array(
4         "Post.title LIKE" => "%magic%",
5         "Post.created >" => date('Y-m-d', strtotime("-2 weeks"))
6     )
7 )
如果需要在同一个列上设置多个条件,比如想要执行一个带有多个条款的 LIKE 搜索,可以使用类似如下的条件:
 
1 array('OR' => array(
2     array('Post.title LIKE' => '%one%'),
3     array('Post.title LIKE' => '%two%')
4 ))
Cake 不能检查 null 列。在本例中,查询将返回所有 title 不为 null 的记录:
 
1 array("NOT" => array(
2         "Post.title" => null
3     )
4 )
要处理 BETWEEN 查询,可以使用如下条件:
 
1 array('Post.read_count BETWEEN ? AND ?' => array(1,10))
注解
 
CakePHP 将引用的数字值依赖于 DB 的列类型。
 
GROUP BY?:
 
1 array(
2     'fields' => array(
3         'Product.type',
4         'MIN(Product.price) as price'
5     ),
6     'group' => 'Product.type'
7 )
所返回的值格式如下:
 
 1 Array
 2 (
 3     [0] => Array
 4     (
 5         [Product] => Array
 6         (
 7             [type] => Clothing
 8         )
 9         [0] => Array
10         (
11             [price] => 32
12         )
13     )
14     [1] => Array
15     ...
下面是执行 DISTINCT 查询的简单示例。可以按类似格式使用其它操作符,例如 MIN()、MAX(),等等:
 
1 array(
2     'fields' => array('DISTINCT (User.name) AS my_column_name'),
3     'order' = >array('User.id DESC')
4 )
通过嵌套多个条件数组,可以构建非常复杂的条件:
 
 1 array(
 2     'OR' => array(
 3         array('Company.name' => 'Future Holdings'),
 4         array('Company.city' => 'CA')
 5     ),
 6     'AND' => array(
 7         array(
 8             'OR' => array(
 9                 array('Company.status' => 'active'),
10                 'NOT' => array(
11                     array('Company.status' => array('inactive', 'suspended'))
12                 )
13             )
14         )
15     )
16 )
其对应的 SQL 查询为:
 
 1 SELECT `Company`.`id`, `Company`.`name`,
 2 `Company`.`description`, `Company`.`location`,
 3 `Company`.`created`, `Company`.`status`, `Company`.`size`
 4 
 5 FROM
 6    `companies` AS `Company`
 7 WHERE
 8    ((`Company`.`name` = 'Future Holdings')
 9    OR
10    (`Company`.`name` = 'Steel Mega Works'))
11 AND
12    ((`Company`.`status` = 'active')
13    OR (NOT (`Company`.`status` IN ('inactive', 'suspended'))))
子查询
 
下面的示例假定我们有一个带有 “id”,”name” 和 “status” 列的 “users” 表。 status 可以是 “A”、”B”、”C”。并且我们想使用子查询获取所有 status 不同于 “B” 的用户。
 
为了达到此目的,我们将获取模型数据源,向其发出请求以建立查询,就像我们正在调用 find 方法,只不过返回的是一条 SQL 语句。然后,我们生成一个表达式并将其添加到条件数组中:
 
 1 $conditionsSubQuery['"User2"."status"'] = 'B';
 2 
 3 $db = $this->User->getDataSource();
 4 $subQuery = $db->buildStatement(
 5     array(
 6         'fields'     => array('"User2"."id"'),
 7         'table'      => $db->fullTableName($this->User),
 8         'alias'      => 'User2',
 9         'limit'      => null,
10         'offset'     => null,
11         'joins'      => array(),
12         'conditions' => $conditionsSubQuery,
13         'order'      => null,
14         'group'      => null
15     ),
16     $this->User
17 );
18 $subQuery = ' "User"."id" NOT IN (' . $subQuery . ') ';
19 $subQueryExpression = $db->expression($subQuery);
20 
21 $conditions[] = $subQueryExpression;
22 
23 $this->User->find('all', compact('conditions'));
生成的 SQL 查询为:
 
 1 SELECT
 2     "User"."id" AS "User__id",
 3     "User"."name" AS "User__name",
 4     "User"."status" AS "User__status"
 5 FROM
 6     "users" AS "User"
 7 WHERE
 8     "User"."id" NOT IN (
 9         SELECT
10             "User2"."id"
11         FROM
12             "users" AS "User2"
13         WHERE
14             "User2"."status" = 'B'
15     )
另外,如果你需要传递上面的原始 SQL 查询的一部分,带有原始 SQL 的数据源**表达式**为查询的任意部分工作。www.2cto.com
 
预处理语句
如果需要对查询有更多控制,可以使用预处理语句。它允许你直接与数据库驱动对话,并且传递任何你需要的自定义查询:
 
1 $db = $this->getDataSource();
2 $db->fetchAll(
3     'SELECT * from users where username = ? AND password = ?',
4     array('jhon', '12345')
5 );
6 $db->fetchAll(
7     'SELECT * from users where username = :username AND password = :password',
8     array('username' => 'jhon','password' => '12345')
9 );
 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/477780.htmlTechArticle检索数据 如前所述,模型层的一个角色是从多种存储中获取数据。 CakePHP 模型类带有很多功能,帮助你搜索这些数据,排序,分页并且进行...
성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
과대 광고 : 오늘 PHP의 역할을 평가합니다과대 광고 : 오늘 PHP의 역할을 평가합니다Apr 12, 2025 am 12:17 AM

PHP는 현대적인 프로그래밍, 특히 웹 개발 분야에서 강력하고 널리 사용되는 도구로 남아 있습니다. 1) PHP는 사용하기 쉽고 데이터베이스와 완벽하게 통합되며 많은 개발자에게 가장 먼저 선택됩니다. 2) 동적 컨텐츠 생성 및 객체 지향 프로그래밍을 지원하여 웹 사이트를 신속하게 작성하고 유지 관리하는 데 적합합니다. 3) 데이터베이스 쿼리를 캐싱하고 최적화함으로써 PHP의 성능을 향상시킬 수 있으며, 광범위한 커뮤니티와 풍부한 생태계는 오늘날의 기술 스택에 여전히 중요합니다.

PHP의 약한 참고 자료는 무엇이며 언제 유용합니까?PHP의 약한 참고 자료는 무엇이며 언제 유용합니까?Apr 12, 2025 am 12:13 AM

PHP에서는 약한 참조가 약한 회의 클래스를 통해 구현되며 쓰레기 수집가가 물체를 되 찾는 것을 방해하지 않습니다. 약한 참조는 캐싱 시스템 및 이벤트 리스너와 같은 시나리오에 적합합니다. 물체의 생존을 보장 할 수 없으며 쓰레기 수집이 지연 될 수 있음에 주목해야합니다.

PHP의 __invoke 마법 방법을 설명하십시오.PHP의 __invoke 마법 방법을 설명하십시오.Apr 12, 2025 am 12:07 AM

\ _ \ _ 호출 메소드를 사용하면 객체를 함수처럼 호출 할 수 있습니다. 1. 객체를 호출 할 수 있도록 메소드를 호출하는 \ _ \ _ 정의하십시오. 2. $ obj (...) 구문을 사용할 때 PHP는 \ _ \ _ invoke 메소드를 실행합니다. 3. 로깅 및 계산기, 코드 유연성 및 가독성 향상과 같은 시나리오에 적합합니다.

동시성에 대해 PHP 8.1의 섬유를 설명하십시오.동시성에 대해 PHP 8.1의 섬유를 설명하십시오.Apr 12, 2025 am 12:05 AM

섬유는 PHP8.1에 도입되어 동시 처리 기능을 향상시켰다. 1) 섬유는 코 루틴과 유사한 가벼운 동시성 모델입니다. 2) 개발자는 작업의 실행 흐름을 수동으로 제어 할 수 있으며 I/O 집약적 작업을 처리하는 데 적합합니다. 3) 섬유를 사용하면보다 효율적이고 반응이 좋은 코드를 작성할 수 있습니다.

PHP 커뮤니티 : 자원, 지원 및 개발PHP 커뮤니티 : 자원, 지원 및 개발Apr 12, 2025 am 12:04 AM

PHP 커뮤니티는 개발자 성장을 돕기 위해 풍부한 자원과 지원을 제공합니다. 1) 자료에는 공식 문서, 튜토리얼, 블로그 및 Laravel 및 Symfony와 같은 오픈 소스 프로젝트가 포함됩니다. 2) 지원은 StackoverFlow, Reddit 및 Slack 채널을 통해 얻을 수 있습니다. 3) RFC에 따라 개발 동향을 배울 수 있습니다. 4) 적극적인 참여, 코드에 대한 기여 및 학습 공유를 통해 커뮤니티에 통합 될 수 있습니다.

PHP vs. Python : 차이점 이해PHP vs. Python : 차이점 이해Apr 11, 2025 am 12:15 AM

PHP와 Python은 각각 고유 한 장점이 있으며 선택은 프로젝트 요구 사항을 기반으로해야합니다. 1.PHP는 간단한 구문과 높은 실행 효율로 웹 개발에 적합합니다. 2. Python은 간결한 구문 및 풍부한 라이브러리를 갖춘 데이터 과학 및 기계 학습에 적합합니다.

PHP : 죽어 가거나 단순히 적응하고 있습니까?PHP : 죽어 가거나 단순히 적응하고 있습니까?Apr 11, 2025 am 12:13 AM

PHP는 죽지 않고 끊임없이 적응하고 진화합니다. 1) PHP는 1994 년부터 새로운 기술 트렌드에 적응하기 위해 여러 버전 반복을 겪었습니다. 2) 현재 전자 상거래, 컨텐츠 관리 시스템 및 기타 분야에서 널리 사용됩니다. 3) PHP8은 성능과 현대화를 개선하기 위해 JIT 컴파일러 및 기타 기능을 소개합니다. 4) Opcache를 사용하고 PSR-12 표준을 따라 성능 및 코드 품질을 최적화하십시오.

PHP의 미래 : 적응 및 혁신PHP의 미래 : 적응 및 혁신Apr 11, 2025 am 12:01 AM

PHP의 미래는 새로운 기술 트렌드에 적응하고 혁신적인 기능을 도입함으로써 달성 될 것입니다. 1) 클라우드 컴퓨팅, 컨테이너화 및 마이크로 서비스 아키텍처에 적응, Docker 및 Kubernetes 지원; 2) 성능 및 데이터 처리 효율을 향상시키기 위해 JIT 컴파일러 및 열거 유형을 도입합니다. 3) 지속적으로 성능을 최적화하고 모범 사례를 홍보합니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

SublimeText3 Linux 새 버전

SublimeText3 Linux 새 버전

SublimeText3 Linux 최신 버전

DVWA

DVWA

DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

Atom Editor Mac 버전 다운로드

Atom Editor Mac 버전 다운로드

가장 인기 있는 오픈 소스 편집기

안전한 시험 브라우저

안전한 시험 브라우저

안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.