一个最小化设置、易于使用的ORM和数据库抽象库

0.6.0 2016-06-03 19:18 UTC

README

Link是一个ORM和数据库抽象库,深受ActiveRecordAREL的启发。就像ActiveRecord一样,Link更倾向于使用约定而非配置,移除了需要长期映射文件和冗长重复的类定义的需求。

Link分为3个模块,旨在供开发者使用:连接AST实体。以下是这三个模块的简要描述,作为入门指南,但要了解每个模块如何工作,请查看每个模块的单独README。

连接模块

连接模块为Link的其他两个模块提供基础。它告诉Link如何将其所有抽象信息转换为数据库能理解的东西。

使用连接模块很简单,基本上无论连接到什么数据库都是一样的。以下示例中将连接到MySQL数据库。

<?php
    // include autoloader

    $adapter = new DaybreakStudios\Link\Connection\Adapter\MySqlPdoAdapter('demo', '127.0.0.1', 'username', 'password');
    
    DaybreakStudios\Link\Connection\Connection::create($adapter);

看起来很简单,对吧?Link为许多不同的数据库提供适配器,连接到你的数据库就像使用适合你项目需求的适配器一样简单。

默认情况下,Link将创建的第一个连接视为默认连接。Link中的所有其他模块都默认使用此连接。这样,你就不需要担心传递新的连接实例,或者将其注册为全局变量。

但是,如果你需要在模块中使用不同的连接,每个模块都提供自己的机制来临时(或永久)更改使用的连接。有关如何操作和有关与连接模块一起工作的完整文档,请查看完整的README

AST模块

我们的抽象金字塔直接位于连接模块之上的是AST层。AST提供了一种通过编程生成平台无关SQL的机制。它与AREL共享大部分语法和约定,尽管你会注意到一些更改和改进。

可以使用AST模块像这样编写简单的选择语句

<?php
    use DaybreakStudios\Link\AST\Table;
    
    $users = new Table('users', 'u'); // The second argument is optional, and defines the table's alias
    $sql = $users
        ->project('*')
        ->where($users['email']->eq('tyler@example.com'))
        ->getSql();
        
    // SELECT * FROM `users` `u` WHERE `u`.`email` = 'tyler@example.com';

可以通过链式调用生成更复杂的选择语句。

<?php
    use DaybreakStudios\Link\AST\Table;
    
    $users = new Table('users', 'u');
    $sql = $users
        ->project('*')
        ->where($users['email']->eq('tyler@example.com')->and($users['deleted']->eq(false))
        ->getSql();
        
    // SELECT * FROM `users` `u` WHERE `u`.`email` = 'tyler@exmaple.com' AND `u`.`deleted` = FALSE

所有值都使用你之前定义的数据库适配器进行了适当转义。

<?php
    use DaybreakStudios\Link\AST\Table;
    
    // Let's pretend you got this from a login for, entered by one of your users
    $userEmail = "tyler@example.com\'; drop table users;";
    
    $users = new Table('users', 'u');
    $sql = $users
        ->project('*')
        ->where($users['email']->eq($userEmail))
        ->getSql();
        
    // SELECT * FROM `users` `u` WHERE `u`.`email` = 'tyler@example.com\\\'; drop table users;'

AST模块还支持连接、调用SQL函数和许多其他功能。请查看AST模块的完整文档

实体模块

实体模块是Link中抽象层次最高的模块。它允许您将行转换为对象表示,以便您可以通过编程进行操作。

创建新实体很容易。假设你有一个名为users的表,该表有以下字段:idfirst_namelast_namedeleted

你所需要做的就是扩展DaybreakStudios\Link\Entity\Entity

<?php
    namespace Your\Project\Namespace\Entity;
    
    /**
     * @method string getFirstName()
     * @method $this  setFirstName(string $firstName)
     * @method string getLastName()
     * @method $this  setLastName(string $lastName)
     * @method bool   isDeleted()   
     * @method $this  setDeleted(bool $deleted)
     */
    use DaybreakStudios\Link\Entity\Entity;
    
    class User extends Entity {}

是的,这就是你需要做的。PHPDoc 块完全是可选的,但推荐使用。大多数 IDE 会使用 @method 定义进行自动完成,有地方列出可用的方法会更好。Entity 基类为 getFieldNamesetFieldNameisFieldName 提供了魔法方法。

为了将新的实体写入数据库,你可以使用 save 实例方法。

<?php
    $user = new User();
    $user
        ->setFirstName('Tyler')
        ->setLastName('Example')
        ->setDeleted(false)
        ->save();
        
    printf("Created User#%d\n", $user->getId()); 

调用 save 将执行其名称所暗示的操作:保存你的实体。在调用 save 之后,任何列值的更改(例如,自动递增分配的 ID 或由数据库赋予默认值的未填充列)将立即可用。

此外,你可能已经注意到,示例中的每个设置器都是在前一个设置器的返回值上调用的。魔法设置器始终返回对象实例,这允许你链式调用设置器。

从数据库中检索实体同样简单。你可以使用四种不同的方法来检索实体。

<?php
     // Returns a User instance, or null if no user exists with the given ID
    $user = User::find($id);
    
    // Returns a User instance matched by the given conditions, or null if none was found.
    // Will throw a DaybreakStudios\Link\Entity\Exception\NonUniqueException if more than one row matched the
    // given conditions.
    $user = User::findOneBy([
        'first_name' => 'Tyler',
    ]);
    
    // Returns an array of User objects matching the given conditions. You may optionally provide an array of order
    // by data as the second argument (formatted "column" => "direction"), and a limit and offset as the 3rd and 4th
    // arguments, respectively.
    $users = User::findBy([
        'deleted' => false,
    ]);

查看完整的 README以获取实体模块的完整文档。