nascentafrica/eloquent-repository

Laravel模型存储库包。

v1.2.1 2020-05-24 01:03 UTC

This package is auto-updated.

Last update: 2024-09-06 11:43:37 UTC


README

Eloquent Repository用于抽象数据层,使我们的应用程序更灵活,易于维护。

感谢Anderson Andrade为此项目,这是一个andersao/l5-repository的简化版。这样做是因为我更愿意在其他地方而不是在存储库中执行验证和转换。

安装

Composer

执行以下命令以获取包的最新版本

composer require nascentafrica/eloquent-repository

Laravel

>= laravel5.5

ServiceProvider将自动附加

其他

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

'providers' => [
    ...
    NascentAfrica\EloquentRepository\RepositoryServiceProvider::class,
],

如果使用Lumen

$app->register(NascentAfrica\EloquentRepository\LumenRepositoryServiceProvider::class);

发布配置

php artisan vendor:publish --provider "NascentAfrica\EloquentRepository\Providers\RepositoryServiceProvider"

方法

NascentAfrica\EloquentRepository\Contracts\RepositoryInterface

  • all($columns = array('*'))
  • first($columns = array('*'))
  • paginate($limit = null, $columns = ['*'])
  • find($id, $columns = ['*'])
  • findByField($field, $value, $columns = ['*'])
  • findWhere(array $where, $columns = ['*'])
  • findWhereIn($field, array $where, $columns = [*])
  • findWhereNotIn($field, array $where, $columns = [*])
  • findWhereBetween($field, array $where, $columns = [*])
  • count()
  • countWhere(array $where = [], $columns = '*'): int
  • create(array $attributes)
  • update(array $attributes, $id)
  • updateOrCreate(array $attributes, array $values = [])
  • delete($id)
  • deleteWhere(array $where)
  • orderBy($column, $direction = 'asc');
  • onlyTrashed()
  • pluck($column, $key = null)
  • with(array $relations)
  • has(string $relation)
  • whereHas(string $relation, closure $closure)
  • function withTrashed()
  • hidden(array $fields)
  • visible(array $fields)
  • search($search = '', $callback = null)
  • scopeQuery(Closure $scope)
  • getFieldsSearchable()
  • setPresenter($presenter)
  • skipPresenter($status = true)

NascentAfrica\EloquentRepository\Contracts\RepositoryCriteriaInterface

  • pushCriteria($criteria)
  • popCriteria($criteria)
  • getCriteria()
  • getByCriteria(CriteriaInterface $criteria)
  • skipCriteria($status = true)
  • getFieldsSearchable()

NascentAfrica\EloquentRepository\Contracts\CacheableInterface

  • setCacheRepository(CacheRepository $repository)
  • getCacheRepository()
  • getCacheKey($method, $args = null)
  • getCacheMinutes()
  • skipCache($status = true)

NascentAfrica\EloquentRepository\Contracts\CriteriaInterface

  • apply($model, RepositoryInterface $repository);

使用

创建模型

正常创建模型,但重要的是要定义可以从输入表单数据填充的属性。

namespace App;

class Post extends Eloquent { // or Ardent, Or any other Model Class

    protected $fillable = [
        'title',
        'author',
        ...
     ];

     ...
}

创建存储库

namespace App;

use NascentAfrica\EloquentRepository\BaseRepository;

class PostRepository extends BaseRepository {

    /**
     * Specify Model class name
     *
     * @return string
     */
    function model()
    {
        return "App\\Post";
    }
}

生成器

通过生成器轻松创建存储库。

配置

您必须首先配置存储库文件的存储位置。默认为“app”文件夹和命名空间“App”。请注意,namespaces数组中的值实际上用作命名空间和文件路径。

    ...
    'generator'  => [
        'basePath'      => app()->path(),
        'rootNamespace' => 'App\\',
        'namespaces'       => [
            'repositories' => '\Repositories',
            'interfaces'   => '\Contracts\Repositories',
            'criteria'     => '\Criteria',
            'providers'    => '\Providers',
            'models'        => '',
        ],

        'provider'  => 'RepositoryServiceProvider'
    ]

您可能希望将项目的根目录保存在app之外,并添加另一个命名空间,例如

    ...
     'generator'=>[
        'basePath'      => base_path('src/Lorem'),
        'rootNamespace' => 'Lorem\\'
    ]

