由于项目里面使用到了doris,虽然doris支持mysql协议,但是如果直接把他当mysql使用是行不通的,因为doris并不支持mysql的一些option和mode设置,然后就会一直报错:
SQLSTATE[HY000]: General error: 2013 Lost connection to MySQL server during query (SQL: select sum(totalvisit) total_visit,hour time from `xxx` where `date` between 2023-12-05 and
追踪代码,一直查到
public function createConnector(array $config)
{
if (! isset($config['driver'])) {
throw new InvalidArgumentException('A driver must be specified.');
}
if ($this->container->bound($key = "db.connector.{$config['driver']}")) {
return $this->container->make($key);
}
switch ($config['driver']) {
case 'mysql':
return new MySqlConnector;
case 'pgsql':
return new PostgresConnector;
case 'sqlite':
return new SQLiteConnector;
case 'sqlsrv':
return new SqlServerConnector;
}
throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]");
}
因此需要写个Doris的连接器,因为和mysql连接器一样,只需要在connect方法里面去掉option即可。
namespace App\Connectors;
use Illuminate\Database\Connectors\MySqlConnector;
class DorisConnector extends MySqlConnector
{
public function connect(array $config)
{
$dsn = $this->getDsn($config);
// We need to grab the PDO options that should be used while making the brand
// new connection instance. The PDO options control various aspects of the
// connection's behavior, and some might be specified by the developers.
$connection = $this->createConnection($dsn, $config, []);
if (!empty($config['database'])) {
$connection->exec("use `{$config['database']}`;");
}
$this->configureEncoding($connection, $config);
// Next, we will check to see if a timezone has been specified in this config
// and if it has we will issue a statement to modify the timezone with the
// database. Setting this DB timezone is an optional configuration item.
$this->configureTimezone($connection, $config);
return $connection;
}
}
注册了connector以后还是报错,具体报错位置如下:
也就是说还需要注册Connection因此还需要写个connection,并绑定。
protected function createConnection($driver, $connection, $database, $prefix = '', array $config = [])
{
if ($resolver = Connection::getResolver($driver)) {
return $resolver($connection, $database, $prefix, $config);
}
switch ($driver) {
case 'mysql':
return new MySqlConnection($connection, $database, $prefix, $config);
case 'pgsql':
return new PostgresConnection($connection, $database, $prefix, $config);
case 'sqlite':
return new SQLiteConnection($connection, $database, $prefix, $config);
case 'sqlsrv':
return new SqlServerConnection($connection, $database, $prefix, $config);
}
throw new InvalidArgumentException("Unsupported driver [$driver]");
}
}
创建 DorisConnection
类时,你需要继承 Laravel 的 Illuminate\Database\MySqlConnection
类,并在类中添加 __construct
方法以及其他必要的方法,以处理与 “doris” 驱动相关的数据库连接逻辑。以下是一个简单的示例:
phpCopy code// app/Database/Connections/DorisConnection.php
namespace App\Database\Connections;
use Illuminate\Database\MySqlConnection;
class DorisConnection extends MySqlConnection
{
/**
* Create a new database connection instance.
*
* @param \PDO|\Closure $pdo
* @param string $database
* @param string $tablePrefix
* @param array $config
* @return void
*/
public function __construct($pdo, $database = '', $tablePrefix = '', array $config = [])
{
parent::__construct($pdo, $database, $tablePrefix, $config);
// 可以在这里添加额外的初始化逻辑
}
// 添加你需要的其他方法和逻辑...
}
在这个示例中,DorisConnection
类继承了 Laravel 的 MySqlConnection
类,并添加了一个构造方法,你可以在其中添加与 “doris” 驱动相关的初始化逻辑。这个类中的其他方法可以根据你的需求进行自定义。
确保这个类的命名空间和文件路径与你之前在 AppServiceProvider
中注册的一致。例如,如果你的 DorisConnection
类在 app/Database/Connections
目录下,那么命名空间应该是 App\Database\Connections
。
打开 app/Providers/AppServiceProvider.php
文件,确保你在 boot
方法中注册了 “doris” 驱动的连接解析器:
use Illuminate\Support\ServiceProvider;
use App\Database\Connectors\DorisConnector;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->app->bind('db.connector.doris', DorisConnector::class);
// 手动指定连接解析器
\Illuminate\Database\Connection::resolverFor('doris', function ($connection, $database, $prefix, $config) {
return new \App\Database\Connections\DorisConnection($connection, $database, $prefix, $config);
});
}
}
最后,在使用的时候,在database.php里面还需要配置:
// config/database.php
'connections' => [
// ...
'doris' => [
'driver' => 'doris',
'host' => env('DB_DORIS_HOST', '127.0.0.1'),
'port' => env('DB_DORIS_PORT', '3306'),
'database' => env('DB_DORIS_DATABASE', 'forge'),
'username' => env('DB_DORIS_USERNAME', 'forge'),
'password' => env('DB_DORIS_PASSWORD', ''),
// 其他配置项...
],
],
在这里,我们使用 \Illuminate\Database\Connection::resolverFor
方法手动指定 “doris” 驱动的连接解析器,并创建了一个与之关联的自定义连接类 DorisConnection
。确保 DorisConnection
类存在,并且包含了正确的连接逻辑。
这样,Laravel 就应该能够正确地识别和使用 “doris” 驱动了。如果问题仍然存在,请确保所有的文件名、类名、配置项等都没有拼写错误,并检查是否有其他配置文件或服务提供者干扰了连接的注册。
再次运行,可以链接了,执行sql成功,因此记录一下,给后来者铺路。