slabphp/database

SlabPHP 数据库库

v0.1.2 2018-02-18 00:00 UTC

This package is auto-updated.

Last update: 2024-09-09 14:09:09 UTC


README

每个框架都需要一种封装/组织数据库数据的方式,对吧?SlabPHP 数据库库为整体框架添加了两个概念。第一个是在数据库提供者和查询消息中的变量替换之间提供一个抽象层。第二个是为构建坚实的对象数据库返回对象而设计的轻量级数据对象模型。

这个库最初是为了提供接口抽象和封装各种 mysql 函数而构建的。它们最终被弃用,整个框架依赖于这个抽象层,因此创建了一个新的提供者来封装 mysqli 类。

用法

首先使用 composer 包含此库

composer require slabphp/database

设置

一般思路是创建一个提供者,创建一个驱动程序,然后为您的对象创建数据模型。

$mysql = new \Mysqli();
$mysql->connect(...);

$provider = new \Slab\Database\Providers\MySQL\Provider();
$provider->setMySQL($mysql);

$db = new \Slab\Database\Driver();
$db->setProvider($provider);

此时,您可以使用 $db 驱动程序进行直接查询或使用数据模型系统。

数据模型示例

您可以为这些模型创建模型和加载器对象。例如,假设您正在构建一个非常轻量级的博客。

您可能会构建以下内容,其中您的数据对象在 ~/src/Models/Article/DataObject.php 中看起来如下

namespace \My\Site\Models\Article;

class DataObject extends \Slab\Database\Models\MySQL\DataObject
{
    const DATA_LOADER = '\My\Site\Models\Article\Loader';

    public $id;

    public $title;

    public $body;

    public $created;

    public $authorId;
}

您的加载器在 ~/src/Models/Article/Loader.php 中可能看起来如下

namespace \My\Site\Models\Article;

class Loader extends \Slab\Database\Models\MySQL\Loader
{
    const DATA_OBJECT_CLASS = '\My\Site\Models\Article\DataObject';

    const TABLE_NAME = 'articles';

    protected $mapping = [
        'id' => 'id',
        'title' => 'title',
        'body' => 'body',
        'date_created' => 'created:date',
        'author_id' => 'authorId'
    ];

    public function getLatestArticles()
    {
        $sql = "select " . $this->getMappingSQL() . " from " . $this->getTable() . " order by date_created desc limit 20;";
        $resultObject = $this->driver->query($sql, [], static::DATA_OBJECT_CLASS);

        return $resultObject->result();
    }
}

基础 MySQL 加载器中有许多默认函数,但总体思路是您将存储检索查询的地方。数据对象将是您的返回结果的实际对象。顺便说一下,当它开源时,这些类被拆分出来。这两个类曾经在一个类中,并使用了许多静态方法。

从这里,您可以在控制器查询中使用加载器。例如,假设您的控制器存在一个成员 $this->driver,它是一个 SlabPHP 数据库驱动程序。您的控制器有一个函数

function getArticles()
{
    try
    {
        $loader = new \My\Site\Models\Articles\Loader($this->driver);
        $this->articles = $loader->getLatestArticles();

        //$this->articles is \My\Site\Models\Articles\DataObject[] an array of dataobjects
    }
    catch (\Throwable $exception)
    {
        //handle appropriately
    }
}

如果您需要创建一个新的加载器来使用不同的数据源,这应该允许您在业务逻辑中做出非常小的更改。

数据模型连接

这个库还包含了一种可能简单的方法来创建使用联合查询和连接的层次数据结构。例如,假设我们想要向我们的文章中添加一个作者对象。我们有一个另一个 "authors" 表,其中已经创建了以下数据模型。

namespace \My\Site\Models\Author;

class DataObject extends \Slab\Database\Models\MySQL\DataObject
{
    const DATA_LOADER = '\My\Site\Models\Author\Loader';

    public $id;

    public $name;

    public $lastPostDate;
}

作者加载器如下所示

namespace \My\Site\Models\Author;

class Loader extends \Slab\Database\Models\MySQL\Loader
{
    const DATA_OBJECT_CLASS = '\My\Site\Models\Author\DataObject';

    const TABLE_NAME = 'authors';

    protected $mapping = [
        'id' => 'id',
        'name' => 'name',
        'last_post_date' => 'lastPostDate:date'
    ];
}

我们可以修改 Article\Loader() 类中的 getLatestArticles 来使其看起来像这样

public function getLatestArticles()
{
    // Step 1, create a join helper. it just means we want to join the author DataObject with a table alias of 'a' and
    // put it in the 'author' member of the resulting object
    $authorJoin = new \Slab\Database\Models\MySQL\Join('\My\Site\Models\Author\DataObject', 'a', 'author');

    // Step 2, add the Author data object fields to the select
    $sql = "select " . $this->getMappingSQL() . ", " . $authorJoin->getMappingSQL();

    $sql .= " from " . $this->getTable() . " order by date_created desc limit 20;";

    // Step 3, finally we craft an array with the returned class as array object 1, and the joins as extra elements
    // This is admittedly kind of a bad design since its unintuitive. Maybe we can fix it later?
    $resultObject = $this->driver->query($sql, [], [static::DATA_OBJECT_CLASS, $authorJoin]);

    return $resultObject->result();
}

现在,当控制器运行时,您的返回对象将如下所示,其中作者对象从响应字段映射到 Author 子对象。

Article Object
(
    [id] => 1
    [title] => First Article
    [body] => Hello, this is my first article
    [created] => DateTime Object
        (
            [date] => 2018-02-05 00:00:00.00000
            [timezone_type] => 3
            [timezone] => America/New_York
        )
    [authorId] => 14
    [author] => Author Object
        (
            [id] => 14
            [name] => Steven Exampler
            [lastPostDate] => DateTime Object
                (
                    [date] => 2018-02-05 00:00:00.00000
                    [timezone_type] => 3
                    [timezone] => America/New_York
                )
        )
)

注意,带有 :date 后的映射字段会自动转换为 \DateTime 对象。这不仅仅适用于连接,即使没有它也会发生。

脚手架

您可以使用 Scaffold 类从您数据库中已创建的表中构建加载器和数据对象模型。它需要您包含 mustache/mustache 包。假设您已经设置了一个驱动程序,您可以通过以下类似操作快速编写脚手架文件

$scaffold = new \Slab\Database\Models\MySQL\Scaffold($db);

$scaffold->writeScaffold('mysql_table_name', '\My\Site\Models', 'Thing', '/my/site/src/Models');

这将创建两个文件

/my/site/src/Models/Thing/DataObject.php
/my/site/src/Models/Thing/Loader.php

它将运行一个 DESCRIBE mysql_table_name sql 查询,并使用输出构建这两个文件。