laravel5.5 里面如果想要使用自定义的数据库连接器

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

你可能感兴趣的:(laravel,大数据,数据库,php)