zoukankan      html  css  js  c++  java
  • Yii2中多表关联查询

    准备条件:

    1、首先准备两张表:

    customer(用户表)(id, name)

    order(订单表)(id, customer_id, price)

    customer 表和 order 表之间是一对多的关系,通过 customer_id 字段关联。

    2、建立相应的模型文件 customer.php 和 order.php 文件。

    关联查询:

    customer.php文件添加getOrder()方法:

    <?php
     
    namespace appmodels;
     
    use Yii;
     
    /**
     * This is the model class for table "customer".
     *
     * @property int $id
     * @property string $name 用户姓名
     */
    class Customer extends yiidbActiveRecord
    {
        /**
         * 获取订单信息
         */
        public function getOrder()
        {
            // 一个用户对应多个订单,一对多的关系使用hasMany()关联
            return $this->hasMany(Order::className(), ['customer_id' => 'id'])->asArray();
        }
     
    }

    order.php文件添加getCustomer()方法:

    <?php
     
    namespace appmodels;
     
    use Yii;
     
    /**
     * This is the model class for table "order".
     *
     * @property int $id
     * @property int $customer_id 用户id
     * @property string $price 价格
     */
    class Order extends yiidbActiveRecord
    {
        /**
         * 获取用户信息
         */
        public function getCustomer()
        {
            // 一个订单对应一个用户,一对一的关系使用hasOne()关联
            return $this->hasOne(Customer::className(), ['id' => 'customer_id'])->asArray();
        }
    }

     

    使用:

    // 查询客户名为张三的订单信息
    $customer = Customer::find()->where(['name' => '张三'])->one();
    // 可以通过$customer->getOrder()方法调用customer.php模型中getOrder()方法
    $orders = $customer->getOrder()->all();
    // 也可以使用$customer->order属性调用,
    // 当程序没有找到order属性时,PHP会调用__get()函数,程序会自动寻找getOrder()方法调用
    // 这里不用加all(),程序会自动识别,如果使用的是hasMany则加all(),hasOne则加上one()
    $orders = $customer->order;
    var_dump($orders);exit;
     
    // 查询订单id为1的客户信息
    $order = Order::find()->where(['id' => 1])->one();
    // 调用order.php模型中getCustomer()方法
    $customer = $order->customer;
    var_dump($customer);exit;

     

    with 和 joinWith 的使用:

    使用上面的关联查询时有个问题就是数据量大的时候性能问题。

    $customers = Customer::find()->all();   // 相当于执行 select * from customer
    foreach ($customers as $customer) {
        $orders = $customer->order;  // 相当于执行 select * from order where customer_id = id;
    }

    假如$customers中有100条数据,则要循环查询100次,整个程序需要执行SQL语句101次。

    这时可以使用with():

    // 相当于执行了两条SQL语句 select * from customer
    // select * from order where customer_id in(...)
    $customers = Customer::find()->with('order')->asArray()->all();
    foreach ($customers as $customer) {
        $orders = $customer['order'];  // 取得order表的关联数据
    }

    joinWith()的用法和with()差不多,joinWith()可以指定连接类型,默认LEFT JOIN连接。

    注意点:

    1、在模型中定义hasMany,hasOne方法时,最好不要加上all(),one()。调用$customer->order时程序会自动根据使用的是hasMany还是hasOne加上相应的all(), one()。

    2、使用with(), joinWith() 查询时,如果在模型中定义hasMany,hasOne方法时加上了all(),one(),程序会报错。

  • 相关阅读:
    vue打包编译报错,These dependencies were not found:core-js/modules/es
    JS 新语法「可选链」「双问号」已进入 Stage 3
    vue 本地和线上跨域的问题 个人解决方案
    vue-router懒加载或者按需加载
    brew 切换国内的源
    vue 数组、对象 深度拷贝和赋值
    全局axios默认值 和 自定义实例默认值
    npm install 报node-sass错误
    linux端口探测
    linux批量操作(一)
  • 原文地址:https://www.cnblogs.com/woods1815/p/11521643.html
Copyright © 2011-2022 走看看