如何通过 Eloquent 查询原始数据?

问题描述 投票:0回答:9

我正在尝试在 Laravel 应用程序中执行查询,并且我想使用正常的结构进行查询。这个类要么使用 Eloquent,所以我需要找到一些东西来完全原始地进行查询。

可能类似于

Model::query($query);
。只是这样不行。

php laravel laravel-4 eloquent
9个回答
98
投票

你可以试试这个:

// query can't be select * from table where
Model::select(DB::raw('query'))->get();

示例:

Model::select(DB::raw('query'))
     ->whereNull('deleted_at')
     ->orderBy('id')
     ->get();

此外,您可以使用类似的东西(使用查询生成器):

$users = DB::table('users')
                 ->select(DB::raw('count(*) as user_count, status'))
                 ->where('status', '<>', 1)
                 ->groupBy('status')
                 ->get();

此外,您可以尝试这样的操作(使用查询生成器):

$users = DB::select('select * from users where id = ?', array(1));
$users = DB::select( DB::raw("select * from users where username = :username"), array('username' => Input::get("username")));

Laravel 网站
上查看有关 Raw-Expressions 的更多信息。


38
投票

您可以使用

hydrate()
函数将数组转换为 Eloquent 模型,
Laravel
本身在内部 使用该函数将查询结果转换为模型。据我所知,文档中没有提到。

下面的代码相当于

$userModels = User::where('id', '>', $userId)->get();
:

$userData = DB::select('SELECT * FROM users WHERE id > ?', [$userId]);
$userModels = User::hydrate($userData);

hydrate()
函数在
\Illuminate\Database\Eloquent\Builder
中定义为:

/**
 * Create a collection of models from plain arrays.
 *
 * @param  array  $items
 * @return \Illuminate\Database\Eloquent\Collection
 */
public function hydrate(array $items) {}

21
投票

使用

DB::statement('your raw query here')
。希望这有帮助。


13
投票

我认为默认情况下你不能。我扩展了 Eloquent 并添加了以下方法。

/**
 * Creates models from the raw results (it does not check the fillable attributes and so on)
 * @param array $rawResult
 * @return Collection
 */
public static function modelsFromRawResults($rawResult = [])
{
    $objects = [];

    foreach($rawResult as $result)
    {
        $object = new static();

        $object->setRawAttributes((array)$result, true);

        $objects[] = $object;
    }

    return new Collection($objects);
}

然后你可以做这样的事情:

class User extends Elegant { // Elegant is my extension of Eloquent

     public static function getWithSuperFancyQuery()
     {
         $result = DB::raw('super fancy query here, make sure you have the correct columns');
         return static::modelsFromRawResults($result);
     }
 }

5
投票

老问题,已经回答了,我知道。

但是,似乎没有人提到 Expression 类。

当然,这可能无法解决您的问题,因为您的问题使得原始条件需要包含在 SQL 中的何处(是在 SELECT 语句中还是在 WHERE 语句中?)不明确。但是,无论如何,您可能会发现这条信息很有用。

在您的模型文件中包含以下类:

use Illuminate\Database\Query\Expression;

然后在 Model 类中定义一个新变量

protected $select_cols = [
    'id', 'name', 'foo', 'bar',
    Expression ('(select count(1) from sub_table where sub_table.x = top_table.x) as my_raw_col'), 'blah'
]

并添加范围:

public function scopeMyFind ($builder, $id) {
    return parent::find ($id, $this->select_cols);
}

然后从您的控制器或逻辑文件中,您只需调用:

$rec = MyModel::myFind(1);
dd ($rec->id, $rec->blah, $rec->my_raw_col);

快乐的日子。

(适用于 Laravel 框架 5.5)


2
投票

使用与您正在处理的查询相关的雄辩模型

并做这样的事情:

$contactus = ContactUS::select('*')
    ->whereRaw('id IN (SELECT min(id) FROM users GROUP BY email)')
    ->orderByDesc('created_at')
    ->get();

0
投票

您可以通过编写来缩短结果处理时间

$objects = new Collection(array_map(function($entry) {
    return (new static())->setRawAttributes((array) $entry, true);
}, $result));

0
投票

如果你想选择信息,那就是

DB::select(Statement goes here)
,请记住,除非你转到Config/Database.php并设置connections = mysql,确保'strict' = false,否则某些查询将无法工作 只需知道这可能会导致一些安全问题


0
投票

如果有的话你可能也需要这个。 orderByRaw() 函数用于您的订单。

喜欢

WodSection::orderBy('score_type')

->orderByRaw('FIELD(score_type,"score_type") DESC')

->get();

© www.soinside.com 2019 - 2024. All rights reserved.