重复造轮子了, 自己开发的 Laravel Repository

根据公司的项目的repository,优化并去除公司的业务代码(继承思路,代码重构),然后和同事一起将repository开源出来

GitHub地址

一 安装使用

安装包文件

composer require littlebug/laravel-repository

生成 model 和 repository

littlebug/laravel-repository 提供了命令行模式生成modelrepository
使用命令

php artisan core:model --table=users --name=User

该命令会在:

  • app/Models/ 文件下生成 User 文件
  • app/Repositories/ 文件下生成 UserRepository 文件

在控制器中使用repository

use App\Repositories\UserRepository;

class UsersController extends Controller 
{
    /**
     * @var UserRepository
     */
    private $userRepository;

    public function __construct(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    public function index()
    {
        // 分页查询
        $list = $this->userRepository->paginate([
            'name:like' => 'test123', 
            'status:in' => [1, 2],
        ]);

        return view('users.index', compact('list'));
    }

    public function create()
    {
        list($ok, $msg, $user) = $this->userRepository->create(request()->all());
        // 你的逻辑
    }

    public function update()
    {
        list($ok, $msg, $row) = $this->userRepository->update(request()->input('id'), request()->all());
        // 你的逻辑
    }

    public function delete()
    {
        list($ok, $msg, $row) = $this->userRepository->delete(request()->input('id'));
        // 你的逻辑
    }
}

二 支持的方法列表

repository所有方法都是对外的,这里只列出常用方法

  • find($conditions, $columns = []) 查询一条数据
  • findBy($conditions, $column) 查询单条数据的单个字段
  • findAll($conditions, $columns = []) 查询多条数据
  • findAllBy($conditions, $column) 查询多条数组的单个字段数组
  • filterFind($conditions, $columns = []) 过滤查询条件中的空值查询一条数据
  • filterFindAll($condtions, $columns = []) 过滤查询条件中的空值查询多条数据
  • paginate($conditions = [], $columns = [], $size = 10, $current = null) 分页查询数据
  • getFilterModel($conditions, $columns = []) 获取已经过滤处理查询条件的model
  • findCondition($conditions = [], $columns = []) 获取已经处理查询条件的model(上面所有查询方法都基于这个方法)
  • create(array $data) 添加数据
  • update($conditions, array $data) 修改数据(使用的是批量修改)
  • delete($conditions) 删除数据(使用的是批量删除)

    参数说明

    参数名称 参数类型 参数说明
    $conditions array or string or int 查询条件(string or int or 索引数组[1, 2, 3, 4]会自动转换为主键查询)
    $columns array 查询的字段数组
    $column string 查询的字段名称
    $data array 创建或者修改的数组数据信息

更多方法GitHub传送门>>

三 特性说明

1 表达式查询

支持的表达式列表
model where 写法

$users = User::where('type', '=', 1)
            ->whereIn('status', [1, 2])
            ->where('username', 'like', '%test%')
            ->whereBetween('created_at', ['2019-01-02 00:00:00', '2019-05-01 23:59:59'])
            ->orderBy('id', 'desc')
            ->get();

使用 repository 查询

$users = $this->userRepository->findAll([
    'type' => 1,
    'status' => [1, 2], // 数组会转为 in 查询,
    'username:like' => '%test%',
    'created_at:between' => ['2019-01-02 00:00:00', '2019-05-01 23:59:59'],
    'order' => 'id desc', // order 定义排序方式 
]);

2 支持scope查询

model 需要定义scope 方法

public function scopeAddress($query, $address)
{
    return $query->join('user_ext', 'users.user_id', '=', 'uesr_ext.user_id')->where('address', 'like', "%{$address}%");
}

model 写法

$users = User::Address('北京')->get();

repository 写法

$users = $this->userRepository->findAll(['address' => '北京']);

3 关联查询

model 需要定义关联

public function ext()
{
    return $this->hasOne(UserExt::class, 'user_id', 'user_id');
}

model 写法

$users = User::with(['ext' => function ($query) {
    return $query->select(['id', 'name'])
    ->where('address', 'like', '%北京%')
    ->orderBy('id', 'desc');
}])->get();

repository 写法

$users = $this->userRepository->findAll([
    // 为关联添加查询条件和排序条件
    'ext.address:like' => '%北京%',
    'ext.order' => 'id desc',
], [
    '*', 
    // 查询关联表信息
    'ext' => ['id', 'name']
]);

4 when 查询替代方法

  • filterFind($conditions, $columns = [])
  • filterFindAll($conditions, $columns = [])

    上述方法会自动过滤$conditions 中的空值(空字符、空数组、null)

在特定情况下,还是比较有用的

$model = User::where('status', '=', 1);
if ($username = request()->input('username')) {
    $model = $model->where('username', '=', $username);
}

if ($type = request()->input('type')) {
    $model = $model->where('type', '=', $type);
}

$users = $model->get();

使用repository

$users = $this->userRepository->filterFindAll([
    'status' => 1,
    'username' => request()->input('username'),
    'type' => request()->input('type')
]);

5 使用findWhere构建复杂的查询

 $users = $this->userRepository->findWhere([
     'and', 
     ['or', ['username:auto_like' => 'test'], ['nick_name', 'like', '%test%']], 
     ['level' => 5], 
     ['status', '=', 1],
 ])->get();

上面查询生成的SQl

select * from `users` where (
    (`users`.`username` like '%test%' or `users`.`nick_name` like '%test%')   
    and `users`.`level` = 5 
    and `users`.`status` = 1
)

更多关于repository的使用方法,可以查看文档>>

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 2
4年前 评论
liujx (楼主) 4年前
fatrbaby

坦率地说,我觉得repository在实际的开发中体验并不好。所以我们现在开发,只抽象domain,摒弃所有的service和repository。

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!