nilportugues/eloquent-repository

Eloquent Repository 实现

2.2.2 2016-06-13 16:47 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:42:11 UTC


README

PHP7 Tested Build Status Scrutinizer Code Quality SensioLabsInsight Latest Stable Version Total Downloads License Donate

使用 nilportugues/repository 作为基础的 Eloquent Repository。

安装

使用 Composer 安装该包

$ composer require nilportugues/eloquent-repository

为什么?驱动和多种实现!

使用此实现,您可以在不设置数据库的情况下切换测试代码。

听起来不方便?让我们再想想您会喜欢的另一个使用场景。 功能测试单元测试

不需要数据库连接,也不需要模拟。使用 InMemoryRepositoryFileSystemRepository 实现将使这些测试变得轻而易举。测试完成后,所有数据都可以轻松销毁,无需担心。

可用驱动

此外,如果您想更改存储库实现,不需要进行任何逻辑更改,因为有一系列驱动程序供您直接使用

用法

设置 Eloquent 时,您根本不需要 Laravel 或 Lumen 框架。这就是您在任何项目中使用 Eloquent 的方法。

<?php
use Illuminate\Database\Capsule\Manager as Capsule;

$capsule = new Capsule();
$capsule->addConnection(
    [
        'driver' => 'sqlite', 
        'database' => __DIR__.'/database.db',
        'prefix' => ''
    ], 
    'default' //connection name.
);
$capsule->bootEloquent();
$capsule->setAsGlobal();

Eloquent 运行后,我们可以使用存储库。

一个存储库对应一个 Eloquent 模型

一个定义良好的存储库返回属于一个业务模型的一种类型的对象。

<?php
use NilPortugues\Foundation\Infrastructure\Model\Repository\Eloquent\EloquentRepository;

class UserRepository extends EloquentRepository 
{
    /**
     * {@inheritdoc}
     */
    protected function modelClassName()
    {
        return User::class;
    }
}

为了忠实于存储库模式,内部使用 Eloquent 模型是可以的,但业务对象应该被返回。

因此,您应该将 Eloquent 转换为业务表示,反之亦然。下面示例中的 $userAdapter 表示这一点。

完整实现应遵循以下模式

<?php
use NilPortugues\Foundation\Infrastructure\Model\Repository\Eloquent\EloquentRepository;

class UserRepository extends EloquentRepository 
{
    protected $userAdapter;
    
    /**
     * @param $userAdapter
     */
    public function __construct($userAdapter)
    {
        $this->userAdapter = $userAdapter; 
    }
    
    /**
     * {@inheritdoc}
     */
    protected function modelClassName()
    {
        return User::class;
    }
    
    /**
     * {@inheritdoc}
     */    
    public function find(Identity $id, Fields $fields = null)
    {
        $eloquentModel = parent::find($id, $fields);   
        
        return $this->userAdapter->fromEloquent($eloquentModel);
    }
    
    /**
     * {@inheritdoc}
     */    
    public function findBy(Filter $filter = null, Sort $sort = null, Fields $fields = null)
    {
        $eloquentModelArray = parent::findBy($filter, $sort, $fields);   
        
        return $this->fromEloquentArray($eloquentModelArray);
    }       
    
    /**
     * {@inheritdoc}
     */
    public function findAll(Pageable $pageable = null)
    {
        $page = parent::findAll($pageable);
        
        return new Page(
            $this->fromEloquentArray($page->content()),
            $page->totalElements(),
            $page->pageNumber(),
            $page->totalPages(),
            $page->sortings(),
            $page->filters(),
            $page->fields()
        );
    } 

   /**
    * @param array $eloquentModelArray
    * @return array
    */
   protected function fromEloquentArray(array $eloquentModelArray)
   {
        $results = [];
        foreach ($eloquentModelArray as $eloquentModel) {
            //This is required to handle findAll returning array, not objects.
            $eloquentModel = (object) $eloquentModel;
            
            $results[] = $this->userAdapter->fromEloquent($eloquentModel);
        }
        
        return $results;
   } 
}

示例实现可以在 /example 目录中找到。

所有 Eloquent 模型的单一 EloquentRepository

虽然 这不是推荐的方法,因为存储库应该只返回一种业务对象,但这与 Laravel 项目配合得很好。

虽然核心代码比上一个示例少,但请注意,您的代码将与 Eloquent 紧密耦合。

<?php
use NilPortugues\Foundation\Infrastructure\Model\Repository\Eloquent\EloquentRepository as Repository;

class EloquentRepository extends Repository
{
    /**
     * @var string
     */
    protected $modelClass;
    
    /**
     * @param string $modelClass
     */
    public function __construct($modelClass)
    {
        $this->modelClass = (string) $modelClass;
    }
    
    /**
     * {@inheritdoc}
     */
    protected function modelClassName()
    {
        return $this->modelClass;
    }
}

数据筛选

筛选就像使用 Filter 对象一样简单。例如,让我们检索名为 Ken 的用户数量。

<?php
use NilPortugues\Foundation\Domain\Model\Repository\Filter;

$repository = new UserRepository();

$filter = new Filter();
$filter->must()->contain('name', 'Ken');

echo $repository->count($filter);

请注意,键 nameusers 表中的数据库列 name 匹配。

可用选项

筛选允许您使用 must()mustNot()should() 方法来设置精细的搜索。这些提供了以下方法的流畅接口

  • public function notEmpty($filterName)
  • public function hasEmpty($filterName)
  • public function startsWith($filterName, $value)
  • public function endsWith($filterName, $value)
  • public function equal($filterName, $value)
  • 公开函数 notEqual($filterName, $value)
  • 公开函数 includeGroup($filterName, array $value)
  • 公开函数 notIncludeGroup($filterName, array $value)
  • 公开函数 range($filterName, $firstValue, $secondValue)
  • 公开函数 notRange($filterName, $firstValue, $secondValue)
  • 公开函数 notContain($filterName, $value)
  • 公开函数 contain($filterName, $value)
  • 公开函数 beGreaterThanOrEqual($filterName, $value)
  • 公开函数 beGreaterThan($filterName, $value)
  • 公开函数 beLessThanOrEqual($filterName, $value)
  • 公开函数 beLessThan($filterName, $value)

数据排序

排序方法简单。创建一个 Sort 实例,并传入列名和排序方式。

<?php
use NilPortugues\Foundation\Domain\Model\Repository\Sort;

$repository = new UserRepository();

$filter = null; //all records
$sort = new Sort(['name', 'id'], new Order('ASC', 'DESC'));
$fields = null; //all columns

$results = $repository->findBy($filter, $sort, $fields);

字段数据

创建一个 Fields 对象以获取所选列。如果没有传入 Fields 对象,默认选择所有列。

<?php
use NilPortugues\Foundation\Domain\Model\Repository\Contracts\Fields;

$repository = new UserRepository();

$filter = null; //all records
$sort = null; //existing order
$fields = new Fields(['name', 'id']);

$results = $repository->findBy($filter, $sort, $fields);

数据检索

存储库允许您使用以下方法从数据库中检索数据

  • public function findAll(Pageable $pageable = null)
  • public function find(Identity $id, Fields $fields = null)
  • public function findBy(Filter $filter = null, Sort $sort = null, Fields $fields = null)

质量

在命令行运行 PHPUnit 测试,请转到 tests 目录并输入 phpunit。

此库试图遵守 PSR-1PSR-2PSR-4

如果您发现遵守上的疏忽,请通过 Pull Request 提交补丁。

贡献

欢迎对包的贡献!

支持

您可以通过以下方式之一与我联系

作者

许可

代码库遵循 MIT 许可证