此外,您可能希望自定义生成类最终保存的位置。这可以通过编辑paths节点来实现。例如

    ...
    'generator'  => [
        'basePath'      => app()->path(),
        'rootNamespace' => 'App\\',
        'namespaces'       => [
            'repositories' => '\Repositories',
            'interfaces'   => '\Repositories',
            'criteria'     => '\Criteria',
            'providers'    => '\Providers',
            'models'        => '\Models',
        ],

        'provider'  => 'RepositoryServiceProvider'
    ]

命令

要为您的模型生成所需的一切,请运行此命令

<<<<<<< HEAD
php artisan na:repository PostRepository --model=Post
=======
php artisan na:repository PostRepository
>>>>>>> aa40fb6f34dd8e5e93b893a7a96ace525b35c4f3

如果模型不存在,此命令将创建模型、存储库和接口类。如果不存在,它还会创建一个新的RepositoryServiceProvider,该服务提供者将用于将Eloquent存储库与其对应的存储库接口绑定。要加载它,只需将其添加到您的AppServiceProvider@register方法中

    $this->app->register(RepositoryServiceProvider::class);

运行命令时,您将在您设置的默认文件夹中创建“Entities”文件夹和“Repositories”

现在,您还需要在您的实际存储库中绑定其接口,例如在您的自己的存储库服务提供者中

App::bind('{YOUR_NAMESPACE}Repositories\PostRepository', '{YOUR_NAMESPACE}Repositories\PostRepositoryEloquent');

然后使用

public function __construct({YOUR_NAMESPACE}Repositories\PostRepository $repository){
    $this->repository = $repository;
}

在存储库中查找所有结果

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

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

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

按id查找结果

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

隐藏模型属性

$post = $this->repository->hidden(['country_id'])->find($id);

仅显示模型的具体属性

$post = $this->repository->visible(['id', 'state_id'])->find($id);

加载模型关系

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

按字段名查找结果

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

按多个字段查找结果

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

按一个字段中的多个值查找结果

$posts = $this->repository->findWhereIn('id', [1,2,3,4,5]);

按一个字段中排除多个值查找结果

$posts = $this->repository->findWhereNotIn('id', [6,7,8,9,10]);

使用自定义范围查找所有结果

$posts = $this->repository->scopeQuery(function($query){
    return $query->orderBy('sort_order','asc');
})->all();

在存储库中创建新条目

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

在存储库中更新条目

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

在存储库中删除条目

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

按多个字段在存储库中删除条目

$this->repository->deleteWhere([
    //Default Condition =
    'state_id'=>'10',
    'country_id'=>'15',
])

创建一个标准

使用命令

php artisan na:criteria MyCriteria

标准是按照您的需求应用特定条件来更改查询存储库的一种方式。您可以在存储库中添加多个标准。

use NascentAfrica\EloquentRepository\Contracts\RepositoryInterface;
use NascentAfrica\EloquentRepository\Contracts\CriteriaInterface;

class MyCriteria implements CriteriaInterface {

    public function apply($model, RepositoryInterface $repository)
    {
        $model = $model->where('user_id','=', Auth::user()->id );
        return $model;
    }
}

在控制器中使用标准

namespace App\Http\Controllers;

use App\PostRepository;

class PostsController extends BaseController {

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

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


    public function index()
    {
        $this->repository->pushCriteria(new MyCriteria1());
        $this->repository->pushCriteria(MyCriteria2::class);
        $posts = $this->repository->all();
		...
    }

}

从标准中获取结果

$posts = $this->repository->getByCriteria(new MyCriteria());

在存储库中设置默认标准

use NascentAfrica\EloquentRepository\Eloquent\BaseRepository;

class PostRepository extends BaseRepository {

    public function boot(){
        $this->pushCriteria(new MyCriteria());
        // or
        $this->pushCriteria(AnotherCriteria::class);
        ...
    }

    function model(){
       return "App\\Post";
    }
}

跳过存储库中定义的标准

在使用任何其他链式方法之前,使用skipCriteria

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

弹出标准

使用popCriteria来删除一个标准

$this->repository->popCriteria(new Criteria1());
// or
$this->repository->popCriteria(Criteria1::class);

使用请求标准

请求标准是一个标准的标准实现。它允许过滤器从请求中发送的参数在存储库中执行。

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

