larachimp/mango-repo

Laravel 5 简单的仓库包。

v3.0.0 2021-09-15 20:34 UTC

README

Mango Repo

Latest Stable Version Latest Unstable Version Build Status StyleCI License Total Downloads

简介

Mango Repo 是一个 Eloquent 仓库包,旨在提供易于使用和流畅的 API。使用仓库模式可能会让人感到有些不知所措。这对于 Eloquent 新手来说尤其如此,他们正在掌握活动记录。在幕后,Mango Repo 尽可能使用 Eloquent API 的功能,并保持简单。

许可

Mango Repo 是开源软件,遵循 MIT 许可证

版本兼容性

安装

像管理其他依赖项一样使用 Composer 安装 Mango Repo。

$ composer require larachimp/mango-repo

配置

如果您使用 Laravel >= 5.5,由于 Laravel 自动包发现功能,您可以跳过服务注册。

安装 Mango repo 后,您只需要在您的 config/app.php 配置文件中注册 LaraChimp\MangoRepo\MangoRepoServiceProviderLaraChimp\PineAnnotations\PineAnnotationsServiceProvider

'providers' => [
    // Other service providers...

    LaraChimp\PineAnnotations\PineAnnotationsServiceProvider::class,
    LaraChimp\MangoRepo\MangoRepoServiceProvider::class,
],

您可以选择注册注解读取器别名。

'aliases' => [
    ...
    'AnnotationsReader' => LaraChimp\PineAnnotations\Facades\Reader::class,
],

有关更多信息,请参阅PineAnnotations 包,了解注解读取器。

创建仓库类

使用 mango:make 命令创建您的仓库类。该命令将接受仓库类命名空间(从 App)和 --model 选项,允许您指定与仓库相关联的 Eloquent 模型的完整命名空间。

$ php artisan mango:make "Repositories\Posts" --model="App\Models\Post"

上述命令将在 app/Repositories 目录中生成以下仓库类

<?php

namespace App\Repositories;

use LaraChimp\MangoRepo\Repositories\EloquentRepository;

class Posts extends EloquentRepository
{
    /**
     * The target Eloquent Model.
     */
    const TARGET = \App\Models\Post::class;
}

请注意,const TARGET 指定了仓库将使用的 Eloquent 模型。如果您想使事情更简单一些,mango:make 命令允许您指定可选的 --annotated 选项,该选项生成一个使用注解指定 Eloquent 模型的仓库类

$ php artisan mango:make "Repositories\Posts" --model="App\Models\Post" --annotated

上述命令将在 app/Repositories 目录中生成以下仓库类

<?php

namespace App\Repositories;

use LaraChimp\MangoRepo\Annotations\EloquentModel;
use LaraChimp\MangoRepo\Repositories\EloquentRepository;

/**
 * @EloquentModel(target="App\Models\Post")
 */
class Posts extends EloquentRepository
{
    //
}

使用仓库

创建您的仓库类后,您可以通过 Laravel 的 Service 容器解析它;要么通过依赖注入,要么通过使用 app() 方法。

在以下控制器中,我们在构造函数中注入了我们的 Posts 仓库,并在索引方法中使用它

<?php

namespace App\Http\Controllers;

use App\Repositories\Posts;

class PostController extends Controller 
{
    /**
     * Posts repository instance.
     * 
     * @var Posts
     */
    protected $posts;
    
    public function __construct(Posts $posts) 
    {
        $this->posts = $posts;
    }
    
    public function index()
    {
        $allPosts = $this->posts->all();
        //
    }
}

请注意,仓库类不仅可以注入到控制器构造函数中,还可以注入到方法和任何由服务容器解析的服务中。

您还可以使用 app()app()->make()resolve() 方法解析您的仓库类实例,并按需使用它

<?php

namespace App\Http\Controllers;

use App\Repositories\Posts;

class PostController extends Controller 
{
    public function index()
    {
        $posts = app()->make(Posts::class)->all();
        //
    }
}

虽然从服务容器解析仓库类似乎是最有效的方法来构建实例,但您可能出于某些原因而更愿意手动实例化您的仓库类。为此,在使用之前,请调用新实例的 boot() 方法。

boot() 方法将负责为我们加载仓库类的依赖项

$posts = (new \App\Repositories\Posts())->boot();

可用方法

出厂时,仓库类已经为您编写了这些方法。然而,您可以自由地添加自己的方法或在您的仓库类中覆盖现有方法,以构建您自己的自定义API和业务逻辑。

为了尽可能保持简单,对于许多这些方法,Mango Repo利用了Eloquent模型上可用的相同方法。因此,Mango Repo的API尽量接近Eloquent的API。

all()

从数据库获取所有模型

$users = app(\App\Repositories\Users::class)->all();

// Illuminate\Database\Eloquent\Collection

$users = app(\App\Repositories\Users::class)->all(['name', 'email']);

// Illuminate\Database\Eloquent\Collection instance

paginate()

分页显示数据库中的模型

$users = app(\App\Repositories\Users::class)->paginate(10, ['name', 'email']);

// Illuminate\Contracts\Pagination\LengthAwarePaginator instance

simplePaginate()

将数据库中的模型分页显示为一个简单的分页器

