存储库模式是由 Eric Evans 在他的领域驱动设计书中首次引入的。 事实上,存储库是应用程序访问域层的入口点。
简单来说,存储库允许您的所有代码使用对象,而无需知道对象是如何持久化的。存储库包含持久性的所有知识,包括从表到对象的映射。这提供了持久层的更加面向对象的视图,并使映射代码更加封装。
让你的存储库在 Laravel 中工作(作为一个真正的存储库——Eric Evans 领域驱动设计书)的唯一方法是将默认的 ORM 从活动记录更改为数据映射器。最好的替代品是教义。
Doctrine 是一种 ORM(对象关系映射),它实现了数据映射器模式,并允许您将应用程序的业务规则与数据库的持久层完全分离。 Doctrine 使用 DQL,而不是 SQL。 DQL 为您带来对象查询语言,这意味着您将使用对象术语进行查询,而不是传统的关系查询术语。
它允许您以面向对象的方式编写数据库查询,并在您需要以使用默认存储库方法无法实现的方式查询数据库时提供帮助。在我看来,DQL 是与数据库保持联系的最强大方式。
Doctrine 实体只是一个普通的 PHP 简单类,不会增加任何 ORM 继承的开销。 Doctrine 使用相同的继承来管理多个查询请求,而无需访问数据库,这意味着整个请求都存在实体对象。
Doctrine 的另一个不错的功能是,无需迁移文件来创建数据库模式,而是自动创建数据库来反映实体注释中的元数据。另一方面,Eloquent 不太复杂并且非常易于使用。
这两者之间的完整比较需要一篇单独的文章。正如您所看到的,Doctrine 对象更轻、更抽象。然而,Doctrine 只适合特定的项目,因此它有时可能会给您带来开销。我相信这取决于程序员为应用程序选择最好的 ORM。
现在是时候使用 Laravel 创建一个博客应用程序了。首先,我们需要建立教义。有一个桥梁可以与 Laravel 5 的现有配置进行匹配。要在 Laravel 项目中安装 Doctrine 2,我们运行以下命令:
composer require laravel-doctrine/orm
像往常一样,该包应该添加到app/config.php
,作为服务提供者:
LaravelDoctrine\ORM\DoctrineServiceProvider::class,
还应该配置别名:
'EntityManager' => LaravelDoctrine\ORM\Facades\EntityManager::class
最后,我们发布包配置:
php artisan vendor:publish --tag="config"
现在我们已经完成了。
实体是应用程序 AppEntitiesPost.php
的重要组成部分:
namespace App\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity * @ORM\Table(name="posts") * @ORM\HasLifecycleCallbacks() */ class Post { /** * @var integer $id * @ORM\Column(name="id", type="integer", unique=true, nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") * */ private $id; /** * @ORM\Column(type="string") */ private $title; /** * @ORM\Column(type="text") */ private $body; public function __construct($input) { $this->setTitle($input['title']); $this->setBody($input['body']); } public function setId($id) { return $this->id=$id; } public function getId() { return $this->id; } public function getTitle() { return $this->title; } public function setTitle($title) { $this->title = $title; } public function getBody() { return $this->body; } public function setBody($body) { $this->body = $body; } }
现在是时候创建存储库了,这在前面已经描述过了。 App/Repositories/PostRepo.php
:
namespace App\Repository; use App\Entity\Post; use Doctrine\ORM\EntityManager; class PostRepo { /** * @var string */ private $class = 'App\Entity\Post'; /** * @var EntityManager */ private $em; public function __construct(EntityManager $em) { $this->em = $em; } public function create(Post $post) { $this->em->persist($post); $this->em->flush(); } public function update(Post $post, $data) { $post->setTitle($data['title']); $post->setBody($data['body']); $this->em->persist($post); $this->em->flush(); } public function PostOfId($id) { return $this->em->getRepository($this->class)->findOneBy([ 'id' => $id ]); } public function delete(Post $post) { $this->em->remove($post); $this->em->flush(); } /** * create Post * @return Post */ private function perpareData($data) { return new Post($data); } }
控制器:App/Http/Controllers/PostController.php
:
namespace App\Http\Controllers; use App\Repository\PostRepo as repo; use App\Validation\PostValidator; class PostController extends Controller { private $repo; public function __construct(repo $repo) { $this->repo = $repo; } public function edit($id=NULL) { return View('admin.edit')->with(['data' => $this->repo->postOfId($id)]); } public function editPost() { $all = Input::all(); $validate = PostValidator::validate($all); if (!$validate->passes()) { return redirect()->back()->withInput()->withErrors($validate); } $Id = $this->repo->postOfId($all['id']); if (!is_null($Id)) { $this->repo->update($Id, $all); Session::flash('msg', 'edit success'); } else { $this->repo->create($this->repo->perpare_data($all)); Session::flash('msg', 'add success'); } return redirect()->back(); } public function retrieve() { return View('admin.index')->with(['Data' => $this->repo->retrieve()]); } public function delete() { $id = Input::get('id'); $data = $this->repo->postOfId($id); if (!is_null($data)) { $this->repo->delete($data); Session::flash('msg', 'operation Success'); return redirect()->back(); } else { return redirect()->back()->withErrors('operationFails'); } } }
如您所见,我使用 Flash 助手来管理消息(您可以使用 Laravel 的)。关于验证器,我应该补充一点,您可以创建自己的验证器(就像我一样)或使用 Laravel 默认值,具体取决于您的偏好。
查看文件与平常相同。在此示例视图中,文件看起来像 resources/views/admin/edit.blade.php
:
@if (Session::has('flash_notification.message')) × {!! Session::get('flash_notification.message') !!} @endif @if($errors->has()) @foreach ($errors->all() as $error) {!! $error !!} @endforeach @endif {!! 'title' !!} {!! 'Body' !!} {!! is_object($ListData)?$ListData->getTitle():'' !!} {!! 'save' !!}
以上是Laravel 5中的仓储模式的详细内容。更多信息请关注PHP中文网其他相关文章!