由于项目里面使用到了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即可。
<?phpnamespace 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.phpnamespace 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成功,因此记录一下,给后来者铺路。