$users = app(\App\Repositories\Users::class)->simplePaginate(10, ['name', 'email']);

// Illuminate\Contracts\Pagination\Paginator

create()

保存一个新的模型并返回实例

$user = app(\App\Repositories\Users::class)->create([
            'name'     => 'John Doe', 
            'email'    => 'john@doe.com'
            'password' => Hash::make('secret')
         ]);
 
 // Illuminate\Database\Eloquent\Model

update()

更新数据库中的模型。更新方法接受第二个参数为模型实例或模型ID

app(\App\Repositories\Users::class)->update(['name' => 'John Smith'], $userId);

// bool

app(App\Repositories\Users::class)->update(['name' => 'John Smith'], $user);

// bool

delete()

从数据库中删除一条记录。删除方法接受第一个参数为模型实例或模型ID

app(\App\Repositories\Users::class)->delete($userId);

// bool

app(\App\Repositories\Users::class)->delete($user);

// bool

find()

使用ID在数据库中查找模型

app(\App\Repositories\Users::class)->find($userId);

// Illuminate\Database\Eloquent\Model

app(\App\Repositories\Users::class)->find($user_id, ['name', 'email']);

// Illuminate\Database\Eloquent\Model

findOrFail()

在数据库中查找模型或抛出异常

app(\App\Repositories\Users::class)->findOrFail($userId);

// Illuminate\Database\Eloquent\Model

app(\App\Repositories\Users::class)->findOrFail($userId, ['name', 'email']);

// Illuminate\Database\Eloquent\Model

findBy()

使用某些标准查找模型或模型

app(\App\Repositories\Users::class)->findBy(['last_name' => 'Doe']);

// Illuminate\Database\Eloquent\Collection

app(\App\Repositories\Users::class)->findBy(['last_name' => 'Doe'], ['last_name', 'email']);

// Illuminate\Database\Eloquent\Collection

getModel()

获取Eloquent模型实例

app(\App\Repositories\Users::class)->getModel();

// Illuminate\Database\Eloquent\Model

模型仓库范围

Mango Repo不使用长而繁琐的“Criterias类”进行查询过滤,而是可以使用mango:make命令创建的任何仓库类都可以是“模型范围”。换句话说,这意味着您可以直接在仓库类上访问在您的模型上定义的本地查询范围。

因此,您只需在模型类上定义一次查询范围,就可以直接在仓库类上使用它们进行查询过滤。

考虑以下示例

<?php

namespace LaraChimp\MangoRepo\Tests\Fixtures\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class User extends Model
{
    //...
    
    /**
     * Apply an is active scope filter to the model.
     *
     * @param Builder $query
     *
     * @return Builder
     */
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }
}

由于我们在用户模型上定义了本地范围Active,所以我们不必在仓库类中重写相同的范围。我们只需直接在仓库类中使用它。是的,就这么简单!

$activeUsers = app(\App\Repositories\Users::class)->active()->get();

// Illuminate\Database\Eloquent\Collection

您甚至可以链式调用范围并应用其他过滤器,就像您对任何Eloquent模型实例所做的那样

 $users = app(\App\Repositories\Users::class)->popular()->active()->orderBy('created_at')->get();
 
 // Illuminate\Database\Eloquent\Collection

更进一步

我们认为我们已经在这里为创建仓库类创建了一个简单但功能丰富的模板,在大多数情况下,您可能只需像 breeze 一样使用mango:make命令创建仓库类。然而,如果您仍然不满意,需要创建不需要模型范围等自定义仓库类;不用担心,我们已经为您准备好了。

首先,创建一个实现LaraChimp\MangoRepo\Contracts\RepositoryInterface的类。现在您可以按需实现所有可用的方法。

<?php

namespace Acme\Company;

use LaraChimp\MangoRepo\Contracts\RepositoryInterface;

class MyCompanyRepo implements RepositoryInterface
{
    public function all($columns = ['*'])
    {
        // ...
    }
    
    // ...
}

请记住,您不需要再次实现这些方法,您可以使用已实现这些方法的LaraChimp\MangoRepo\Concerns\IsRepositorable特质。

<?php

namespace Acme\Company;

use LaraChimp\MangoRepo\Concerns\IsRepositorable;
use LaraChimp\MangoRepo\Contracts\RepositoryInterface;

class MyCompanyRepo implements RepositoryInterface
{
    use IsRepositorable;
    
    // ...
}

如果您希望仓库可启动,请使用LaraChimp\MangoRepo\Concerns\IsRepositoryBootable特质,对于模型范围,请使用LaraChimp\MangoRepo\Concerns\IsRepositoryScopable

<?php

namespace Acme\Company;

use LaraChimp\MangoRepo\Concerns;
use LaraChimp\MangoRepo\Contracts\RepositoryInterface;

class MyCompanyRepo implements RepositoryInterface
{
    use Concerns\IsRepositorable,
        Concerns\IsRepositoryBootable,
        Concerns\IsRepositoryScopable;
    
    // ...
}

致谢

衷心感谢所有辛勤工作创建惊人产品的开发者们!

LaraChimp

创作者

Twitter: @PercyMamedy

GitHub: percymamedy