laravel 存储仓基础
- laravel存储仓基础
- 创建存储仓
- 手动创建存储仓
- 创建接口
- 创建接口实现
- 测试接口
- Criteria 封装查询逻辑的模式
- 作用
- 使用场景
- 使用示例
- 封装商品排序逻辑
- 封装商品状态过滤逻辑
- 业务逻辑封装
- 创建测试控制器
- 测试与结果
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
结果:
- 按价格从高到低排序,返回符合条件的商品列表