前言
使用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实现,但是优缺点和此方案相同,不建议使用。