laravel 存储仓基础
laravel存储仓基础
本文基于 Laravel 9.* 版本,PHP 8.2 进行开发,所用扩展为 l5-repository。
安装命令:
composer require prettus/l5-repository
创建存储仓
如果尚未创建过存储仓库的 Model,可以直接使用以下命令生成存储仓库文件:
php artisan make:repository Goods/Goods
此命令会自动生成 Model 及对应的存储仓库文件。
手动创建存储仓
创建接口
首先,创建一个存储仓库接口:
namespace App\Repositories\Goods\Interfaces;
use Prettus\Repository\Contracts\RepositoryInterface;
/**
* Interface GoodsRepositoryRepository.
*
* @package namespace App\Repositories\Goods;
*/
interface GoodsRepository extends RepositoryInterface
{
/**
*
* 获取商品列表信息
*
* @param $request
* @return mixed
*/
public function goodsPaginate($request);
}
创建接口实现
接下来,实现该接口:
namespace App\Repositories\Goods;
use App\Models\Goods;
use App\Repositories\Goods\Interfaces\GoodsRepository;
use Prettus\Repository\Criteria\RequestCriteria;
use Prettus\Repository\Eloquent\BaseRepository;
/**
* Class GoodsRepositoryRepositoryEloquent.
*
* @package namespace App\Repositories\Goods;
*/
class GoodsRepositoryEloquent extends BaseRepository implements GoodsRepository
{
/**
* Specify Model class name
*
* @return string
*/
public function model()
{
return Goods::class;
}
protected $fieldSearchable = [
'goods_name'=>'like',
'goods_subname'=>'like',
'goods_no'=>'like',
];
/**
* Boot up the repository, pushing criteria
*/
public function boot()
{
$this->pushCriteria(app(RequestCriteria::class));
}
public function goodsPaginate($request)
{
// TODO: Implement goodsPaginate() method.
$this->applyCriteria();
$this->applyScope();
$limit = (int)($data['page_size'] ?? 25);
$limit = abs($limit) < 2000 ? abs($limit) : 2000;
$page = abs((int)($data['page'] ?? 1));
$results = $this->model->paginate($limit, ['*'], $pageName = 'page', $page);
$this->resetModel();
return $this->parserResult($results);
}
}
在 config/app.php 中注册服务提供者
'providers' => [
// .....
App\Providers\RepositoryServiceProvider::class,
]
在 RepositoryServiceProvider 中绑定服务
public function boot()
{
$this->app->bind(\App\Repositories\Goods\Interfaces\GoodsRepository::class, \App\Repositories\Goods\GoodsRepositoryEloquent::class);
}
创建测试 Controller
namespace App\Http\Controllers\Learn;
use App\Http\Controllers\Controller;
use App\Repositories\Goods\Interfaces\GoodsRepository;
use Illuminate\Http\Request;
class GoodsController extends Controller
{
/**
* @var GoodsRepository
*/
protected $repository;
/**
* GoodsController constructor.
*
* @param GoodsRepository $repository
*/
public function __construct(GoodsRepository $repository)
{
$this->repository = $repository;
}
public function getList(Request $request)
{
return $this->repository->goodsPaginate($request);
}
}
测试接口
访问接口:
http://xxx.test/api/Learn/goods/getList?search=goods_name:haha
返回的结果会是 goods_name 字段进行 like 模糊匹配,查询条件为 haha。
Criteria 封装查询逻辑的模式
Criteria 是一种用于封装查询逻辑的模式,可以将复杂的查询条件独立成类,从而提高代码的复用性、可读性和维护性。
作用
- 动态过滤数据:通过 Criteria,你可以根据请求参数或业务需求动态地添加查询条件
- 解耦查询逻辑:Criteria 将查询逻辑从仓库实现中分离出来,方便代码复用和测试
- 链式调用:Criteria 可以组合使用,逐步添加查询条件
使用场景
- 按条件过滤:例如,根据用户输入的关键词或筛选条件动态调整查询结果
- 全局查询逻辑:比如,自动添加 where 条件过滤被软删除的数据
- 复杂查询逻辑:将复杂查询封装到 Criteria 类中,保持代码简洁
使用示例
为了实现商品的灵活排序和状态筛选,我们通过以下两种 Criteria 对商品查询逻辑进行了封装:GoodsSortCriteria 用于处理排序逻辑,GoodsPublishedCriteria 用于状态筛选。下面是具体实现及业务调用的方式。
封装商品排序逻辑
GoodsSortCriteria 通过解析输入参数中的排序选项,动态生成排序规则,从而支持多种排序模式
namespace App\Criteria\Goods;
use Prettus\Repository\Contracts\CriteriaInterface;
use Prettus\Repository\Contracts\RepositoryInterface;
class GoodsSortCriteria implements CriteriaInterface
{
public function __construct($filterData)
{
$this->request = $filterData;
}
const SORTBYCATEGORY = [
'price-descending' => 'price_descending',
'price-ascending' => 'price_ascending',
'created-descending' => 'created_descending',
'created-ascending' => 'created_ascending',
];
public function apply($model, RepositoryInterface $repository)
{
$type = self::SORTBYCATEGORY[$this->request['sort']] ?? '';
switch ($type) {
case 'price_descending':
$model = $model->orderByRaw('goods_price DESC');
break;
case 'price_ascending':
$model = $model->orderByRaw('goods_price ASC');
break;
case 'created_ascending':
$model = $model->orderByRaw('created_at ASC');
break;
case 'created_descending':
$model = $model->orderByRaw('created_at DESC');
break;
default:
$model = $model->orderByRaw('id DESC');
}
return $model;
}
}
封装商品状态过滤逻辑
GoodsPublishedCriteria 用于筛选商品状态,返回已发布且审核通过的商品
namespace App\Criteria\Goods;
use Prettus\Repository\Contracts\CriteriaInterface;
use Prettus\Repository\Contracts\RepositoryInterface;
class GoodsPublishedCriteria implements CriteriaInterface
{
public function apply($model, RepositoryInterface $repository)
{
return $model->where('goods_status', 1)->where('goods_verify', 1);
}
}
业务逻辑封装
在业务层,通过 GoodsService 结合上述 Criteria 实现商品的排序与筛选功能
namespace App\Services\Study;
use App\Criteria\Goods\GoodsPublishedCriteria;
use App\Criteria\Goods\GoodsSortCriteria;
use App\Repositories\Goods\Interfaces\GoodsRepository;
class GoodsService
{
public $goodsRepository;
public function __construct(GoodsRepository $goodsRepository)
{
$this->goodsRepository = $goodsRepository;
}
public function goodsFilterAndSort($filterData)
{
$this->goodsRepository->pushCriteria(new GoodsSortCriteria($filterData));
$this->goodsRepository->pushCriteria(new GoodsPublishedCriteria($filterData));
return $this->goodsRepository;
}
public function goodsPaginator($filterData)
{
return $this->goodsFilterAndSort($filterData)->goodsPaginate($filterData);
}
}
创建测试控制器
通过 GoodsController 调用 GoodsService,实现接口逻辑
namespace App\Http\Controllers\Learn;
use App\Http\Controllers\Controller;
use App\Repositories\Goods\Interfaces\GoodsRepository;
use App\Services\Study\GoodsService;
use Illuminate\Http\Request;
class GoodsController extends Controller
{
public function getServerList(Request $request)
{
return app(GoodsService::class)->goodsPaginator($request);
}
}
测试与结果
通过访问接口验证实现效果:
http://jwj.test/api/Learn/goods/getGoodsList?sort=price-descending
结果:
- 按价格从高到低排序,返回符合条件的商品列表
1758

被折叠的 条评论
为什么被折叠?



