반응형
1. QueryBuilder를 SQL로 변환하기
QueryBuilder에서는 toSql() 메서드를 호출하여 SQL 문을 가져올 수 있습니다. Placeholder의 값은 getBindings()를 사용하여 가져올 수 있습니다.
$query = \App\Model\User::where('id', 1);
dd($query->toSql(), $query->getBindings());
이 방법은 Tinker와 같은 개발 환경에서도 유용합니다.
2. 여러 개의 QueryBuilder에서 SQL 확인
SQL 실행 전에 DB::enableQueryLog()를 사용하여 쿼리 로그를 활성화하고, SQL 실행 후에 DB::getQueryLog() 메서드를 사용하여 쿼리 내용 및 실행 시간을 얻을 수 있습니다.
\DB::enableQueryLog();
\App\Model\User::find(1);
\App\Model\User::where('id', 1);
dd(\DB::getQueryLog());
이렇게 하면 활성화된 후에 실행된 쿼리 로그를 얻을 수 있습니다.
3. ServiceProvider에 등록하여 로그 파일에 자동 출력
환경 변수를 사용하여 로그 출력을 활성화/비활성화
DatabaseQueryServiceProvider를 생성합니다.
$ php artisan make:provider DatabaseQueryServiceProvider
app/Providers/DatabaseQueryServiceProvider.php 파일이 생성됩니다.
config/app.php에 추가합니다.
'providers' => [
// ... 생략
App\Providers\DatabaseQueryServiceProvider::class,
],
위의 코드는 providers 배열안에 DatabaseQueryServiceProvider를 등록합니다.
app/Providers/DatabaseQueryServiceProvider.php를 편집합니다.
<?php
declare(strict_types=1);
namespace App\Providers;
use Carbon\Carbon;
use DateTime;
use Illuminate\Database\Events\TransactionBeginning;
use Illuminate\Database\Events\TransactionCommitted;
use Illuminate\Database\Events\TransactionRolledBack;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\ServiceProvider;
final class DatabaseQueryServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
if (config('logging.sql.enable') !== true) {
return;
}
DB::listen(function ($query): void {
$sql = $query->sql;
foreach ($query->bindings as $binding) {
if (is_string($binding)) {
$binding = "'{$binding}'";
} elseif (is_bool($binding)) {
$binding = $binding ? '1' : '0';
} elseif (is_int($binding)) {
$binding = (string) $binding;
} elseif (is_float($binding)) {
$binding = (string) $binding;
} elseif ($binding === null) {
$binding = 'NULL';
} elseif ($binding instanceof Carbon) {
$binding = "'{$binding->toDateTimeString()}'";
} elseif ($binding instanceof DateTime) {
$binding = "'{$binding->format('Y-m-d H:i:s')}'";
}
$sql = preg_replace('/\\?/', $binding, $sql, 1);
}
Log::debug('SQL', ['sql' => $sql, 'time' => "{$query->time} ms"]);
});
Event::listen(TransactionBeginning::class, function (TransactionBeginning $event): void {
Log::debug('START TRANSACTION');
});
Event::listen(TransactionCommitted::class, function (TransactionCommitted $event): void {
Log::debug('COMMIT');
});
Event::listen(TransactionRolledBack::class, function (TransactionRolledBack $event): void {
Log::debug('ROLLBACK');
});
}
}
config/logging.php을 편집합니다.
return [
/*
|--------------------------------------------------------------------------
| Custom Log
|--------------------------------------------------------------------------
*/
'sql' => [
'enable' => env('LOG_SQL_ENABLE', false),
],
];
.env를 편집합니다.
LOG_SQL_ENABLE=true
※ 프로덕션 환경에서는 성능 및 보안 문제로 인해 비활성화하는 것이 좋습니다!
routes/web.php 파일을 편집합니다.
<?php
use App\Model\User;
Route::get('/', function () {
$user = DB::transaction(function () {
$user = factory(User::class)->create();
$user->name = 'new name';
$user->age = 29;
$user->save();
$user->delete();
return factory(User::class)->create();
});
User::find($user->id);
return view('welcome');
});
적당한 SQL실행처리를 추가하고, 기존의 웰컴 페이지를 표시합니다.
storage/logs/laravel-***.log 파일을 확인하면 다음과 같은 데이터베이스 쿼리 로그가 출력됩니다.
[2019-06-15 07:14:09] local.DEBUG: START TRANSACTION
[2019-06-15 07:14:09] local.DEBUG: SQL {"sql":"insert into `users` (`name`, `email`, `email_verified_at`, `password`, `remember_token`, `updated_at`, `created_at`) values ('Pietro Conn', 'leuschke.kiarra@example.net', '2019-06-15 07:14:09', 'yIXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'rch9DXbn5W', '2019-06-15 07:14:09', '2019-06-15 07:14:09')","time":"2.19 ms"}
[2019-06-15 07:14:09] local.DEBUG: SQL {"sql":"update `users` set `name` = 'change name', `users`.`updated_at` = '2019-06-15 07:14:09' where `id` = 23","time":"1.66 ms"}
[2019-06-15 07:14:09] local.DEBUG: SQL {"sql":"delete from `users` where `id` = 23","time":"1.33 ms"}
[2019-06-15 07:14:09] local.DEBUG: SQL {"sql":"insert into `users` (`name`, `email`, `email_verified_at`, `password`, `remember_token`, `updated_at`, `created_at`) values ('Zoila Wintheiser', 'eokon@example.com', '2019-06-15 07:14:09', 'yIXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'Ya6yCp6UTX', '2019-06-15 07:14:09', '2019-06-15 07:14:09')","time":"1.61 ms"}
[2019-06-15 07:14:09] local.DEBUG: COMMIT
[2019-06-15 07:14:09] local.DEBUG: SQL {"sql":"select * from `users` where `users`.`id` = 24 limit 1","time":"4.41 ms"}
반응형
'PROGRAMMING > PHP' 카테고리의 다른 글
CodeIgniter4 디렉토리 구조 설명 (0) | 2023.07.12 |
---|---|
PHP array_walk() 배열 콜백함수 적용 (0) | 2023.07.11 |
PHP array_chunk() 배열 나누기 (0) | 2023.07.10 |
PHP array_multisort() 배열 정렬 다차원 배열 정렬 (0) | 2023.07.10 |
PHP array_column() 다차원 배열 키로 값 추출 (0) | 2023.07.07 |
댓글