要在您的存储库中使用标准,您可以在存储库的boot方法中添加一个新的标准,或者直接在控制器中使用,以便仅过滤出少量请求。

在存储库中启用

use NascentAfrica\EloquentRepository\BaseRepository;
use NascentAfrica\EloquentRepository\Criteria\RequestCriteria;


class PostRepository extends BaseRepository {

	/**
     * @var array
     */
    protected $fieldSearchable = [
        'name',
        'email'
    ];

    public function boot(){
        $this->pushCriteria(app('NascentAfrica\EloquentRepository\Criteria\RequestCriteria'));
        ...
    }

    function model(){
       return "App\\Post";
    }
}

记住,您需要定义模型中哪些字段可以搜索。

在您的存储库中,将$fieldSearchable设置为要搜索的字段名称或字段关系。

protected $fieldSearchable = [
	'name',
	'email',
	'product.name'
];

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

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

在控制器中启用

	public function index()
    {
        $this->repository->pushCriteria(app('NascentAfrica\EloquentRepository\Criteria\RequestCriteria'));
        $posts = $this->repository->all();
		...
    }

示例标准

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

https:///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"
    }
]

在存储库中进行研究

https:///users?search=John%20Doe

https:///users?search=John&searchFields=name:like

https:///users?search=john@gmail.com&searchFields=email:=

https:///users?search=name:John Doe;email:john@gmail.com

https:///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"
    }
]

默认情况下,请求标准使用每个查询参数的OR比较操作符进行查询。https:///users?search=age:17;email:john@gmail.com

上述示例将执行以下查询

SELECT * FROM users WHERE age = 17 OR email = 'john@gmail.com';

要使用AND查询,请传递以下searchJoin参数

https:///users?search=age:17;email:john@gmail.com&searchJoin=and

过滤字段

https:///users?filter=id;name

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

排序结果

https:///users?filter=id;name&orderBy=id&sortedBy=desc

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

通过相关表排序

https:///users?orderBy=posts|title&sortedBy=desc

查询将如下所示

...
INNER JOIN posts ON users.post_id = posts.id
...
ORDER BY title
...

https:///users?orderBy=posts:custom_id|posts.title&sortedBy=desc

查询将如下所示

...
INNER JOIN posts ON users.custom_id = posts.id
...
ORDER BY posts.title
...

添加关系

https:///users?with=groups

覆盖参数名称

您可以在配置文件config/repository.php中更改参数的名称

缓存

轻松为您的仓库添加缓存层

缓存使用

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

use NascentAfrica\EloquentRepository\BaseRepository;
use NascentAfrica\EloquentRepository\Contracts\CacheableInterface;
use NascentAfrica\EloquentRepository\Traits\CacheableRepository;

class PostRepository extends BaseRepository implements CacheableInterface {

    use CacheableRepository;

    ...
}

完成,这样您的仓库就会被缓存,每当创建、修改或删除一个项目时,仓库缓存都会被清除。

缓存配置

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

config/repository.php

'cache'=>[
    //Enable or disable cache repositories
    'enabled'   => true,

    //Lifetime of cache
    'minutes'   => 30,

    //Repository Cache, implementation Illuminate\Contracts\Cache\Repository
    'repository'=> 'cache',

    //Sets clearing the cache
    'clean'     => [
        //Enable, disable clearing the cache on changes
        'enabled' => true,

        'on' => [
            //Enable, disable clearing the cache when you create an item
            'create'=>true,

            //Enable, disable clearing the cache when upgrading an item
            'update'=>true,

            //Enable, disable clearing the cache when you delete an item
            'delete'=>true,
        ]
    ],
    'params' => [
        //Request parameter that will be used to bypass the cache repository
        'skipCache'=>'skipCache'
    ],
    'allowed'=>[
        //Allow caching only for some methods
        'only'  =>null,

        //Allow caching for all available methods, except
        'except'=>null
    ],
],

您可以直接在仓库中覆盖这些设置。

use NascentAfrica\EloquentRepository\BaseRepository;
use NascentAfrica\EloquentRepository\Contracts\CacheableInterface;
use NascentAfrica\EloquentRepository\Traits\CacheableRepository;

class PostRepository extends BaseRepository implements 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、getByCriteria

许可证

本软件根据 MIT 许可证 (MIT) 发布。