前言
使用DB::table('menu as m')->get()
生成的SQL語句是select * from menu as prefix_m
,可見Laravel自動給alias加了表前綴,可以通過預先註冊Grammar實現的方式修改。
- 缺點:不同數據庫引擎需要分別編寫不同的實現
- 優點:簡單可靠方便
使用後,SQL語句變成了select * from menu as m
適用版本:Laravel5.x、Laravel7.x (6.x未測試)
代碼
<?php
namespace App\Providers\patch;
use \Illuminate\Database\Query\Builder;
/**
* Class MysqlGrammar
* @author Student414
* @date 2020-5-21
*/
class MysqlGrammar extends \Illuminate\Database\Query\Grammars\MySqlGrammar
{
/**
* Wrap a table in keyword identifiers.
*
* @param \Illuminate\Database\Query\Expression|string $table
* @return string
*/
public function wrapTable($table)
{
if (!$this->isExpression($table)) {
return $this->wrap($this->tablePrefix . $table, false); // hack
}
return $this->getValue($table);
}
/**
* Wrap the given value segments.
*
* @param array $segments
* @return string
*/
protected function wrapSegments($segments)
{
return collect($segments)->map(function ($segment, $key) use ($segments) {
return $key == 0 && count($segments) > 1
? $this->wrap($segment) // hack
: $this->wrapValue($segment);
})->implode('.');
}
}
<?php
namespace App\Providers\patch;
/**
* Class MysqlConnection
*/
class MysqlConnection extends \Illuminate\Database\Connection
{
/**
* @return MysqlGrammar
*/
protected function getDefaultQueryGrammar()
{
return $this->withTablePrefix(new MysqlGrammar()); // here comes our custom Grammar object
}
}
<?php
namespace App\Providers;
use App\Providers\patch\MysqlConnection;
use Illuminate\Database\Connection;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
Connection::resolverFor('mysql', function ($connection, $database, $prefix, $config) {
return new MysqlConnection($connection, $database, $prefix, $config);
});
// 也可以使用這個替換Grammar實現
// $this->app->get('db.connection')->setQueryGrammar(new MysqlGrammar());
}
}
參考資料
https://medium.com/@daniilromazanov/how-to-extend-query-grammar-in-laravel-fb3d2d6de6d4
PS:還可以通過反射實現,動態替換Grammar實現,但是優缺點和此方案相同,不建議使用。