lrc-se/anax-repository

基于模型的数据库访问的存储库模块,与Anax框架一起使用。

1.1.0 2017-10-23 15:28 UTC

This package is not auto-updated.

Last update: 2024-09-29 04:42:57 UTC


README

Latest Stable Version Travis CI Build Status Scrutinizer Build Status Scrutinizer Code Quality Scrutinizer Code Coverage

为模块化Anax框架提供的存储库模块,通过一致的用户界面提供基于模型的数据库访问。目前,包含的实现仅适用于关系数据库。

此模块旨在替代anax/database中的现有ActiveRecordModel,在提供更好的语义适应性的同时,也更容易管理和测试,尤其是在依赖注入方面。

此模块还提供按需使用的自动软删除功能。

要求

  • PHP 5.6+
  • anax/database 1.1.0+ (1.1.6+ 用于包含的测试)

使用方法

要在Anax安装中使用此模块,请使用composer require lrc-se/anax-repository安装它。该模块本身不需要配置,但期望从anax/database实例化一个正确配置的DatabaseQueryBuilder来执行实际的数据库操作。

DbRepository

RepositoryInterface的实现。构造参数

$db,            // Anax database service (query builder)
$table,         // Name of the database table the repository represents
$modelClass,    // Name of the model class representing each repository entry
$key            // Name of the primary key column (optional, defaults to 'id')

示例

// setup
$db = (new \Anax\Database\DatabaseQueryBuilder())->configure('db.php');
$books = new \LRC\Repository\DbRepository($db, 'book', Book::class);

// count entries
echo $books->count();

// retrieve entries
$allBooks = $books->getAll();
$firstBook = $books->getFirst();
$book = $books->find('id', 2);

// update entry
$book->title .= ' (2nd revision)';
$book->published = date('Y');
$books->save($book);

// delete entry
$books->delete($book);
$book2 = $books->find('id', 2);
var_dump($book->id);    // null
var_dump($book2);       // false (standard "no result" return value from PDO)

// re-insert entry
$books->save($book);
var_dump($book->id);    // higher than 2 since the entry was re-inserted, not updated

// use criteria and query options
$filteredBook = $books->getFirst('published < 2000', [], ['order' => 'published DESC']);
$match = 'Tolkien';
$filteredBooks = $books->getAll(
    'author LIKE ?',
    ["%{$match}%"],
    [
        'order' => 'title',
        'limit' => 5,
        'offset' => 2
    ]
);

请参阅RepositoryInterface以获取主要API的完整说明。

SoftDbRepository

SoftRepositoryInterface的实现,增加了软删除意识。构造参数

$db,            // Anax database service (query builder)
$table,         // Name of the database table the repository represents
$modelClass,    // Name of the model class representing each repository entry
$deleted,       // Name of the attribute used to flag deletion (optional, defaults to 'deleted')
$key            // Name of the primary key column (optional, defaults to 'id')

示例

// setup
$db = (new \Anax\Database\DatabaseQueryBuilder())->configure('db.php');
$books = new \LRC\Repository\SoftDbRepository($db, 'book', Book::class);

// count non-deleted entries
echo $books->countSoft();

// retrieve non-deleted entries
$allBooks = $books->getAllSoft();
$firstBook = $books->getFirstSoft();
$book = $books->findSoft('id', 3);

// soft-delete entry
$books->deleteSoft($book);
$book2 = $books->findSoft('id', 3);
var_dump($book->id);        // still 3
var_dump($book->deleted);   // timestamp
var_dump($book2);           // false (standard "no result" return value from PDO)

// restore soft-deleted entry
$books->restoreSoft($book);
var_dump($book->deleted);   // null

请参阅SoftRepositoryInterface以获取扩展API的完整说明。

ReferenceResolverTrait

注意:此功能已弃用,转而使用下文所述的管理存储库。

在模型类中包含以获取外键引用解析。方法调用

$model->getReference(
    $repository,        // Repository to query
    $attr,              // Name of the foreign key attribute
    $key                // Name of the referenced attribute (optional, defaults to 'id')
);

如果找不到匹配的引用条目,则此方法返回null

示例

// model class
class Review
{
    use \LRC\Repository\ReferenceResolverTrait;
    
    /* ... */
}


// setup
$db = (new \Anax\Database\DatabaseQueryBuilder())->configure('db.php');
$books = new \LRC\Repository\DbRepository($db, 'book', Book::class);
$reviews = new \LRC\Repository\DbRepository($db, 'review', Review::class);

// retrieve referenced entry
$review = $reviews->find('id', 1);
$book = $review->getReference($books, 'bookId');

