eilander/repository

灵活的 Laravel 5 仓库包。

v5.8.0 2019-08-21 08:03 UTC

This package is auto-updated.

Last update: 2024-09-21 20:12:56 UTC


README

Repository Pattern 的 Laravel 实现

The repository mediates between the data source layer and the business layers of the application. It queries the data source for the data, maps the data from the data source to a business entity, and persists changes in the business entity to the data source. A repository separates the business logic from the interactions with the underlying data source or Web service.

进一步阅读: http://ryantablada.com/post/two-design-patterns-that-will-make-your-applications-better

目录

[目录]

使用方法

步骤 1:添加服务提供者

在您的 config/app.php 中,将 Eilander\Repository\Providers\RepositoryServiceProvider:class 添加到 providers 数组的末尾

<?php
'providers' => [
    ...
    Eilander\Repository\Providers\RepositoryServiceProvider::class,
],

步骤 2:添加包到 composer.json 以实现自动加载

将包添加到主 composer.json 中以实现自动加载,并运行 composer dump-autoload,如下所示

<?php
   "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/",
            "Eilander\\Repository\\": "../library/eilander/repository/src/"
        }
    },
#!json

composer dump-autoload

步骤 3:在 ApiServiceProvider 中将接口绑定到实现

<?php
    public function register()
    {
        // Bind FruitRepository interface to Elasticsearch\FruitRepository implementation
        $this->app->bind('Modules\Api\Repositories\FruitRepository', 'Modules\Api\Repositories\Elasticsearch\FruitRepository');
        $this->app->bind('Modules\Api\Repositories\FruitRepository', 'Modules\Api\Repositories\Eloquent\FruitRepository');
    }

Elasticsearch

方法

在 Elasticsearch 仓库中搜索

$posts = $this->repository->query($selection = '');

当您使用 ElasticsearchGateway 时,过滤器将自动从以下格式的 URL 中解析出来

http://www.url.nl?filter={"provider":["kpn","vodafone"],"betweenDate":["2015-01-01","2015-12-31"]}

betweenDate

BetweenDate 是一个特殊函数,使得在 Elasticseaerch 中使用日期直方图变得轻而易举。它期望一个起始日期和结束日期,并将其解析为一个功能齐全的日期直方图。

Eloquent

方法

在仓库中查找所有结果

$posts = $this->repository->all();

使用分页在仓库中查找所有结果

$posts = $this->repository->paginate($limit = null, $columns = ['*']);

通过 ID 查找结果

$post = $this->repository->find($id);

加载模型关系

$post = $this->repository->with(['state'])->find($id);

通过字段名称查找结果

$posts = $this->repository->findByField('country_id','15');

通过多个字段查找结果

$posts = $this->repository->where([
    //Default Condition =
    'state_id'=>'10',
    'country_id'=>'15',
    //Custom Condition
    ['columnName','>','10']
]);

在仓库中创建新条目

$post = $this->repository->create( Input::all() );

更新仓库中的条目

$post = $this->repository->update( Input::all(), $id );

删除仓库中的条目

$this->repository->delete($id)

使用过滤器

仓库代码足够智能,可以执行来自请求参数的过滤和搜索。

您可以执行动态搜索,过滤数据并自定义查询。

在仓库中启用

<?php

namespace App\Repositories\Eloquent;

use Eilander\Repository\Eloquent\BaseRepository;
use Eilander\Repository\Contracts\CacheableInterface;
use App\Repositories\FruitRepository as Repository;
use App\Presenters\FruitPresenter;
use App\Entities\Fruit;

/**
 * Class FruitRepository
 */
class FruitRepository extends BaseRepository implements Repository
{
     /**
     * @var array
     */
    protected $fieldSearchable = [
        'name',
        'email'
    ];
    ...
}

您可以设置用于执行查询的条件类型,默认条件是 "="

protected $fieldSearchable = [
    'name'=>'like',
    'email', // Default Condition "="
    'your_field'=>'condition'
];

示例

通过请求请求所有数据而不进行筛选

http://stash.directsurvey.nl/api/v1/users

[
    {
        "id": 1,
        "name": "John Doe",
        "email": "john@gmail.com",
        "created_at": "-0001-11-30 00:00:00",
        "updated_at": "-0001-11-30 00:00:00"
    },
    {
        "id": 2,
        "name": "Lorem Ipsum",
        "email": "lorem@ipsum.com",
        "created_at": "-0001-11-30 00:00:00",
        "updated_at": "-0001-11-30 00:00:00"
    },
    {
        "id": 3,
        "name": "Laravel",
        "email": "laravel@gmail.com",
        "created_at": "-0001-11-30 00:00:00",
        "updated_at": "-0001-11-30 00:00:00"
    }
]

在仓库中进行研究

http://stash.directsurvey.nl/api/v1/users?search=John%20Doe

http://stash.directsurvey.nl/api/v1/users?search=John&searchFields=name:like

http://stash.directsurvey.nl/api/v1/users?search=john@gmail.com&searchFields=email:=

http://stash.directsurvey.nl/api/v1/users?search=name:John Doe;email:john@gmail.com

http://stash.directsurvey.nl/api/v1/users?search=name:John;email:john@gmail.com&searchFields=name:like;email:=

