dees040/repository

Laravel仓库模式的包。

0.1.10 2020-09-14 11:47 UTC

README

本包正在开发中

这个包可以帮助你轻松地在Laravel应用中实现仓库模式。

为什么要在众多Laravel仓库包中选择这个包? 这个包受到了多个其他Laravel仓库包的启发。我从那些包中汲取了所有的好东西,创建了一个独特的包。此外,我也一直在维护这个包,因为我将它用于多个自己的项目中。

安装

您可以使用composer安装此包,运行以下命令

composer require dees040/repository

服务提供者将通过Laravel包发现自动添加。

方法

Dees040\Repository\Contracts\Repository

  • all($columns = ['*'])
  • paginate($perPage = null, $columns = ['*'])
  • first($columns = ['*'])
  • find($id, $columns = ['*'])
  • findOrFail($id, $columns = ['*'])
  • findByField($field, $value, $columns = ['*'])
  • findWhere(array $where, $columns = ['*'])
  • findWhereIn(array $where, $columns = ['*'])
  • firstOrCreate(array $attributes, array $values = [])
  • create(array $attributes = [])
  • insert(array $attributes = [])
  • update($id, array $attributes)
  • updateOrCreate(array $attributes, array $values = [])
  • delete($id)
  • deleteWhere(array $where)
  • deleteWhereIn(array $where)
  • orderBy($column, $direction = 'asc')
  • with($relations)
  • has($relation)
  • whereHas($relation, \Closure $closure)
  • orWhereHas($relation, \Closure $closure)
  • sync($id, $relation, $attributes, $detaching = true)
  • syncWithoutDetaching($id, $relation, $attributes)

用法

创建仓库

仓库可以通过手动创建或使用本包提供的命令来创建。如果您想手动创建仓库,您应该为每个仓库创建两个文件。

一个用于仓库合约的类

<?php

namespace App\Repositories\Contracts;

use Dees040\Repository\Contracts\Repository;

interface PostRepository extends Repository
{

}

一个用于实际仓库的类

<?php

namespace App\Repositories;

use App\Post;
use App\Repositories\Contracts\PostRepository;
use Dees040\Repository\Eloquent\BaseRepository;

class PostEloquentRepository extends BaseRepository implements PostRepository
{
    /**
     * Get the base model.
     *
     * @return string
     */
    public function getModel()
    {
        return Post::class;
    }
}

另一种选择是使用 make:repository 命令创建文件

php artisan make:repository Post

在控制器中使用

在创建仓库之后,您应该使用Laravel容器将仓库合约绑定到正确的仓库。这样做可以让Laravel确切地知道应该使用哪个仓库来处理哪个合约。这使得在Eloquent仓库或MongoDB仓库之间切换变得非常容易。

因此,在您的控制器中使用任何仓库之前,请确保将其绑定到容器中。您可以使用 Container 中的 bind($abstract, concrete) 方法来完成此操作。例如:App::bind(\App\Repositories\Contracts\PostRepository::class, \App\Repositories\PostEloquentRepository::class)

我个人喜欢创建一个新的服务提供者 \App\Providers\RepositoryServiceProvider.php 并做类似的事情

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class RepositoryServiceProvider extends ServiceProvider
{
    /**
     * The contracts with their associated repositories.
     *
     * @var array
     */
    protected $repositories = [
        \App\Repositories\Contracts\PostRepository::class => \App\Repositories\PostEloquentRepository::class,
    ];
    
    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
       //
    }

    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        foreach ($this->repositories as $contract => $repository) {
            $this->app->bind($contract, $repository);
        }
    }
}

绑定到容器后,您可以在控制器中使用依赖注入来获取仓库。

public function __contruct(PostRepository $repostiroy)
{
    $this->repository = $repostiroy;
}

使用条件

如果您想对数据库执行自定义查询调用,可以使用条件。您可以通过调用 pushCriteria 方法将条件添加到调用中。

$this->repository->pushCriteria(new Criteria());
$this->repository->pushCriteria(Criteria::class);

确保您的自定义条件类实现了 \Dees040\Repository\Contracts\Criteria 接口。一个自定义条件的示例是

<?php

namespace App\Criteria;

use Dees040\Repository\Contracts\Criteria;

class HasUserRelationCriteria implements Criteria
{
    /**
     * Execute the criteria.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  \Dees040\Repository\Contracts\Repository  $repository
     * @return \Illuminate\Database\Eloquent\Model
     */
    public function apply($model, $repository)
    {
        return $this->model->orderBy('created_at')
            ->whereHas('users', function ($query) {
                $query->where('users.id', 1);
            });
    }
}

RequestCriteria

该包自带了一个有用的条件 RequestCriteria。它允许您通过路由参数轻松地在查询上执行额外操作。您可以在仓库的构造函数中默认添加条件

public function __construct()
{
    $this->pushCriteria(\Dees040\Repository\Criteria\RequestCriteria::class);
}

完成此操作后,您可以添加以下查询参数。

  • https://example.test/posts?order_by=created_at
  • https://example.test/posts?order_by=created_at&sort_by=desc
  • https://example.test/posts?search=Lorem ipsum
  • https://example.test/posts?search=Lorem ipsum&search_fields=body
  • https://example.test/posts?search=Lorem ipsum&search_fields=title,body:like
  • https://example.test/posts?search=Lorem ipsum&search_fields=title,body:like&order_by=title

如果您想拥有搜索功能,您应该在您的仓库中重写 getSearchableFields() 方法。该方法返回的数组中的所有字段都可以通过路由参数进行搜索。

/**
 * Get all fields which are searchable.
 *
 * @return array
 */
public function getSearchableFields()
{
    return [
        'title',
        'body',
    ];
}

待办事项

  • 为请求创建内置的准则类
  • 在请求准则中搜索字段
  • 创建缓存
  • 解析结果
  • 分页选项
  • 在请求准则中搜索自定义字段
  • 动态准则类
  • 在搜索字段上使用正则表达式拆分
  • 在请求准则中添加点关系
  • 创建命令