Laravel 数据库基本操作

Laravel 数据库基本操作

了解 Laravel 某个模块的内部实现,最好的切入点就是从 composer.json 开始,
从里面我们主要可以得到以下信息:

  • require 字段可以知道相关的依赖包
  • extra.laravel.providers 可以知道它的服务提供者的类名称,这个字段配置的类
    会被laravel自动加载执行

Laravel 扩展扩展功能通常都是以 ServiceProvider 的形式注入到 Laravel 项目中的。
所以我们如果要从代码内部层面了解某个扩展包的内部逻辑,都是从 ServiceProvider 都是切入点去了解。

Laravel 数据库操作的服务提供者类为 Illuminate\Database\DatabaseServiceProvider

Laravel 数据库操作主要由以下几个部分组成:

  • Connector 数据库连接器,它负责创建具体的数据库连接
  • ConnectionFactory 连接创建器,它的主要作用就是根据配置的不同,创建对应的
    Connection
  • DatabaseManager 数据库管理器,数据操作的组织类,它就是名为 DB 的 facade
  • DatabaseTransactionsManager 数据库操作事务管理类,主要负责事务相关操作

Connectors 数据库连接器

连接器的作用是用来和数据库建立连接,其其底层依赖 PDO。目前 Laravel 支持4中类型的
数据库:

  • MySqlConnector 创建 MySqlConnection
  • PostgresConnector 创建 PostgresConnection
  • SQLiteConnector 创建 SQLiteConnection
  • SqlServerConnector 创建 SqlServerConnection

以 mysql 为例介绍整个数据库连接创建的过程

  • 首先根据 database 的配置生成 PDO 创建连接需要的 dsn 字符串
  • 合并 PDO 的设置项,设置项都是以 PDO::ATTR_xxxx 开头,具体可以查看 php 手册
  • 创建 PDO 连接
  • 执行 use ${database} 选择数据库
  • 如果设置了 isolation_level ,会执行 SET SESSION TRANSACTION ISOLATION LEVEL 设置事务的级别
  • set names 设置连接的字符编码
  • set time_zone= 时区设置
  • set session sql_mode 设置 sql_mode

ConnectionFactory 连接创建器

ConnectionFactory 作用特别简单,就是根据 database 配置的不同的 driver 实例化上面介绍的4中数据库类型的连接器。

如果想要想要使用自定义的数据库连接器,可以在容器里面注册名为 db.connector.${driver} 创建器。

DatabaseManager

DatabaseManager 是我们操作数据的入口,负责把上面介绍的各个功能类串联起来,在操作数据库的业务逻辑中,我们都是透过 DatabaseManager 来和数据库打交道。

我们在业务逻辑中用的 DB facade 本质就是这个类。它通过魔术方法 __call,把具体的数据库的操作代理到具体的 Connection 上去执行了。


    /**
     * Dynamically pass methods to the default connection.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        return $this->connection()->$method(...$parameters);
    }

例如我们执行 DB::select('select * from users where active = ?', [1]);
具体的过程如下

  • 创建一个默认的数据库连接
  • 调用数据库连接对象上的 query 方法。

数据库操作相关的主要功能模块基本就是以上这个,下面介绍下如何的使用

use Illuminate\Config\Repository;
use Illuminate\Database\Connectors\ConnectionFactory;
use Illuminate\Database\DatabaseManager;
use Illuminate\Foundation\Application;
// 配置
$repository = new Repository();
$repository->set('database', [
    'default' => 'mysql',
    'connections' => [
        'mysql' => [
            'driver' => 'mysql',
            'host' => '127.0.0.1',
            'port' => '3306',
            'database' => 'app',
            'username' => 'root',
            'password' => '123456',
            'unix_socket' => '',
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => [],
        ]
    ],
]);


// 创建 Application 对象
$app = new Application();

// 数据库的配置保存到 Application 中
$app->instance('config',$repository);

// 创建数据库连接器
$connectionFactory = new ConnectionFactory($app);

// 创建数据库管理对象
$db = new DatabaseManager($app,$connectionFactory);

// 执行查询的 SQL
$list = $db->select("show databases");

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 1

你好,我看到这个:如果想要想要使用自定义的数据库连接器,可以在容器里面注册名为 db.connector.${driver} 创建器。这个具体怎么写啊?我现在需要使用doris数据库,虽然是mysql协议,但是不支持mysqlconnector的options选项,因此需要单独创建一个conector,继承自MySqlConnector,然后进行注册,我这样写不行是怎么回事呢? D:\WWW\xxx\app\Providers\DorisConnectorServiceProvider.php

  public function register()
    {
        $this->app->resolving('db.connector.doris', function ($db) {
            return new DorisConnector();
        });
    }```

下面是DorisConnector的代码:

<?php

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;
}

} ```

3个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!