Yii2.0 关联查询

最近一直在看网上视频学习Yii2.0,刚学习了关联查询这一章,就把自己的学习笔记总结了一下。关联查询在实际中用的是比较多的,其实在关联查询中,还有几个小的知识点需要注意,比如:hasMany和hasOne,joinWith 和 with的区别等,如果有理解不正确的地方,欢迎指正!

1.表的关联设计

a)Customer表
—-id 用户ID
—-name 用户名

b)Order表
—-id 价格ID
—-customer_id 用户ID
—-price 价格

customer表中的id 和Order表中的 customer_id 是关联的

2.在models中的写法

a)在customer表中加上方法getOrders();(这个方法中的get是固定的,而Orders是可以随便取的,但是我们一般倾向于和表名一致);

public function getOrders(){    
$orders=$this->hasMany(Order::className(),['customer_id'=>'id'])->asArray()->all();
    return $orders;
   }

b)在price表中加上方法getCustomer();

public function getCustomer(){      
$customer=$this->hasOne(Customer::className(),['id'=>'customer_i  d'])->asArray()->one();
    return $customer;
}

注意:在两个模型类中,你会发现getOrders方法中用的是hasMany,而在getCustomer方法中用的是hasOne,他们有什么区别呢?

i.通过customer来查询order,一个顾客可能会有多个订单,所以就调用的是hasMany(),所以说,hasMany 就是用于一对多的情况;

ii.通过订单来查询顾客,一个订单只能属于一个顾客,所以就调用的是hasOne(),所以说,hasOne 就是用于一对一的情况;

3.在Controllers中调用的写法

a)通过顾客查询订单:

public function actionOrder(){
//查新顾客信息
$customer=Customer::find()->where(['name'=>'zhangsan'])->one();
//查询出张三对应的所有订单
$orders=$customer->getOrders();
var_dump($orders);
}

注意:以上$orders=$customer->getOrders();这行代码也可以写为:$orders=$customer->orders;(这个orders就是models中的getorders中的orders),不过如果这样写的话,model中的方法最后的all()或one,方法就不能调用了,因为我们这样用时,$orders=$customer->orders;它会根据我们model中的hasMany 和 hasOne在后边自动补全all 或 one.

b)通过订单查询顾客:

public function actionCustomer(){
//查询出订单
$order=Order::find()->where(['id'=>1])->one();
//查询出顾客
$cus=$price->getCustomer();
var_dump($cus);
}

c)其实在控制器中我们也可以直接写成以下形式:

public function actionOrder(){
$customer=Customer::find()->where(['name'=>'zhangsan'])->one();
$orders=$customer->hasMany(Price::className(),['customer_id'=>'id'])->asArray()->all();
$orders=$customer->getOrders();
}

就是把model中封装的那个方法直接写在控制器中,但是这样写有个缺陷,就是当我们的表名或关联字段发生改变的时候,就需要修改控制器,如果我们在多个控制器中都查询了,修改起来就比较复杂,封装在models中之后,就直接修改对应的model就ok了。

4.关联查询的性能问题

a)关联查询的多次查询

//查询出所有的customer
$customer=Customer::find()->all();//select * from customer
foreach($customers as $customer){
//把每个顾客对应的订单都查询出来
$orders[]=$customer->orders;//=>select * from order where customer_id =....如果是100个customer,就要调用100次查询
}

以上的写法,如果是100个顾客,就会查询数据库101次,查用户一次,根据用户查订单100次
b)优化

$customers=Customer::find()->with('orders')->all();
//这样优化之后,相当于:
select * from customer 
select * from orders where customer_id in (....);

之前要查询101次的,现在只需要查询2次就可以了
注意:with 中的“orders”,也是model中的getOrders中的orders

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值