【Laravel】存储仓Repository基础

embedded/2024/11/29 15:47:30/

laravel 存储仓基础

  • laravel存储仓基础
    • 创建存储仓
    • 手动创建存储仓
      • 创建接口
      • 创建接口实现
      • 测试接口
  • Criteria 封装查询逻辑的模式
        • 作用
        • 使用场景
    • 使用示例
      • 封装商品排序逻辑
      • 封装商品状态过滤逻辑
      • 业务逻辑封装
      • 创建测试控制器
      • 测试与结果

laravel_2">laravel存储仓基础

本文基于 Laravel 9.* 版本,PHP 8.2 进行开发,所用扩展为 l5-repository。

安装命令:
composer require prettus/l5-repository

创建存储仓

如果尚未创建过存储仓库的 Model,可以直接使用以下命令生成存储仓库文件:

php artisan make:repository Goods/Goods

此命令会自动生成 Model 及对应的存储仓库文件。

手动创建存储仓

创建接口

首先,创建一个存储仓库接口:

php">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);
}

创建接口实现

接下来,实现该接口:

php">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 中注册服务提供者

php">'providers' => [// .....App\Providers\RepositoryServiceProvider::class,
]

在 RepositoryServiceProvider 中绑定服务

php"> public function boot(){$this->app->bind(\App\Repositories\Goods\Interfaces\GoodsRepository::class, \App\Repositories\Goods\GoodsRepositoryEloquent::class);}

创建测试 Controller

php">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 通过解析输入参数中的排序选项,动态生成排序规则,从而支持多种排序模式

php">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 用于筛选商品状态,返回已发布且审核通过的商品

php">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 实现商品的排序与筛选功能

php">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,实现接口逻辑

php">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

结果:

  • 按价格从高到低排序,返回符合条件的商品列表

http://www.ppmy.cn/embedded/141512.html

相关文章

linux-cmd

过滤, 管道与重定向 过滤 过滤出 /etc/passwd 文件中包含 root 的记录 grep root /etc/passwd 递归地过滤出 /var/log/ 目录中包含 linux 的记录 grep -r linux /var/log/ 管道 简单来说, Linux 中管道的作用是将上一个命令的输出作为下一个命令的输入, 像 pipe 一样将各个命令…

Leetcode:349. 两个数组的交集

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 Leetcode&#xff1a;349. 两个数组的交集 给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的 交集。输出结果中的每个元素…

Java基础夯实——2.9 多线程如何共享数据

在 Java 多线程编程中&#xff0c;共享数据通过以下几种方式实现&#xff1a; 1. 使用共享对象 多个线程可以通过引用同一个对象来实现数据共享。例如&#xff1a; class SharedData {private int count;public synchronized void increment() {count;}public synchronized …

C/C++基础知识复习(30)

1) 什么是 C 中的 Lambda 表达式&#xff1f;它的作用是什么&#xff1f; Lambda 表达式&#xff1a; 在 C 中&#xff0c;Lambda 表达式是一种可以定义匿名函数的机制&#xff0c;可以在代码中快速创建一个内联的函数对象&#xff0c;而不需要显式地定义一个函数。Lambda 表…

健康养生:开启活力生活的密码

在快节奏的现代生活中&#xff0c;人们越发重视健康养生&#xff0c;追求身体与心灵的和谐共生。 健康养生&#xff0c;饮食为先。我们应遵循 “五谷为养&#xff0c;五果为助&#xff0c;五畜为益&#xff0c;五菜为充” 的理念&#xff0c;确保各类营养物质的均衡摄入。减少油…

Flink 之 Window 机制详解(上):基础概念与分类

《Flink 之 Window 机制详解&#xff08;上&#xff09;&#xff1a;基础概念与分类》 一、引言 在当今大数据蓬勃发展的时代&#xff0c;Flink 作为一款卓越的分布式流处理和批处理框架&#xff0c;以其独特的架构和强大的功能在数据处理领域占据着重要地位。其底层基于流式…

Mybatis:Mybatis快速入门

Mybatis的官方文档是真的非常好&#xff01;非常好&#xff01; 点一下我呗&#xff1a;Mybatis官方文档 MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可…

rk3588交叉编译opencv

基于forlinx开发板Linux5.10.66Qt5.15.2的环境 交叉编译工具链&#xff1a;aarch64-buildroot-linux-gnu-gcc、aarch64-buildroot-linux-gnu-g opencv版本&#xff1a;3.4.15 创建toolchain.cmake # 工具链路径 set(CMAKE_C_COMPILER /home/forlinx/aarch64-buildroot-linux…