Eloquent:我需要做这个原始查询吗?

Posted

技术标签:

【中文标题】Eloquent:我需要做这个原始查询吗?【英文标题】:Eloquent: Do I need to do this query raw? 【发布时间】:2018-12-19 19:48:46 【问题描述】:

我正在使用 laravel/eloquent 重写部分遗留软件。

我对典型的 eloquent 的理解很好,并且我在 laravel 中做过一些项目,但对于遗留代码并没有那么多。

我正在尝试用 eloquent 来创建 79 行:

INSERT IGNORE INTO `ps_module_shop` (`id_module`, `enable_device`, id_shop) (SELECT `id_module`, `enable_device`, 555 FROM ps_module_shop WHERE `id_shop` = 1);

我读到您只能使用 model::insert 进行批量插入,但我不确定如何使用此查询来执行此操作,而不是纯 sql。

这就是我现在的做法,但是对于这个查询来说,原始 sql 感觉更优雅:

$blkInsert = [];
$tplModuleShop = ModuleShop::where('id_shop', 1)->get();
foreach($tplModuleShop as $mshop) 
    $blkInsert[] = [
        'id_module'     => $mshop->id_module,
        'enable_device' => $mshop->enable_device,
        'id_shop'       => $shop->id_shop,
    ];

ModuleShop::insert($blkInsert);

注意:我知道这是一个数据透视表,但它是使用复合键的遗留数据库,所以我决定将其视为自己的模型。

【问题讨论】:

【参考方案1】:

老实说,这可能只是使用你的 sql 语句更容易......这是我的尝试:

DB::table('ps_model_shop')
    ->insert(DB::table('ps_module_shop')
        ->select(['id_module', 'enable_device'])
        ->where('id_shop', 1)
        ->get()
        ->map(function($module)
            $module['id_shop'] = 555;
        )
        ->toArray()
    );

【讨论】:

编辑了代码以使其工作,需要修复集合,因为数组元素仍然是对象。接受这个答案,因为它不使用任何原始 sql。但原始 sql 可能是要走的路。 @AvedisKiyici 非常感谢。不要忘记将参数化查询与 ?如果这些数字是用户输入【参考方案2】:

我们找到了一种使用 DB::select 的方法(尽管仍在执行 sql 部分“原始”)

    $fixCollection = function($collection) 
        return json_decode(json_encode($collection), true);
    ;

    ModuleShop::insert(
        $fixCollection(
            \DB::select("SELECT `id_module`, `enable_device`, $shop->id_shop as id_shop FROM ps_module_shop WHERE `id_shop` = 1")
        )
    );

【讨论】:

以上是关于Eloquent:我需要做这个原始查询吗?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel (8.x) 这个多对多过滤问题有更好的 Eloquent 查询吗?

Laravel:在“query-builder”或“eloquent”中更改原始查询

用于原始 SQL 查询的等效 Laravel Eloquent

如何从原始对象创建一个Eloquent模型实例?

从原始 SQL 到 Laravel Eloquent 或查询构建器

Laravel / Eloquent - 无法执行原始查询