nilportugues/eloquent-mongodb-repository

2.2.1 2016-03-19 15:43 UTC

This package is not auto-updated.

Last update: 2024-09-14 17:53:40 UTC


README

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

使用 nilportugues/repository 作为基础,并使用 jenssegers/mongodb 的 Eloquent MongoDB 仓库。

安装

使用 Composer 安装此包

$ composer require nilportugues/eloquent-mongodb-repository

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

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

听起来不实用?让我们再想一个您会喜欢的用例。 功能测试单元测试

不需要数据库连接或伪造。使用 InMemoryRepositoryFileSystemRepository 实现将使这些测试变得容易编写。并且一旦测试完成,所有数据都可以无后顾之忧地销毁。

可用驱动程序

此外,如果您想更改仓库实现,不需要进行任何逻辑更改,因为有一组开箱即用的驱动程序可供您使用

用法

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

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

$capsule = new Capsule();
$capsule->getDatabaseManager()->extend('mongodb', function($config) {
    return new \Jenssegers\Mongodb\Connection($config);
});

$capsule->addConnection([
        'driver' => 'mongodb',
        'host' => 'localhost',
        'port' => 27017,
        'database' => 'default',
        'username' => '',
        'password' => '',
        'options' => [
            'db' => 'admin'
        ]
    ],
    'default'
);
$capsule->bootEloquent();
$capsule->setAsGlobal();

现在 Eloquent 已运行,我们可以使用仓库。

关于 MongoDB 模型的说明

为了确保与其他仓库实现的最大兼容性,最好 忽略 MongoDB 的 ObjectId 字段: _id 并声明一个类似于 id 的字段。这意味着,不使用 MongoDB 的 ObjectId 来获取元素。

这也意味着您需要从 MongoDB 对象构建一个适配器来生成预期的业务对象。更多内容请参考下面的内容,或查看 /example 目录。

一个仓库对应一个 Eloquent 模型

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

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

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

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

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

完整的实现应大致如下

<?php
use NilPortugues\Foundation\Infrastructure\Model\Repository\EloquentMongoDB\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()
        );
    } 

    /**
     * {@inheritdoc}
     */
    public function add(Identity $value)
    {
        $value = $this->userAdapter->toEloquent($value);

        return parent::add($value);
    }

    /**
     * {@inheritdoc}
     */
    public function addAll(array $values)
    {
        $eloquent = [];
        foreach ($values as $value) {
            $eloquent[] = $this->userAdapter->toEloquent($value);
        }

        parent::addAll($eloquent);
    }
    
   /**
    * @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 目录中找到示例实现。

一个 EloquentRepository 对应所有 Eloquent 模型

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

尽管代码量比上一个示例少,但请注意,您的代码将与 Eloquent 紧耦合。

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

class EloquentMongoDBRepository extends EloquentRepository
{
    /**
     * @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);

注意键 name 如何与 users 表中的数据库列 name 匹配。

可用选项

Filter 允许您使用 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)
  • public function notEqual($filterName, $value)
  • public function includeGroup($filterName, array $value)
  • public function notIncludeGroup($filterName, array $value)
  • public function range($filterName, $firstValue, $secondValue)
  • public function notRange($filterName, $firstValue, $secondValue)
  • public function notContain($filterName, $value)
  • public function contain($filterName, $value)
  • public function beGreaterThanOrEqual($filterName, $value)
  • public function beGreaterThan($filterName, $value)
  • public function beLessThanOrEqual($filterName, $value)
  • public function 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 测试,请转到测试目录并运行 phpunit。

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

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

贡献

始终欢迎对该包的贡献!

支持

使用以下方式之一与我联系

作者

许可证

代码库在 MIT 许可证 下授权。