主页/PHP笔记/PHP问答/框架Laravel/如何获取Eloquent生成的原始SQL查询

如何获取Eloquent生成的原始SQL查询

Bug编译狮

Bug编译狮

在 Laravel 中,你可以通过以下几种方式来获取 Eloquent 生成的原始 SQL 查询:

方法一:使用 toSql 方法

$users = User::select('*')->get();

// 获取原始 SQL 查询
$sql = $users->toSql();
echo $sql;

方法二:使用 raw 方法

如果你需要将某些部分作为字符串插入到 SQL 查询中,可以使用 raw 方法。

$user = User::where('name', 'John Doe')
                ->whereRaw('age > ?', [30])
                ->first();

// 获取原始 SQL 查询
$sql = $user->toSql();
echo $sql;

方法三:使用 getQueryString 方法

如果你需要获取完整的查询字符串,包括所有条件和排序,可以使用 getQueryString 方法。

$user = User::orderBy('created_at', 'desc')
                ->take(10)
                ->get();

// 获取完整查询字符串
$queryString = $user->getQueryString();
echo $queryString;

示例代码

假设我们有一个简单的模型 User,并且我们想要获取其所有用户的原始 SQL 查询。

use AppModelsUser;

public function getOriginalSql()
{
    // 获取所有用户
    $users = User::all();

    // 获取原始 SQL 查询
    $sql = $users->toSql();
    echo $sql;
}

运行这个方法后,你会看到类似以下的输出:

SELECT * FROM users

这些方法可以帮助你在 Laravel 中获取 Eloquent 生成的原始 SQL 查询,以便更好地理解查询逻辑和执行过程。

黑板Bug讲师

黑板Bug讲师

介绍

在使用Laravel的Eloquent ORM时,Active Record模式的优雅和简洁性有时会掩盖底层数据库交互的事实。对于调试、优化或仅仅理解背后的逻辑,开发人员通常需要查看Eloquent生成的原始SQL查询。本文探讨了从基本示例到更高级用法的各种方法来获取Eloquent生成的原始SQL查询。

启用查询日志

最简单的方法之一是启用查询日志,这样可以查看Laravel正在执行的SQL查询。Laravel会记录所有应用程序运行的所有查询,并可以通过DB Facade访问该日志。

use IlluminateSupportFacadesDB;

DB::enableQueryLog();

// Perform some database operations...

$queries = DB::getQueryLog();
print_r($queries);

在上述代码片段中,您在执行数据库查询之前启用查询日志。完成操作后,您可以检索日志并打印出来。

使用 toSql() 方法

对不起,我不明白您的问题。toSql()查询构建器实例的方法返回查询的SQL,但不运行它以连接数据库。

$users = User::where('active', 1)->toSql();

echo $users;

这将会打印出类似的东西:

select * from `users` where `active` = 1

绑定参数

看到查询占位符可以帮助,但在某些情况下你需要完整的查询并绑定参数。Eloquent并没有提供直接的方法来实现这一点,但你可以利用这个特性。getBindings()与方法相结合的toSql()

$query = User::where('active', 1);
$sqlWithBindings = str_replace(array('%', '?'), array('%%', '%s'), $query->toSql());
$sqlWithBindings = vsprintf($sqlWithBindings, $query->getBindings());

echo $sqlWithBindings;

在将绑定直接注入查询字符串时要小心,如果不正确处理可能会使您的应用程序变得脆弱。

使用DB::listen()

你可以让Laravel监听数据库查询并每次执行查询时调用自己的回调函数:

DB::listen(function ($query) {
    var_dump($query->sql);
    var_dump($query->bindings);
    var_dump($query->time);
});

// Any query executed hereafter will trigger the above callback.

回调接收一个查询对象,该对象包含SQL字符串、绑定参数和执行时间。此方法在开发或调试期间特别有用。

正在处理分页查询的检查。

分页在应用中很常见,但这些自动调整可能导致困惑的查询。要查看发生了什么,请记录查询或将其转换为SQL:

