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

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

Jun 13, 2016 am 10:54 AM
cakephp un 中文版 数据 检索 模型 de chapitre

检索数据

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

 

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Où trouver la courte de la grue à atomide atomique
1 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Configuration du projet CakePHP Configuration du projet CakePHP Sep 10, 2024 pm 05:25 PM

Dans ce chapitre, nous comprendrons les variables d'environnement, la configuration générale, la configuration de la base de données et la configuration de la messagerie dans CakePHP.

Le modèle MoE open source le plus puissant au monde est ici, avec des capacités chinoises comparables à celles du GPT-4, et le prix ne représente que près d'un pour cent de celui du GPT-4-Turbo. Le modèle MoE open source le plus puissant au monde est ici, avec des capacités chinoises comparables à celles du GPT-4, et le prix ne représente que près d'un pour cent de celui du GPT-4-Turbo. May 07, 2024 pm 04:13 PM

Imaginez un modèle d'intelligence artificielle qui non seulement a la capacité de surpasser l'informatique traditionnelle, mais qui permet également d'obtenir des performances plus efficaces à moindre coût. Ce n'est pas de la science-fiction, DeepSeek-V2[1], le modèle MoE open source le plus puissant au monde est ici. DeepSeek-V2 est un puissant mélange de modèle de langage d'experts (MoE) présentant les caractéristiques d'une formation économique et d'une inférence efficace. Il est constitué de 236B paramètres, dont 21B servent à activer chaque marqueur. Par rapport à DeepSeek67B, DeepSeek-V2 offre des performances plus élevées, tout en économisant 42,5 % des coûts de formation, en réduisant le cache KV de 93,3 % et en augmentant le débit de génération maximal à 5,76 fois. DeepSeek est une entreprise explorant l'intelligence artificielle générale

KAN, qui remplace MLP, a été étendu à la convolution par des projets open source KAN, qui remplace MLP, a été étendu à la convolution par des projets open source Jun 01, 2024 pm 10:03 PM

Plus tôt ce mois-ci, des chercheurs du MIT et d'autres institutions ont proposé une alternative très prometteuse au MLP – KAN. KAN surpasse MLP en termes de précision et d’interprétabilité. Et il peut surpasser le MLP fonctionnant avec un plus grand nombre de paramètres avec un très petit nombre de paramètres. Par exemple, les auteurs ont déclaré avoir utilisé KAN pour reproduire les résultats de DeepMind avec un réseau plus petit et un degré d'automatisation plus élevé. Plus précisément, le MLP de DeepMind compte environ 300 000 paramètres, tandis que le KAN n'en compte qu'environ 200. KAN a une base mathématique solide comme MLP est basé sur le théorème d'approximation universelle, tandis que KAN est basé sur le théorème de représentation de Kolmogorov-Arnold. Comme le montre la figure ci-dessous, KAN a

Vitesse Internet lente des données cellulaires sur iPhone : correctifs Vitesse Internet lente des données cellulaires sur iPhone : correctifs May 03, 2024 pm 09:01 PM

Vous êtes confronté à un décalage et à une connexion de données mobile lente sur iPhone ? En règle générale, la puissance de l'Internet cellulaire sur votre téléphone dépend de plusieurs facteurs tels que la région, le type de réseau cellulaire, le type d'itinérance, etc. Vous pouvez prendre certaines mesures pour obtenir une connexion Internet cellulaire plus rapide et plus fiable. Correctif 1 – Forcer le redémarrage de l'iPhone Parfois, le redémarrage forcé de votre appareil réinitialise simplement beaucoup de choses, y compris la connexion cellulaire. Étape 1 – Appuyez simplement une fois sur la touche d’augmentation du volume et relâchez-la. Ensuite, appuyez sur la touche de réduction du volume et relâchez-la à nouveau. Étape 2 – La partie suivante du processus consiste à maintenir le bouton sur le côté droit. Laissez l'iPhone finir de redémarrer. Activez les données cellulaires et vérifiez la vitesse du réseau. Vérifiez à nouveau Correctif 2 – Changer le mode de données Bien que la 5G offre de meilleures vitesses de réseau, elle fonctionne mieux lorsque le signal est plus faible

La vitalité de la super intelligence s'éveille ! Mais avec l'arrivée de l'IA qui se met à jour automatiquement, les mères n'ont plus à se soucier des goulots d'étranglement des données. La vitalité de la super intelligence s'éveille ! Mais avec l'arrivée de l'IA qui se met à jour automatiquement, les mères n'ont plus à se soucier des goulots d'étranglement des données. Apr 29, 2024 pm 06:55 PM

Je pleure à mort. Le monde construit à la folie de grands modèles. Les données sur Internet ne suffisent pas du tout. Le modèle de formation ressemble à « The Hunger Games », et les chercheurs en IA du monde entier se demandent comment nourrir ces personnes avides de données. Ce problème est particulièrement important dans les tâches multimodales. À une époque où rien ne pouvait être fait, une équipe de start-up du département de l'Université Renmin de Chine a utilisé son propre nouveau modèle pour devenir la première en Chine à faire de « l'auto-alimentation des données générées par le modèle » une réalité. De plus, il s’agit d’une approche à deux volets, du côté compréhension et du côté génération, les deux côtés peuvent générer de nouvelles données multimodales de haute qualité et fournir un retour de données au modèle lui-même. Qu'est-ce qu'un modèle ? Awaker 1.0, un grand modèle multimodal qui vient d'apparaître sur le Forum Zhongguancun. Qui est l'équipe ? Moteur Sophon. Fondé par Gao Yizhao, doctorant à la Hillhouse School of Artificial Intelligence de l’Université Renmin.

CakePHP travaillant avec la base de données CakePHP travaillant avec la base de données Sep 10, 2024 pm 05:25 PM

Travailler avec la base de données dans CakePHP est très simple. Nous comprendrons les opérations CRUD (Créer, Lire, Mettre à jour, Supprimer) dans ce chapitre.

L'US Air Force présente son premier avion de combat IA de grande envergure ! Le ministre a personnellement effectué l'essai routier sans intervenir pendant tout le processus, et 100 000 lignes de code ont été testées 21 fois. L'US Air Force présente son premier avion de combat IA de grande envergure ! Le ministre a personnellement effectué l'essai routier sans intervenir pendant tout le processus, et 100 000 lignes de code ont été testées 21 fois. May 07, 2024 pm 05:00 PM

Récemment, le milieu militaire a été submergé par la nouvelle : les avions de combat militaires américains peuvent désormais mener des combats aériens entièrement automatiques grâce à l'IA. Oui, tout récemment, l’avion de combat IA de l’armée américaine a été rendu public pour la première fois, dévoilant ainsi son mystère. Le nom complet de ce chasseur est Variable Stability Simulator Test Aircraft (VISTA). Il a été personnellement piloté par le secrétaire de l'US Air Force pour simuler une bataille aérienne en tête-à-tête. Le 2 mai, le secrétaire de l'US Air Force, Frank Kendall, a décollé à bord d'un X-62AVISTA à la base aérienne d'Edwards. Notez que pendant le vol d'une heure, toutes les actions de vol ont été effectuées de manière autonome par l'IA ! Kendall a déclaré : "Au cours des dernières décennies, nous avons réfléchi au potentiel illimité du combat air-air autonome, mais cela a toujours semblé hors de portée." Mais maintenant,

Date et heure de CakePHP Date et heure de CakePHP Sep 10, 2024 pm 05:27 PM

Pour travailler avec la date et l'heure dans cakephp4, nous allons utiliser la classe FrozenTime disponible.

See all articles