nilportugues / eloquent-mongodb-repository
Eloquent MongoDB 仓库实现
Requires
- illuminate/database: ^5.2
- illuminate/pagination: ^5.2
- jenssegers/mongodb: v3.0.*
- nilportugues/assert: ^1.0
- nilportugues/repository: ^2.2
Requires (Dev)
- fabpot/php-cs-fixer: 1.9.*
- phpunit/phpunit: 4.8.*
Suggests
- nilportugues/eloquent-repository: SQL Eloquent Repository implementation.
- nilportugues/filesystem-repository: FileSystem repository implementation.
- nilportugues/mongodb-repository: MongoDB Repository implementation.
- nilportugues/repository-cache: Cache any nilportugues/repository implementation.
This package is not auto-updated.
Last update: 2024-09-14 17:53:40 UTC
README
使用 nilportugues/repository 作为基础,并使用 jenssegers/mongodb 的 Eloquent MongoDB 仓库。
安装
使用 Composer 安装此包
$ composer require nilportugues/eloquent-mongodb-repository
为什么?驱动程序和多种实现!
使用此实现,您可以在不设置数据库的情况下切换以测试代码。
听起来不实用?让我们再想一个您会喜欢的用例。 功能测试
和 单元测试
。
不需要数据库连接或伪造。使用 InMemoryRepository
或 FileSystemRepository
实现将使这些测试变得容易编写。并且一旦测试完成,所有数据都可以无后顾之忧地销毁。
可用驱动程序
此外,如果您想更改仓库实现,不需要进行任何逻辑更改,因为有一组开箱即用的驱动程序可供您使用
- 使用
composer require nilportugues/repository-cache
安装 缓存。 - 使用
composer require nilportugues/repository
安装 InMemoryRepository 实现。 - 使用
composer require nilportugues/filesystem-repository
安装 FileSystemRepository 实现。 - 使用
composer require nilportugues/eloquent-repository
安装 SQL Eloquent 实现。 - 使用
composer require nilportugues/doctrine-repository
安装 SQL Doctrine 实现。
用法
设置 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。
如果您发现任何遵守上的疏忽,请通过 Pull Request 发送补丁。
贡献
始终欢迎对该包的贡献!
支持
使用以下方式之一与我联系
- 通过电子邮件联系我 contact@nilportugues.com
- 打开一个 问题
作者
许可证
代码库在 MIT 许可证 下授权。