个人在 laravel 开发中使用到的一些技巧(持续更新)

1、更高效率地查询:使用批量查询代替 foreach 查询(多次 io 操作转换为一次 io操作)

在维护的项目中, 我发现了有不少需要查询关联数据的时候是这样做的:先查询出列表,然后 foreach 列表去查询列表每一条记录的关联数据,好比如这样:

$products = \DB::table('product')->where('category_id', 1)->paginate();
foreach ($products as $key => $product) {
    $product['some_other_info'] = \DB::table('some_other_info')
        ->where('product_id', $product['id'])
        ->get();

    $products[$key] = $product;
}

  解决方法:使用一次查询代替多次查询

    a. 定义模型关联,使用 Model 的 with 进行查询。如:

AdminUser::with('admin_user_info')->where('id', '>', 1)->get();

    b. 获取查询结果集的 id 列(根据实际情况而定),使用 whereIn 一次查询关联数据。对于那些不能定义关联的才用这种方法,因为这种写法有点啰嗦

$products = \DB::table('product')->where('category_id', 1)->paginate();
$product_ids = $products->pluck('id')->toArray(); // 获取所有 id 
$some_other_infos = \DB::table('some_other_info') // 根据 id 数组一次查询所有关联数据 ->whereIn('product_id', $product_ids) ->get();
$some_other_infos = array_column($some_other_infos, null, 'product_id'); // 使用 id 把结果集转换为关联数组,这样下面可以更高效地操作,否则我们只能两次 foreach 了 foreach ($products as $key => $product) { $product['some_other_info'] = array_get($some_other_infos, $product['id']); $products[$key] = $product; }

  先说说 关联查询:我们在 Model 类里定义的关联,我们不一定在第一次查询就全部查出来,我们可以在需要的时候再去查询 ,使用 load 方法,可以实现这个目标,但是这个 load 只是针对单个 model 对象的,如果我们 Model::xxx()->xx() 链式操作最后是 get(),我们得到的结果将会是一个 Collection 实例,最后调用的方法是 first() 或其他类似的 firstOrFail() 的时候,返回的才是一个 Model 实例。也就是说 load 方法只针对 Model 实例。如下:

我们假设有如下模型定义:

AdminUser

<?php

namespace App\Model;

class AdminUser extends BaseModel
{

    public function admin_user_info()
    {
        return $this->hasOne(AdminUserInfo::class);
    }
}

  

AdminUserInfo

<?php

namespace App\Model;

class AdminUserInfo{
    
}
$admin_users = \App\Model\AdminUser::where('id', '>', 1)->get();
$admin_users->load('admin_user_info'); // 错误, 因为 $admin_users 是一个 Collection 实例

$admin_user = \App\Model\AdminUser::first();
$admin_user->load('admin_user_info'); // 正确, $admin_user 是一个 Model 实例

  

  好像有点跑题了,而我们使用 with 的话,效果相当于一次性给结果集 load 完了所有的关联。如果我们有使用 laravel-debugbar 来,就会发现一对多关联使用 with 时候执行的 sql 都是使用了 whereIn 进行查询的。

  

猜你喜欢

转载自www.cnblogs.com/eleven24/p/9380514.html
今日推荐