ホームページ php教程 php手册 CakePHP 2.x CookBook 中文版 第七章 模型 之 检索数据

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

Jun 13, 2016 am 10:54 AM
cakephp 1つ 中国バージョン データ 検索 モデル

检索数据

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

 

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

CakePHP プロジェクトの構成 CakePHP プロジェクトの構成 Sep 10, 2024 pm 05:25 PM

この章では、CakePHP の環境変数、一般設定、データベース設定、電子メール設定について理解します。

世界で最も強力なオープンソース MoE モデルが登場。GPT-4 に匹敵する中国語機能を備え、価格は GPT-4-Turbo のわずか 1% 近くです 世界で最も強力なオープンソース MoE モデルが登場。GPT-4 に匹敵する中国語機能を備え、価格は GPT-4-Turbo のわずか 1% 近くです May 07, 2024 pm 04:13 PM

従来のコンピューティングを超える能力を備えているだけでなく、より低コストでより効率的なパフォーマンスを実現する人工知能モデルを想像してみてください。これは SF ではありません。世界で最も強力なオープンソース MoE モデルである DeepSeek-V2[1] が登場しました。 DeepSeek-V2 は、経済的なトレーニングと効率的な推論の特徴を備えた強力な専門家混合 (MoE) 言語モデルです。これは 236B のパラメータで構成されており、そのうち 21B は各マーカーをアクティブにするために使用されます。 DeepSeek67B と比較して、DeepSeek-V2 はパフォーマンスが優れていると同時に、トレーニング コストを 42.5% 節約し、KV キャッシュを 93.3% 削減し、最大生成スループットを 5.76 倍に高めます。 DeepSeek は一般的な人工知能を研究する会社です

CakePHP の日付と時刻 CakePHP の日付と時刻 Sep 10, 2024 pm 05:27 PM

Cakephp4 で日付と時刻を操作するには、利用可能な FrozenTime クラスを利用します。

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 が普遍近似定理に基づいているのに対し、KAN はコルモゴロフ-アーノルド表現定理に基づいているのと同様に、強力な数学的基礎を持っています。以下の図に示すように、KAN は

超知性の生命力が覚醒する!しかし、自己更新 AI の登場により、母親はデータのボトルネックを心配する必要がなくなりました。 超知性の生命力が覚醒する!しかし、自己更新 AI の登場により、母親はデータのボトルネックを心配する必要がなくなりました。 Apr 29, 2024 pm 06:55 PM

世界は狂ったように大きなモデルを構築していますが、インターネット上のデータだけではまったく不十分です。このトレーニング モデルは「ハンガー ゲーム」のようであり、世界中の AI 研究者は、データを貪欲に食べる人たちにどのように餌を与えるかを心配しています。この問題は、マルチモーダル タスクで特に顕著です。何もできなかった当時、中国人民大学学部のスタートアップチームは、独自の新しいモデルを使用して、中国で初めて「モデル生成データフィード自体」を実現しました。さらに、これは理解側と生成側の 2 つの側面からのアプローチであり、両方の側で高品質のマルチモーダルな新しいデータを生成し、モデル自体にデータのフィードバックを提供できます。モデルとは何ですか? Awaker 1.0 は、中関村フォーラムに登場したばかりの大型マルチモーダル モデルです。チームは誰ですか?ソフォンエンジン。人民大学ヒルハウス人工知能大学院の博士課程学生、ガオ・イージャオ氏によって設立されました。

iPhoneのセルラーデータインターネット速度が遅い:修正 iPhoneのセルラーデータインターネット速度が遅い:修正 May 03, 2024 pm 09:01 PM

iPhone のモバイル データ接続に遅延や遅い問題が発生していませんか?通常、携帯電話の携帯インターネットの強度は、地域、携帯ネットワークの種類、ローミングの種類などのいくつかの要因によって異なります。より高速で信頼性の高いセルラー インターネット接続を実現するためにできることがいくつかあります。解決策 1 – iPhone を強制的に再起動する 場合によっては、デバイスを強制的に再起動すると、携帯電話接続を含む多くの機能がリセットされるだけです。ステップ 1 – 音量を上げるキーを 1 回押して放します。次に、音量小キーを押して、もう一度放します。ステップ 2 – プロセスの次の部分は、右側のボタンを押し続けることです。 iPhone の再起動が完了するまで待ちます。セルラーデータを有効にし、ネットワーク速度を確認します。もう一度確認してください 修正 2 – データ モードを変更する 5G はより優れたネットワーク速度を提供しますが、信号が弱い場合はより適切に機能します

アメリカ空軍が初のAI戦闘機を公開し注目を集める!大臣はプロセス全体を通じて干渉することなく個人的にテストを実施し、10万行のコードが21回にわたってテストされました。 アメリカ空軍が初のAI戦闘機を公開し注目を集める!大臣はプロセス全体を通じて干渉することなく個人的にテストを実施し、10万行のコードが21回にわたってテストされました。 May 07, 2024 pm 05:00 PM

最近、軍事界は、米軍戦闘機が AI を使用して完全自動空戦を完了できるようになったというニュースに圧倒されました。そう、つい最近、米軍のAI戦闘機が初めて公開され、その謎が明らかになりました。この戦闘機の正式名称は可変安定性飛行シミュレーター試験機(VISTA)で、アメリカ空軍長官が自ら飛行させ、一対一の空戦をシミュレートした。 5 月 2 日、フランク ケンダル米国空軍長官は X-62AVISTA でエドワーズ空軍基地を離陸しました。1 時間の飛行中、すべての飛行動作が AI によって自律的に完了されたことに注目してください。ケンダル氏は「過去数十年にわたり、私たちは自律型空対空戦闘の無限の可能性について考えてきたが、それは常に手の届かないものだと思われてきた」と語った。しかし今では、

テスラのロボットは工場で働く、マスク氏:手の自由度は今年22に達する! テスラのロボットは工場で働く、マスク氏:手の自由度は今年22に達する! May 06, 2024 pm 04:13 PM

テスラのロボット「オプティマス」の最新映像が公開され、すでに工場内で稼働可能となっている。通常の速度では、バッテリー(テスラの4680バッテリー)を次のように分類します:公式は、20倍の速度でどのように見えるかも公開しました - 小さな「ワークステーション」上で、ピッキング、ピッキング、ピッキング:今回は、それがリリースされたハイライトの1つビデオの内容は、オプティマスが工場内でこの作業を完全に自律的に行​​い、プロセス全体を通じて人間の介入なしに完了するというものです。そして、オプティマスの観点から見ると、自動エラー修正に重点を置いて、曲がったバッテリーを拾い上げたり配置したりすることもできます。オプティマスのハンドについては、NVIDIA の科学者ジム ファン氏が高く評価しました。オプティマスのハンドは、世界の 5 本指ロボットの 1 つです。最も器用。その手は触覚だけではありません

See all articles