亲宝软件园·资讯

展开

PHP Yii2 关联模型

PeakXin 人气:0

Active Record 可以将相关数据集中进来, 使其可以通过原始数据轻松访问。 例如,客户数据与订单数据相关 因为一个客户可能已经存放了一个或多个订单。这种关系通过适当的声明, 你可以使用 $customer->orders 表达式访问客户的订单信息 这表达式将返回包含 Order Active Record 实例的客户订单信息的数组。

声明关联关系

你必须先在 Active Record 类中定义关联关系,才能使用 Active Record 的关联数据。 简单地为每个需要定义关联关系声明一个 关联方法 即可,如下所示,

class Customer extends ActiveRecord
{
    // ...
    public function getOrders()
    {
        return $this->hasMany(Order::className(), ['customer_id' => 'id']);
    }
}
class Order extends ActiveRecord
{
    // ...
    public function getCustomer()
    {
        return $this->hasOne(Customer::className(), ['id' => 'customer_id']);
    }
}

上述的代码中,我们为 Customer 类声明了一个 orders 关联, 和为 Order 声明了一个 customer 关联。

每个关联方法必须这样命名:getXyz。然后我们通过 xyz(首字母小写)调用这个关联名。 请注意关联名是大小写敏感的。

当声明一个关联关系的时候,必须指定好以下的信息:

一个简单的口诀,先附表的主键,后主表的主键。 正如上面的例子,customer_idOrder 的属性,而 idCustomer 的属性。 (译者注:hasMany() 的第二个参数,这个数组键值顺序不要弄反了)

访问关联数据

定义了关联关系后,你就可以通过关联名访问相应的关联数据了。就像 访问一个由关联方法定义的对象一样,具体概念请查看 属性。 因此,现在我们可以称它为 关联属性 了。

// SELECT * FROM `customer` WHERE `id` = 123
$customer = Customer::findOne(123);
// SELECT * FROM `order` WHERE `customer_id` = 123
// $orders 是由 Order 类组成的数组
$orders = $customer->orders;

提示: 当你通过 getter 方法 getXyz() 声明了一个叫 xyz 的关联属性,你就可以像 属性 那样访问 xyz。注意这个命名是区分大小写的。

如果使用 hasMany() 声明关联关系,则访问此关联属性 将返回相关的 Active Record 实例的数组; 如果使用 hasOne() 声明关联关系,访问此关联属性 将返回相关的 Active Record 实例,如果没有找到相关数据的话,则返回 null

当你第一次访问关联属性时,将执行 SQL 语句获取数据,如 上面的例子所示。如果再次访问相同的属性,将返回先前的结果,而不会重新执行 SQL 语句。要强制重新执行 SQL 语句,你应该先 unset 这个关联属性, 如:unset($ customer-> orders)

$customer->orders; // 获得 `Order` 对象的数组
$customer->getOrders(); // 返回 ActiveQuery 类的实例

设置别名

class Order extends ActiveRecord
{
    // ...
    public function getCustomer()
    {
        return $this->hasOne(Customer::className(), ['id' => 'customer_id'])->alias('c');
    }
}

关联查询

$order = Order::find()->joinWith('customer')
            ->where(['filter1'=>$filter1, 'filter2'=>$filter2])
            ->andWhere(['=', 'c.filter3', $filter3])
            ->andWhere(['<=', 'cfilter4', $filter4])
            ->one();

加载全部内容

相关教程
猜你喜欢
用户评论