Laravel 5.8中使用DB::listen监听查询时获取返回/影响行数的方法问询
Laravel 5.8 数据库日志新增查询行数实现方案
原生限制说明
Laravel 5.8 中 DB::listen 监听的是 Illuminate\Database\Events\QueryExecuted 事件,该事件默认仅传递SQL语句、绑定参数、执行耗时、连接实例这几个属性,默认没有携带结果集行数或影响行数,需要自行扩展数据库连接逻辑注入该属性。
可行实现步骤
方案:扩展核心数据库连接类(无侵入性,适配原有日志逻辑)
- 新建自定义连接类,继承框架原生连接类,重写查询执行方法捕获行数
在app/Database目录下新建CustomConnection.php:
<?php namespace App\Database; use Illuminate\Database\Connection as BaseConnection; class CustomConnection extends BaseConnection { // 临时存储当前查询的行数 public $currentQueryRowCount = 0; /** * 重写查询执行回调方法,执行完SQL后统计行数 */ protected function runQueryCallback($query, $bindings, \Closure $callback) { $result = parent::runQueryCallback($query, $bindings, $callback); // 区分查询类型统计行数:select类统计返回结果数,增删改统计影响行数 if (stripos(trim($query), 'select') === 0) { $this->currentQueryRowCount = is_countable($result) ? count($result) : 0; } else { $this->currentQueryRowCount = (int) $result; } return $result; } }
- 在服务提供者中替换框架默认的连接驱动
打开app/Providers/AppServiceProvider.php,在register方法中添加如下代码:
public function register() { // 按你实际使用的数据库驱动注册,如使用pgsql、sqlite可新增对应resolver \DB::resolverFor('mysql', function ($connection, $database, $prefix, $config) { return new \App\Database\CustomConnection($connection, $database, $prefix, $config); }); }
- 修改原有DB监听逻辑,直接读取行数
if (config('app.sql_profiler')) { DB::listen(function ($query) { Log::channel('db')->debug( $query->sql, [ $query->bindings, $query->time, 'resultCount' => $query->connection->currentQueryRowCount, ] ); }); }
注意事项
- 如果使用多类型数据库驱动,需要为每个用到的驱动都注册对应的自定义连接resolver
- 分页查询返回的行数为当前页的实际返回数据行数,符合业务日志统计预期
- 该扩展仅在你配置的
app.sql_profiler开启时才会产生日志,不会额外增加正常运行时的性能开销
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