[
    {
        "id": 1,
        "name": "John Doe",
        "email": "john@gmail.com",
        "created_at": "-0001-11-30 00:00:00",
        "updated_at": "-0001-11-30 00:00:00"
    }
]

筛选字段 http://stash.directsurvey.nl/api/v1/users?filter=id;name

[
    {
        "id": 1,
        "name": "John Doe"
    },
    {
        "id": 2,
        "name": "Lorem Ipsum"
    },
    {
        "id": 3,
        "name": "Laravel"
    }
]

排序结果 http://stash.directsurvey.nl/api/v1/users?filter=id;name&orderBy=id&sortedBy=desc

[
    {
        "id": 3,
        "name": "Laravel"
    },
    {
        "id": 2,
        "name": "Lorem Ipsum"
    },
    {
        "id": 1,
        "name": "John Doe"
    }
]

关系

http://stash.directsurvey.nl/api/v1/users?include=groups

缓存

为您的仓库添加一个完全自动化的缓存层

缓存使用

实现接口 CacheableInterface 并使用 CacheableRepository 特性。

<?php

namespace App\Repositories\Eloquent;

use Eilander\Repository\Eloquent\BaseRepository;
use Eilander\Repository\Contracts\CacheableInterface;
use Eilander\Repository\Traits\CacheableRepository;
use App\Repositories\FruitRepository as Repository;
use App\Entities\Fruit;

/**
 * Class FruitRepository
 */
class FruitRepository extends BaseRepository implements Repository, CacheableInterface
{
    use CacheableRepository;

    ...
}

当创建、添加或删除项目时,将清除仓库缓存。

缓存配置

您可以在配置文件 config/repository.php 中更改缓存设置,或直接在您的仓库中更改。

config/repository.php

    /*
    |--------------------------------------------------------------------------
    | Cache Config
    |--------------------------------------------------------------------------
    |
    */
    'cache'=>[
        /*
         |--------------------------------------------------------------------------
         | Cache Status
         |--------------------------------------------------------------------------
         |
         | Enable or disable cache
         |
         */
        'enabled'   => true,

        /*
         |--------------------------------------------------------------------------
         | Cache Minutes
         |--------------------------------------------------------------------------
         |
         | Time of expiration cache
         |
         */
        'minutes'   => 30,

        /*
         |--------------------------------------------------------------------------
         | Cache Store Path
         |--------------------------------------------------------------------------
         |
         | Path to store cache keys in..
         |
         */
        'store'   => [
            'path' => storage_path('eilander/repository/'),
            'file' => 'cached-keys.json'
        ],

        /*
        |--------------------------------------------------------------------------
        | Methods Allowed
        |--------------------------------------------------------------------------
        |
        | methods cacheable : all, paginate, find, findByField, findWhere
        |
        | Ex:
        |
        | 'only'  =>['all','paginate'],
        |
        | or
        |
        | 'except'  =>['find'],
        */
         'allowed'=>[
             'only'  =>null,
             'except'=>null
         ],

        /*
          |--------------------------------------------------------------------------
          | Cache Clean Listener
          |--------------------------------------------------------------------------
          |
          |
          |
          */
        'clean'     => [

            /*
              |--------------------------------------------------------------------------
              | Enable clear cache on repository changes
              |--------------------------------------------------------------------------
              |
              */
            'enabled' => true,

            /*
              |--------------------------------------------------------------------------
              | Actions in Repository
              |--------------------------------------------------------------------------
              |
              | create : Clear Cache on create Entry in repository
              | update : Clear Cache on update Entry in repository
              | delete : Clear Cache on delete Entry in repository
              |
              */
            'on' => [
                'create'=>true,
                'update'=>true,
                'delete'=>true,
            ]
        ]
    ]

直接在仓库中

<?php
namespace App\Repositories\Eloquent;

use Eilander\Repository\Eloquent\BaseRepository;
use Eilander\Repository\Contracts\CacheableInterface;
use Eilander\Repository\Traits\CacheableRepository;
use App\Repositories\FruitRepository as Repository;
use App\Entities\Fruit;

/**
 * Class FruitRepository
 */
class FruitRepository extends BaseRepository implements Repository, CacheableInterface
{
    // Setting the lifetime of the cache to a repository specifically
    protected $cacheMinutes = 90;

    protected $cacheOnly = ['all', ...];
    //or
    protected $cacheExcept = ['find', ...];

    use CacheableRepository;

    ...
}

可缓存的函数是:all、paginate、find、findByField、findWhere。您还可以通过控制器中选择的函数来设置有效期:分钟、小时、天。

<?php
namespace App\Http\Controllers;

use Eilander\Repository\Listeners\EloquentClearCache;
use App\Http\Controllers\Controller;
use App\Http\Requests\FruitRequest;
use App\Repositories\FruitRepository;

class FruitController extends Controller {

    /**
     * @var FruitRepository
     */
    protected $repository;

    public function __construct(FruitRepository $repository){
        $this->repository = $repository;
    }
    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        // cache for 15 minutes
        $fruits = $this->repository->minutes(15)->paginate(50);
        or
        // cache for 6 hours
        $fruits = $this->repository->hours(6)->paginate(50);
        or
        // cache for 4 days
        $fruits = $this->repository->days(4)->paginate(50);


        return view('fruits.index', compact('fruits'));
    }