SoftReferenceResolverTrait

注意:此功能已弃用,转而使用下文所述的管理存储库。

在模型类中包含以获取外键引用解析,考虑软删除。方法调用

$model->getReferenceSoft(
    $repository,        // Soft-deletion-aware repository to query
    $attr,              // Name of the foreign key attribute
    $key                // Name of the referenced attribute (optional, defaults to 'id')
);

如果找不到匹配的非删除引用条目,则此方法返回null

示例

// model class
class Review
{
    use \LRC\Repository\SoftReferenceResolverTrait;
    
    /* ... */
}


// setup
$db = (new \Anax\Database\DatabaseQueryBuilder())->configure('db.php');
$books = new \LRC\Repository\SoftDbRepository($db, 'book', Book::class);
$reviews = new \LRC\Repository\DbRepository($db, 'review', Review::class);

// retrieve non-deleted referenced entry
$review = $reviews->find('id', 1);
$book = $review->getReferenceSoft($books, 'bookId');

RepositoryManager

管理应用程序中的存储库,允许根据模型类完全自动地基于模型类进行引用解析。对于createRepository()配置数组中的键与上述存储库实现的构造参数相同,但db是数据库服务,而type指定要实例化的存储库类;当前支持值为"db"(用于DbRepository)或"db-soft"(用于SoftDbRepository,后者是默认值)。请注意,模型类仍然是单独的参数。

示例

$db = (new \Anax\Database\DatabaseQueryBuilder())->configure('db.php');
$manager = new \LRC\Repository\RepositoryManager();

// managed creation
$books = $manager->createRepository(Book::class, [
    'db' => $db,
    'type' => 'db-soft',
    'table' => 'book'
]);

// manual addition
$reviews = new \LRC\Repository\DbRepository($db, 'review', Review::class);
$manager->addRepository($reviews);

ManagedRepository

此基类使用ManagedRepositoryTrait,与上述存储库管理和下文所述的管理模型一起提供完全自动的外键解析。立即检索每个引用深入一级,之后必须使用按需获取。类DbRepositorySoftDbRepository继承自此类并实现所有必要的功能,以利用下一节中描述的引用系统。

ManagedModelTrait/SoftManagedModelTrait

RepositoryManager和上述ManagedRepository一起提供完全自动的外键解析。使用以下参数格式为setReferences()声明外键引用

[
    'name' => [         // reference name
        'attribute',    // foreign key attribute
        'model',        // model class of referenced entity
        'key',          // primary key of referenced entity (defaults to 'id')
        'magic'         // whether to make the reference available as a magic model attribute
    ],
    ...
]

示例

class Review implements \LRC\Repository\SoftManagedModelInterface
{
    use \LRC\Repository\SoftManagedModelTrait;
    
    public function __construct()
    {
        $this->setReferences([
            'book' => [
                'attribute' => 'bookId',
                'model' => Book::class,
                'magic' => true
            ]
        ]);
    }
    
    /* ... */
}


/* using the managed repositories created above */

// fetch reference on demand
$review = $reviews->find(null, 1);      // default primary key
$book = $review->getReference('book');  // explicit resolution
$book2 = $review->book;                 // magic resolution
var_dump($book);                        // <Book> model instance
var_dump($book2);                       // same as $book

// fetch reference on demand, taking soft-deletion into account
// (magic resolution always ignores soft-deletion)
$book3 = $review->getReferenceSoft('book');

// fetch references together with main entity
// (always creates true public attributes, which are skipped when saving the model back)
$review = $reviews->fetchReferences()->find(null, 1);
$book4 = $review->book;
var_dump($book4);       // same as $book and $book2, stored in <Review> object

// fetch named references together with main entity,
// taking soft-deletion into account for both
$allReviews = $reviews->fetchReferences(['book'], true)->getAllSoft();
foreach ($allReviews as $review) {
    var_dump($review->book);    // <Book> model instance stored in <Review> object,
                                // or null if the reference has been soft-deleted
}

注意

模块 anax/configure 并非这个模块本身的依赖,但它 DatabaseQueryBuilder 所需的,因此被包含在 composer.jsonrequire-dev 部分,以便单元测试能够运行。此外,注意在 anax/database 的 v1.1.6 版本之前,这一需求是针对 anax/common 的。

此外,anax/database 实际上并不需要作为依赖,只需要一个提供相同公共API的对应实现 DatabaseQueryBuilder 类即可,但它被包括作为依赖以简化实现。

关于

类型: 学校项目 @BTH
许可证: MIT
作者: LRC