$users = User::where('active', 1)->paginate(15);

// Using toSql() on a paginator instance won't work as expected.
// Instead, get the underlying query:
$query = $users->toBase();
$querySql = $query->toSql();

// You can then dump the bound query as before

高级示例

扩展Eloquent的Builder类以添加新功能是Laravel的强大特性之一。在这里,我将提供一个示例,在其中我们扩展了Builder类以添加一个自定义调试方法。该方法将使我们能够记录SQL查询及其绑定,以便于调试使用。

步骤1:扩展Eloquent的Builder类

首先,创建一个继承自Laravel的Builder类的自定义构建器类。

创建一个新的文件。AppEloquentsCustomBuilder.php

<?php

namespace AppEloquents;

use IlluminateDatabaseEloquentBuilder;
use IlluminateSupportFacadesLog;

class CustomBuilder extends Builder
{
    /**
     * Log the query SQL and bindings.
     *
     * @return $this
     */
    public function debugQuery()
    {
        $sql = $this->toSql();
        $bindings = $this->getBindings();

        Log::debug('SQL Query: ' . $sql, ['bindings' => $bindings]);

        return $this;
    }
}

步骤 2:扩展 Laravel 模型类

接下来,扩展基础的Eloquent模型以使用此自定义构建器。

创建一个新的文件。AppEloquentsCustomModel.php

<?php

namespace AppEloquents;

use IlluminateDatabaseEloquentModel;

class CustomModel extends Model
{
    /**
     * Create a new Eloquent query builder for the model.
     *
     * @param  IlluminateDatabaseQueryBuilder  $query
     * @return AppEloquentsCustomBuilder|static
     */
    public function newEloquentBuilder($query)
    {
        return new CustomBuilder($query);
    }
}

步骤 3:使用定制模型

现在,请使用。CustomModel作为您Eloquent模型的基础模式。

<?php

namespace AppModels;

use AppEloquentsCustomModel;

class User extends CustomModel
{
    // Model content here
}

步骤 4:使用 debugQuery 方法

现在你可以使用了。debugQuery在Eloquent查询方法中使用方法。

use AppModelsUser;

// Example usage
User::where('name', 'John')->debugQuery()->get();

这将记录SQL查询及其绑定到Laravel默认日志通道中的信息,这对于调试复杂的查询非常有帮助。

结论。

在本教程中,我们探讨了多种方法来暴露Eloquent的底层SQL语句,这对于Laravel开发者了解ORM内部机制或需要诊断复杂数据库交互非常有用。

长工码奴1523

长工码奴1523

要在Eloquent模型中获取生成的原始SQL查询,你可以使用from()方法来指定表名和字段。这是一个例子:

$statement = $query->getSql()->getStatement();
echo $statement; // 输出:SELECT * FROM `table_name` WHERE `column1` = ? AND `column2` = ?

在这个例子中,我们首先调用$query->getSql()方法,这会返回一个新的QueryBuilder对象,其中包含了数据库查询的所有部分(包括原始SQL语句)。然后,我们调用getStatement()方法来获取这个查询的字符串表示形式。

如果你想将这些信息保存到变量中以便将来使用,可以这样做:

$sqlString = $query->getSql()->getStatement();
// 现在你可以将$sqlString存储为一个变量或者使用它进行其他操作

// 或者,如果你需要解析原始SQL语句并执行查询
$connection = new PDO($dsn, $username, $password);
$stmt = $connection->prepare($sqlString);

// 假设我们有一个名为$parameters的数组
$parameters = [
    ['value' => 'exampleValue1'],
    ['value' => 'exampleValue2']
];

foreach ($parameters as $param) {
    $stmt->execute($param['value']);
}

请注意,这里假设你已经正确地设置了连接、准备了查询,并且有正确的参数传递。根据你的具体需求,你可能还需要添加更多的逻辑来处理结果集或其他查询组件。