如果您问“ Yii是什么?” 查阅我之前的教程: Yii Framework简介 ,它回顾了Yii的好处,并概述了2014年10月发布的Yii 2.0的变化。
在本使用Yii2编程系列中 ,我指导读者使用PHP的Yii2框架。 在今天的教程中,我将指导您使用Yii的对象关系映射 (称为ORM)来处理数据库。 它称为Active Record ,是在Yii中有效编程数据库应用程序的关键方面。
Yii提供了以编程方式使用数据库的不同方式,例如直接查询和查询生成器 ,但使用Active Record可为面向对象的数据库编程提供一整套好处。 您的工作变得更高效,更安全,并且在Yii的模型视图控制器体系结构内工作,并且在您决定切换数据库平台(例如,从MySQL到PostgreSQL)时可移植。
我将详细介绍Yii中Active Record的基础知识。
提醒一下,我确实参与了下面的评论主题。 如果您有不同的方法,其他想法,或者想为以后的教程提出建议,我特别感兴趣。 如果您有任何问题或建议,请在下面发布。 您也可以直接通过Twitter @reifman与我联系 。
什么是活动记录?
Yii的模型视图控制器是其主要优点之一。 Active Record提供了一个与Yii模型紧密集成的面向对象的解决方案来处理您的数据库。 根据Wikipedia的说法,活动记录是“ 马丁·福勒 ( Martin Fowler)在其2003年的《 企业应用程序体系结构的模式 》中命名的”。
Yii文档简要总结了这一点:
Active Record类与数据库表相关联,Active Record实例对应于该表的一行,Active Record实例的属性表示该行中特定列的值。 您无需访问原始SQL语句,而可以访问Active Record属性并调用Active Record方法来访问和操作存储在数据库表中的数据。
Active Record模式到Yii的集成是该框架的强大优势,但是对于大多数框架(如Ruby on Rails)来说都是常见的。
从模型到数据库表的这种抽象允许框架在任何地方执行繁重的安全性工作,例如分解SQL注入查询 。
Yii的Active Record支持还提供了跨多个数据库的可移植性。 您可以切换数据库而无需更改很多代码:
- MySQL 4.1或更高版本
- PostgreSQL 7.3或更高版本
- SQLite 2和3
- Microsoft SQL Server 2008或更高版本
- CUBRID 9.3或更高版本
- Oracle
- Sphinx:通过yii \ sphinx \ ActiveRecord ,需要
yii2-sphinx
扩展名
- ElasticSearch:通过yii \ elasticsearch \ ActiveRecord ,需要
yii2-elasticsearch
扩展
以及以下NoSQL数据库:
- Redis 2.6.12或更高版本:通过yii \ redis \ ActiveRecord ,需要
yii2-redis
扩展 - MongoDB 1.3.0或更高版本:通过yii \ mongodb \ ActiveRecord ,需要
yii2-mongodb
扩展
学习基础
在上一集“ 如何使用Yii2编程:使用数据库和Active Record”中 ,我逐步介绍了如何创建数据库,如何在每个会话中连接Yii,使用迁移来创建数据库表以及使用Gii(Yii的有用代码脚手架生成器)以创建默认模型代码。 如果您不熟悉任何一个,请查看该情节。
在这一集中,我将集中精力在代码中利用Active Record。
在模型中声明活动记录类
首先,让我回顾一下如何转换Yii模型以利用Active Record。 我将使用在“ 构建您的启动”系列中创建的示例模型。 该系列文章将指导您完成如何在Yii2中构建我的初创公司Meeting Planner的工作。
我将使用我创建的一个名为Launch的简单模型的示例,该模型允许主页访问者提供电子邮件地址,如果他们希望在产品未预览并完全发布时得到通知。
将Active Record与模型配合使用非常简单; 请注意, class Launch extends \yii\db\ActiveRecord
:
<?php
namespace frontend\models;
use Yii;
use yii\db\ActiveRecord;
/**
* This is the model class for table "launch".
*
* @property integer $id
* @property string $email
* @property string $ip_addr
* @property integer $status
* @property integer $created_at
* @property integer $updated_at
*/
class Launch extends \yii\db\ActiveRecord
{
const STATUS_REQUEST =0;
/**
* @inheritdoc
*/
public static function tableName()
{
return 'launch';
}
而已。
建筑查询
让我们看一些常见的Active Record查询。
个人记录
如果您有一个记录ID,通常是从控制器的查询参数中获取的,则很容易找到所需的记录:
public function actionSomething($id)
{
$model = Launch::findOne($id);
这等同于:
$model = Launch::find()
->where(['id' => $id])
->one();
您还可以使用更多字段或布尔条件扩展->where
数组:
$model = Launch::find()
->where(['id' => $id,'status'=>Launch::ACTIVE_REQUEST])
...
//equivalent to
$model = Launch::find()
->where(['id' => $id)
->andWhere(['status'=>Launch::ACTIVE_REQUEST])
->orWhere(['status'=>Launch::FUTURE_REQUEST])
...
多个记录
这是查找与特定status
匹配的所有记录(按$id
排序)的示例:
$people = Launch::find()
->where(['status' => Launch::STATUS_REQUEST])
->orderBy('id')
->all();
->all();
查找所有记录,而不只是一个。 变量$people
作为模型对象数组返回。 或者,在没有条件的情况下,可以使用->findAll();
访问所有记录->findAll();
返回数组
使用indexBy
返回由其id
索引的项目数组:
$people = Launch::find()
->indexBy('id')
->all();
或者,您可以使用->asArray()
返回关联数组:
$people = Launch::find()
->asArray()
->all();
注意: Yii的文档说:“虽然此方法节省了内存并提高了性能,但它更接近较低的数据库抽象层,您将失去大多数Active Record功能。”
计数记录
您还可以从查询中返回一个count
:
$count = Launch::find()
->where(['status' => Launch::STATUS_REQUEST])
->count();
例如,我在Meeting Planner中大量使用计数进行统计。 在我们的仪表板集中了解更多信息 :
// calculate $count_meetings_completed
$hd->count_meetings_completed = Meeting::find()->where(['status'=>Meeting::STATUS_COMPLETED])->andWhere('created_at<'.$since)->count();;
// calculate $count_meetings_expired
$hd->count_meetings_expired = Meeting::find()->where(['status'=>Meeting::STATUS_EXPIRED])->andWhere('created_at<'.$since)->count();;
// calculate $count_meetings_planning
$hd->count_meetings_planning = Meeting::find()->where('status<'.Meeting::STATUS_COMPLETED)->andWhere('created_at<'.$since)->count();;
// calculate $count_places
$hd->count_places = Place::find()->where('created_at>'.$after)->andWhere('created_at<'.$since)->count();
存取资料
查询数据(例如单个模型)后,可以很容易地将数据作为模型对象进行访问:
$model = Launch::findOne($id);
$id = $model->id;
$email = $model->email;
我经常以这种方式处理数组:
$users = User::findAll();
foreach ($users as $u) {
$id = $u->id;
$email = $u->email;
大量分配
您还可以通过ActiveRecord快速将数组分配给模型记录:
$values = [
'name' => 'James',
'email' => 'james@example.com',
];
$customer = new Customer();
$customer->attributes = $values;
$customer->save();
这通常用于在表单提交后填充模型数据 :
if (isset($_POST['FormName'])) {
$model->attributes = $_POST['FormName'];
if ($model->save()) {
// handle success
}
}
或者,您可以使用->load()
:
if ($model->load(Yii::$app->request->post()) && $model->save()) {
...
}
Yii的Gii脚手架代码生成器非常适合使用ActiveRecord生成模型,这些模型可以为您完成很多工作,例如模型,控制器,表单,视图等。
保存数据
如上所示,使用Active Record保存数据也很容易。 在Yii文档的此示例中,创建并保存了一条新记录,然后按id加载一条记录,并保存更新:
// insert a new row of data
$customer = new Customer();
$customer->name = 'James';
$customer->email = 'james@example.com';
$customer->save();
// update an existing row of data
$customer = Customer::findOne(123);
$customer->email = 'james@newexample.com';
$customer->save();
删除记录
删除记录更加容易:
$u = User::findOne(99);
$u->delete();
更新柜台
Yii还提供简单的计数器增量。 假设某个用户安排了另一次会议,而我正在跟踪用户表中的会议数:
$u = User::findOne(99);
$u->updateCounters(['meeting_count'=>1]);
// equivalent to
// UPDATE `User` SET `meeting_count` = `meeting_count` + 1 WHERE `id` = 99
关系
跨索引连接表是Active Record最强大的功能之一。 例如,在会议计划器中,每个会议可能有0个或多个MeetingPlaces
。 Meeting.php模型为此定义了一个关系ActiveQuery:
* @property MeetingPlace[] $meetingPlaces
/**
* @return \yii\db\ActiveQuery
*/
public function getMeetingPlaces()
{
return $this->hasMany(MeetingPlace::className(), ['meeting_id' => 'id']);
}
然后,我可以使用$meetingPlaces
属性访问所有会议场所。 下面,我加载一个会议并对其所有的meetingPlaces
进行迭代,这很容易,就好像它是一个内置的子对象数组一样:
$mtg=Meeting::find()->where(['id'=>$meeting_id])->one();
foreach ($mtg->meetingPlaces as $mp) {
...
}
当然,这依赖于在迁移表时创建外键:
$this->createTable('{{%meeting_place}}', [
'id' => Schema::TYPE_PK,
'meeting_id' => Schema::TYPE_INTEGER.' NOT NULL',
'place_id' => Schema::TYPE_INTEGER.' NOT NULL',
'suggested_by' => Schema::TYPE_BIGINT.' NOT NULL',
'status' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 0',
'created_at' => Schema::TYPE_INTEGER . ' NOT NULL',
'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL',
], $tableOptions);
$this->addForeignKey('fk_meeting_place_meeting',
'{{%meeting_place}}', 'meeting_id', '{{%meeting}}',
'id', 'CASCADE', 'CASCADE');
下一步是什么
我希望这可以为Active Record的出色表现提供一个简单的介绍。 它还包括生命周期,事务和锁定,我可能会在以后写到。 如果您想前进,Yii2在其文档中提供了两个学习更多方面的好地方:《 Yii2 Active Record指南》和《 Yii2 Active Record功能规范》 。 这些是写得很好的介绍。
当我们继续深入研究框架的不同方面时,请观看“ 使用Yii2编程”系列中即将推出的教程。 您可能还需要查看前面提到的“ 用PHP构建启动”系列 。
如果您想知道下一个Yii2教程何时到达, 请在Twitter上关注我@reifman或查看我的讲师页面 。
相关链接
翻译自: https://code.tutsplus.com/tutorials/how-to-program-with-yii2-active-record--cms-27434