YII2中多表关联的使用

首先先来讲明一下表结构php

表结构sql

如今有订单表、用户表、商品清单表、商品库存表,数据库

订单表Order Id Order_id User_id  
用户表User Id User_id User_name  
商品清单表Order_goods Id Order_id Goods_id  
商品表Goods Id Goods_id Goods_name  
商品库存表Stock Id Stock-id Goods_id Stock_count

上页下页数组

 

 

 

在YII中,若是想直接关联其余表进行查询的话,须要先在模型里定义它们的关联缓存

Orderyii

class Order extends \yii\db\ActiveRecord.{

    // 关联函数以get+要关联的数据表名来命名

    // 这是获取下订单的客户

    public function getUser(){

        // 第一个参数为要关联的子表模型类名,

        // 第二个参数指定 经过子表的user_id,关联主表的usesr_id字段

        // 这里写清楚点大概意思就是User.user_id => Order.user_id

         return $this->hasMany(User::className(), ['user_id' => 'user_id']);
    }
}

hasMany、hasOne使用函数

Yii2中的表之间的关联有2种,它们用来指定两个模型之间的关联。this

  • 一对多:hasMany
  • 一对一:hasOne
  •  
  • 返回结果:这两个方法的返回结果都为yii\db\ActiveQuery对象(若是你想最后返回的是标准数组形式,记得加上asArray()参数)
  • 第一个参数:所关联的模型的类名称。
  • 第二个参数:是一个数组,其中键为所关联的模型中的属性,值为当前模型中的属性。

关联的使用

如今咱们来尝试获取一个订单spa

//获取订单信息

$order = Order::findOne(1);

//根据订单信息获取到用户信息

$user = $order->user;

固然你能够选择使用with方法,这样看起来简洁一些,其中with的参数为关系的名称,也就在model里面定义的getUser中的usercode

//返回订单信息(包括用户信息)

$order = Order::find(1)->with('user');

//或者

$order = Order::find(1)->getUser();

上面的代码会生成并执行以下的sql语句

SELECT * FROM order    WHERE id=1;

SELECT * FROM user     WHERE user.user_id=order.user_id;

从上面能够看出访问一个关联的时候有两种方法

  • 若是以函数的方式调用,会返回一个 ActiveQuery 对象($customer->getOrders()->all())
  • 若是以属性的方式调用,会直接返回模型的结果($customer->orders)

关联结果缓存

若是这时order表发生了改变,咱们但愿再次查询的话

$user = $order->user;

再次获得订单的时候你会发现没有变化。缘由是只会在第一次执行$order->user的时候才会去数据库里面查询,而后会把结果缓存起来,之后查询的时候都不会再执行sql。

那么若是你想再次执行sql如何作呢?能够执行

//先释放缓存

unset($order->user);

$order->user;

跨表查询

下面重点来了!经过上面表结构的图能够看到,User表和Order_goods表示没有直接关联的,那么若是咱们想根据用户信息查找这个用户买了哪些商品的话,就势必须要经过Order表去关联两张表。那么该怎么作呢?首先仍是model层。由于咱们是根据用户去查,因此到User的model层去定义关联。

User

public function getOrder() {
    return $this->hasMany(Order::className(), ['user_id' => 'user_id']);
}

public function getOrderGoods() {
    return $this->hasMany(OrderGoods::className(), ['order_id' => 'order_id'])->
        via('order');
}

这里注意:getOrderGoods中的第二个order_id是指getOrder关联的Order中的order_id,第一个order_id是指OrderGoods中的order_id。

可是!咱们还有最简单的方法,那就是使用SQL语句啦!

$map = 'select
       user.name,
       order.id,
       order_goods.goods_id,
       goods.goods_name,
       stock.stock_count
       from user
       LEFT JOIN order          ON order.user_id = user.user_id
       LEFT JOIN order_goods    ON order_goods.order_id = order.order_id
       LEFT JOIN goods          ON goods.goods_id = order_goods.goods_id
       LEFT JOIN stock          ON stock.goods_id = goods.goods_id';
$list1   = Article::findBySql($map)->asArray()->all();

这样基本就是整个关联部分了

相关文章
相关标签/搜索