zerospam/laraval-cacheable-repository

Laravel 5 - 数据库层仓库

6.1.4 2020-09-10 15:01 UTC

README

Laravel 5 仓库用于抽象数据层,使我们的应用程序更灵活,易于维护。

你想了解更多关于仓库模式的信息? 阅读这篇优秀的文章

目录

安装

Composer

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

composer require zerospam/laravel-cacheable-repository

Laravel

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

'providers' => [
    ...
    Prettus\Repository\Providers\RepositoryServiceProvider::class,
],

如果使用 Lumen

$app->register(Prettus\Repository\Providers\LumenRepositoryServiceProvider::class);

发布配置

php artisan vendor:publish

方法

Prettus\Repository\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 = [*])
  • create(array $attributes)
  • update(array $attributes, $id)
  • updateOrCreate(array $attributes, array $values = [])
  • delete($id)
  • orderBy($column, $direction = 'asc');
  • with(array $relations);
  • has(string $relation);
  • whereHas(string $relation, closure $closure);
  • hidden(array $fields);
  • visible(array $fields);
  • scopeQuery(Closure $scope);
  • getFieldsSearchable();

Prettus\Repository\Contracts\RepositoryCriteriaInterface

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

Prettus\Repository\Contracts\CacheableInterface

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

Prettus\Repository\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 Prettus\Repository\Eloquent\BaseRepository;

class PostRepository extends BaseRepository {

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

使用方法

namespace App\Http\Controllers;

use App\PostRepository;

class PostsController extends BaseController {

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

    public function __construct(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)

创建条件

使用命令

php artisan make:criteria My

标准是一种通过应用特定条件来改变查询仓库的方法,以满足您的需求。您可以在您的仓库中添加多个标准。


use Prettus\Repository\Contracts\RepositoryInterface;
use Prettus\Repository\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 Prettus\Repository\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);

使用请求条件

RequestCriteria 是标准的标准实现。它允许过滤器根据请求中发送的参数在仓库中执行。

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

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

在仓库中启用

use Prettus\Repository\Eloquent\BaseRepository;
use Prettus\Repository\Criteria\RequestCriteria;


class PostRepository extends BaseRepository {

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

    public function boot(){
        $this->pushCriteria(app('Prettus\Repository\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('Prettus\Repository\Criteria\RequestCriteria'));
        $posts = $this->repository->all();
		...
    }

标准示例

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

http://prettus.local/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://prettus.local/users?search=John%20Doe

http://prettus.local/users?search=John&searchFields=name:like

http://prettus.local/users?search=john@gmail.com&searchFields=email:=

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

http://prettus.local/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://prettus.local/users?filter=id;name

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

排序结果

http://prettus.local/users?filter=id;name&orderBy=id&sortedBy=desc

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

通过相关表排序

http://prettus.local/users?orderBy=posts|title&sortedBy=desc

查询将类似于以下内容

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

http://prettus.local/users?orderBy=posts:custom_id|posts.title&sortedBy=desc

查询将类似于以下内容

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

添加关联

http://prettus.local/users?with=groups

覆盖参数名称

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

缓存

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

缓存使用

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

use Prettus\Repository\Eloquent\BaseRepository;
use Prettus\Repository\Contracts\CacheableInterface;
use Prettus\Repository\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 Prettus\Repository\Eloquent\BaseRepository;
use Prettus\Repository\Contracts\CacheableInterface;
use Prettus\Repository\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