giordanolima/eloquent-repository

Eloquent ORM的仓库模式,具有强大的数据库查询缓存功能。

2.2.1 2023-07-01 16:29 UTC

README

Latest Stable Version Total Downloads License StyleCI

葡萄牙语文档。

辅助使用Eloquent ORM实现仓库模式的包。主要特点是灵活性和易用性,以及强大的查询缓存驱动器。

安装

通过Composer安装

composer require giordanolima/eloquent-repository

要配置包选项,在config / app.php文件中声明服务提供者。

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

如果你使用的是Laravel 5.5或更高版本,服务提供者将自动被Package Discover识别。

发布配置文件

php artisan vendor:publish

用法

要开始,你需要创建你的仓库类并扩展包中可用的BaseRepository。你还需要设置将用于执行查询的模型。示例

namespace App\Repositories;
use GiordanoLima\EloquentRepository\BaseRepository;
class UserRepository extends BaseRepository
{
    protected function model() {
        return \App\User::class;
    }
}

现在可以像在Elquent中一样执行查询。

namespace App\Repositories;
use GiordanoLima\EloquentRepository\BaseRepository;
class UserRepository extends BaseRepository
{
    protected function model() {
        return \App\User::class;
    }
    
    public function getAllUser(){
        return $this->all();
    }
    
    public function getByName($name) {
        return $this->where("name", $name)->get();
    }
    
    // You can create methods with partial queries
    public function filterByProfile($profile) {
        return $this->where("profile", $profile);
    }
    
    // Them you can use the partial queries into your repositories
    public function getAdmins() {
        return $this->filterByProfile("admin")->get();
    }
    public function getEditors() {
        return $this->filterByProfile("editor")->get();
    }
    
    // You can also use Eager Loading in queries
    public function getWithPosts() {
        return $this->with("posts")->get();
    }
}

要使用该类,只需将其注入到控制器中。

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Repositories\UserRepository;
class UserController extends Controller
{
    protected function index(UserRepository $repository) {
        return $repository->getAdmins();
    }
}

注入也可以在构造函数中完成,以便在所有方法中使用仓库。

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Repositories\UserRepository;
class UserController extends Controller
{
    private $repository;
	public function __construct()(UserRepository $repository) {
        $this->repository = $repository;
    }
    
    public function index() {
        return $this->repository->getAllUsers();
    }
    
}

Eloquent/QueryBuilder方法被封装为受保护的,仅在仓库类中可用。在仓库中声明自己的公开数据访问方法,以便通过控制器访问它们。

分页

默认情况下,paginate方法使用每页15条记录。此默认值可以在配置文件中设置,以便在所有仓库中使用。如果需要,您还可以覆盖perPage属性以更改单个仓库的默认值。

namespace App\Repositories;
use GiordanoLima\EloquentRepository\BaseRepository;
class UserRepository extends BaseRepository
{
    protected $perPage = 10;
    protected function model() {
        return \App\User::class;
    }
}

排序

您可以在特定仓库中声明一个字段和默认方向,用于所有查询。您仍然可以选择其他字段进行排序,或者完全跳过排序方法。

namespace App\Repositories;
use GiordanoLima\EloquentRepository\BaseRepository;
class UserRepository extends BaseRepository
{
    protected $orderBy = "created_at";
    protected $orderByDirection = "DESC";
	protected function model() {
        return \App\User::class;
    }
    
    public function getAllUser(){
        // This query will use the default ordering of the repository.
        return $this->all();
    }
    
    public function getByName($name) {
        // In this query only the declared sort will be used.
        return $this->orderBy("name")->where("name", $name)->get();
    }
    
    // É possível criar métodos com consultas parciais
    public function getWithoutOrder() {
        // In this query, no sort will be used.
        return $this->skipOrderBy()->all();
    }
    
}

全局作用域

您可以设置一个作用域,用于仓库中的所有查询。如果需要,您还可以忽略此全局作用域。

namespace App\Repositories;
use GiordanoLima\EloquentRepository\BaseRepository;
class AdminRepository extends BaseRepository
{
    protected function model() {
        return \App\User::class;
    }
    protected function globalScope() {
        return $this->where('is_admin', true);
    }
    
    public function getAdmins() {
        // In this query the declared global scope will be included.
        return $this->all();
    }
    
    public function getAll() {
        // In this query the declared global scope will not be included.
        return $this->skipGlobalScope()->all();
    }
}

缓存

该包附带了一个强大的缓存驱动器。想法是查询完成后,它将被缓存。一旦缓存完成,就可以将数据库访问次数减少到零。所有缓存都使用为应用程序配置的缓存驱动器执行。要使用驱动器,只需使用实现它的特质。

namespace App\Repositories;
use GiordanoLima\EloquentRepository\BaseRepository;
use GiordanoLima\EloquentRepository\CacheableRepository;
class UserRepository extends BaseRepository
{
    use CacheableRepository;
    protected function model() {
        return \App\User::class;
    }
}

用法保持不变,所有缓存管理逻辑都自动完成。

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Repositories\UserRepository;
class UserController extends Controller
{
    private $repository;
	public function __construct()(UserRepository $repository) {
        $this->repository = $repository;
    }
    
    public function index() {
        $users = $this->repository->getAllUsers();
        // if you call the same query later (even in other requests)
        // the query is already cached and you do not need to access the database again.
        $users = $this->repository->getAllUsers(); 
    }
    
}

每次数据库数据更改时,缓存都会自动清理以避免过时数据。然而,如果需要清理缓存,可以通过clearCache()方法执行。您还可以使用skipCache()方法强制访问数据库并避免使用缓存数据。

namespace App\Repositories;
use GiordanoLima\EloquentRepository\BaseRepository;
use GiordanoLima\EloquentRepository\CacheableRepository;
class UserRepository extends BaseRepository
{
    use CacheableRepository;
	protected function model() {
        return \App\User::class;
    }
    
    public function createUser($data) {
        // After inserting the data, the cache
        // is cleaned automatically.
        return $this->create($data);
    }
    
    public function addRules($user, $rules) {
        $user->rules()->attach($rules);
        $this->clearCache(); // Forcing cache cleaning.
    }
    
    public function getWithoutCache() {
        $this->skipCache()->all(); // Finding the data without using the cache.
    }
}