首頁 後端開發 php教程 CakePHP 2.x CookBook 中文版 第七章 模型 之 检索数据_PHP教程

CakePHP 2.x CookBook 中文版 第七章 模型 之 检索数据_PHP教程

Jul 14, 2016 am 10:08 AM
cakephp 中文版 數據 檢索 模型

检索数据

如前所述,模型层的一个角色是从多种存储中获取数据。 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

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

CakePHP 專案配置 CakePHP 專案配置 Sep 10, 2024 pm 05:25 PM

在本章中,我們將了解CakePHP中的環境變數、常規配置、資料庫配置和電子郵件配置。

CakePHP 使用資料庫 CakePHP 使用資料庫 Sep 10, 2024 pm 05:25 PM

在 CakePHP 中使用資料庫非常容易。本章我們將了解CRUD(建立、讀取、更新、刪除)操作。

全球最強開源 MoE 模型來了,中文能力比肩 GPT-4,價格僅 GPT-4-Turbo 的近百分之一 全球最強開源 MoE 模型來了,中文能力比肩 GPT-4,價格僅 GPT-4-Turbo 的近百分之一 May 07, 2024 pm 04:13 PM

想像一下,一個人工智慧模型,不僅擁有超越傳統運算的能力,還能以更低的成本實現更有效率的效能。這不是科幻,DeepSeek-V2[1],全球最強開源MoE模型來了。 DeepSeek-V2是一個強大的專家混合(MoE)語言模型,具有訓練經濟、推理高效的特點。它由236B個參數組成,其中21B個參數用於啟動每個標記。與DeepSeek67B相比,DeepSeek-V2效能更強,同時節省了42.5%的訓練成本,減少了93.3%的KV緩存,最大生成吞吐量提高到5.76倍。 DeepSeek是一家探索通用人工智

替代MLP的KAN,被開源專案擴展到卷積了 替代MLP的KAN,被開源專案擴展到卷積了 Jun 01, 2024 pm 10:03 PM

本月初,來自MIT等機構的研究者提出了一種非常有潛力的MLP替代方法—KAN。 KAN在準確性和可解釋性方面表現優於MLP。而且它能以非常少的參數量勝過以更大參數量運行的MLP。例如,作者表示,他們用KAN以更小的網路和更高的自動化程度重現了DeepMind的結果。具體來說,DeepMind的MLP有大約300,000個參數,而KAN只有約200個參數。 KAN與MLP一樣具有強大的數學基礎,MLP基於通用逼近定理,而KAN基於Kolmogorov-Arnold表示定理。如下圖所示,KAN在邊上具

iPhone上的蜂窩數據網路速度慢:修復 iPhone上的蜂窩數據網路速度慢:修復 May 03, 2024 pm 09:01 PM

在iPhone上面臨滯後,緩慢的行動數據連線?通常,手機上蜂窩互聯網的強度取決於幾個因素,例如區域、蜂窩網絡類型、漫遊類型等。您可以採取一些措施來獲得更快、更可靠的蜂窩網路連線。修復1–強制重啟iPhone有時,強制重啟設備只會重置許多內容,包括蜂窩網路連線。步驟1–只需按一次音量調高鍵並放開即可。接下來,按降低音量鍵並再次釋放它。步驟2–過程的下一部分是按住右側的按鈕。讓iPhone完成重啟。啟用蜂窩數據並檢查網路速度。再次檢查修復2–更改資料模式雖然5G提供了更好的網路速度,但在訊號較弱

特斯拉機器人進廠打工,馬斯克:手的自由度今年將達到22個! 特斯拉機器人進廠打工,馬斯克:手的自由度今年將達到22個! May 06, 2024 pm 04:13 PM

特斯拉機器人Optimus最新影片出爐,已經可以在工廠裡打工了。正常速度下,它分揀電池(特斯拉的4680電池)是這樣的:官方還放出了20倍速下的樣子——在小小的「工位」上,揀啊揀啊揀:這次放出的影片亮點之一在於Optimus在廠子裡完成這項工作,是完全自主的,全程沒有人為的干預。而且在Optimus的視角之下,它還可以把放歪了的電池重新撿起來放置,主打一個自動糾錯:對於Optimus的手,英偉達科學家JimFan給出了高度的評價:Optimus的手是全球五指機器人裡最靈巧的之一。它的手不僅有觸覺

FisheyeDetNet:首個以魚眼相機為基礎的目標偵測演算法 FisheyeDetNet:首個以魚眼相機為基礎的目標偵測演算法 Apr 26, 2024 am 11:37 AM

目標偵測在自動駕駛系統當中是一個比較成熟的問題,其中行人偵測是最早得以部署演算法之一。在多數論文當中已經進行了非常全面的研究。然而,利用魚眼相機進行環視的距離感知相對來說研究較少。由於徑向畸變大,標準的邊界框表示在魚眼相機當中很難實施。為了緩解上述描述,我們探索了擴展邊界框、橢圓、通用多邊形設計為極座標/角度表示,並定義一個實例分割mIOU度量來分析這些表示。所提出的具有多邊形形狀的模型fisheyeDetNet優於其他模型,並同時在用於自動駕駛的Valeo魚眼相機資料集上實現了49.5%的mAP

超級智能體生命力覺醒!可自我更新的AI來了,媽媽再也不用擔心資料瓶頸難題 超級智能體生命力覺醒!可自我更新的AI來了,媽媽再也不用擔心資料瓶頸難題 Apr 29, 2024 pm 06:55 PM

哭死啊,全球狂煉大模型,一網路的資料不夠用,根本不夠用。訓練模型搞得跟《飢餓遊戲》似的,全球AI研究者,都在苦惱怎麼才能餵飽這群資料大胃王。尤其在多模態任務中,這問題尤其突出。一籌莫展之際,來自人大系的初創團隊,用自家的新模型,率先在國內把「模型生成數據自己餵自己」變成了現實。而且還是理解側和生成側雙管齊下,兩側都能產生高品質、多模態的新數據,對模型本身進行數據反哺。模型是啥?中關村論壇上剛露面的多模態大模型Awaker1.0。團隊是誰?智子引擎。由人大高瓴人工智慧學院博士生高一鑷創立,高

See all articles