Как разработчик PHP, вы могли встретить термин ORM. ORM — это способ работы с базами данных так же, как вы работаете с классами и объектами. Если вы хотите глубже вникнуть в то, как веб-приложения проектируются и создаются, после некоторого изучения их ORM вы найдете два хорошо известных шаблона: Active Record и Data Mapper .
Активная запись относится к отображению объекта в строке базы данных. Действительно, каждая строка в базе данных связана с объектом. Когда вы извлекаете строку из базы данных, вы можете обновить, удалить или сохранить ее, используя сам объект. Вот как работают Eloquent и Paris , и как это делается в Ruby on Rails.
С другой стороны, Data Mapper
— это уровень программного обеспечения, который отделяет объекты в памяти от базы данных. При использовании Data Mapper объектам в памяти не нужно знать, что существует даже база данных. Им не требуется код интерфейса SQL или знание схемы базы данных. Одним из таких решений является доктрина .
Что такое доктрина?
Doctrine — это ORM, который реализует шаблон отображения данных и позволяет четко отделить бизнес-правила приложения от уровня персистентности базы данных.
Некоторые из преимуществ, которые я обнаружил при использовании Doctrine с Laravel:
- Быстрее и проще в использовании.
- Сущности — это просто обычные объекты PHP.
- В Doctrine используется подход «сначала код», поэтому вы можете сначала создать сущности, а затем автоматически создать для них базу данных. Возможен и обратный случай, но я его не рекомендую.
- Поддерживает аннотации, XML и YAML для схемы.
- DQL (замена SQL) абстрагирует ваши таблицы.
- События Doctrine позволяют вам легко подключаться к определенным событиям базы данных и выполнять определенные действия.
- Репозитории более верны шаблону репозитория.
- Методология
Transactional write-behind
позволяет Doctrine меньше взаимодействовать с базой данных, пока не будет вызван методflush()
.
Конечно, Doctrine также имеет недостатки, но программист должен выбрать правильный ORM.
Доктрина DQL
DQL расшифровывается как Doctrine Query Language. DQL предоставляет вам язык объектных запросов, что означает, что вместо традиционных реляционных запросов у вас есть запросы в форме объектов.
DQL позволяет вам писать запросы к базе данных объектно-ориентированным способом, что полезно, когда вам нужно выполнить запрос к базе данных способом, который не может быть достигнут (или очень сложен), используя стандартные методы репозитория.
Пример DQL-запроса:
sql SELECT b.id as ItemId, b.title as ItemTitle , b.url as ItemUrl FROM Alireza\Domain\Identity\Entities\Menu u WHERE u.id =:id
Доктрины Фильтры
Doctrine позволяет ограничивать результаты запросов с помощью фильтров . Например, вы можете изменить только информацию о вошедшем в систему пользователе или убедиться, что данные текущего клиента были возвращены из базы данных. Фильтр — это автоматическое решение для запоминания конкретных условий для всех ваших запросов.
Doctrine предоставляет ограничения на уровне SQL, поэтому нет необходимости поддерживать предложение в нескольких репозиториях вашего проекта. Это повышает безопасность и облегчает чтение вашего кода.
Давайте посмотрим на пример:
php /** * @ManyToOne(targetEntity="User") * @JoinColumn(name="user_id", referencedColumnName="id") **/ private $user;
Как вы можете видеть в сущности User, результат JoinColumn
ограничен только элементами с условием WHERE user_id = :user_id
.
Настройка Доктрины 2
Для настройки Doctrine существует мост, позволяющий сопоставить его с существующей конфигурацией Laravel 5. Чтобы установить Doctrine 2 в нашем проекте Laravel, мы запускаем следующую команду:
bash composer require laravel-doctrine/orm
Как обычно, пакет должен быть добавлен в app/config.php
в качестве поставщика услуг:
php LaravelDoctrine\ORM\DoctrineServiceProvider::class,
Псевдоним также должен быть настроен:
php 'EntityManager' => LaravelDoctrine\ORM\Facades\EntityManager::class
Наконец, мы публикуем конфигурацию пакета с:
bash php artisan vendor:publish --tag="config"
Doctrine не требуется конфигурация базы данных и используется текущая конфигурация Laravel, но если вы хотите переопределить ее, вам следует изменить конфигурационный файл Doctrine в Config/doctrine.php
:
« `php ‘manager’ => [‘default’ => [‘dev’ => env (‘APP_DEBUG’), ‘meta’ => env (‘DOCTRINE_METADATA’, ‘annotations’), ‘connection’ => env (‘DB_CONNECTION’, ‘mysql’), ‘namespaces’ => [‘App’],
« `Это все, что нужно сделать.
Что такое сущность?
«Сущность» относится к объекту, который имеет отличительную идентичность. Сущность должна иметь определенный идентификатор, который уникален во всей системе, например, клиент или студент. Были бы другие объекты, такие как адреса электронной почты, которые не являются объектами, а являются объектами значений .
Давайте создадим приложение Post Entity App/Entity/Post.php
:
« `php namespace App \ Entity;
используйте Doctrine \ ORM \ Mapping в качестве 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 (стратегии =” AUTO ”) * * / private $ id;
/ ** * @ORM \ Column (type = "string") * / личное $ title; / ** * @ORM \ Column (type = "text") * / личное $ тело; публичная функция __construct ($ input) { $ Этом-> SetTitle ($ вход [ 'название']); $ Этом-> setBody ($ вход [ 'тело']); } публичная функция getId () { вернуть $ this-> id; } публичная функция getTitle () { вернуть $ this-> title; } публичная функция setTitle ($ title) { $ this-> title = $ title; } публичная функция getBody () { вернуть $ this-> body; } публичная функция setBody ($ body) { $ this-> body = $ body; }} `` `
Свойства класса должны совпадать с полями в таблице базы данных, или вы можете определить их с помощью @Colum("name"="myfield")
.
Что такое репозиторий?
Хранилище позволяет всему вашему коду использовать объекты без необходимости знать, как эти объекты сохраняются. Хранилище содержит все знания о постоянстве, включая отображение из таблиц в объекты. Это обеспечивает более объектно-ориентированное представление персистентного уровня и делает код отображения более инкапсулированным.
Теперь пришло время создать репозиторий в App/Repository/PostRepo.php
:
« `php namespace App \ Repository; используйте App \ Entity \ Post; использовать Doctrine \ ORM \ EntityManager;
класс PostRepo {
/ ** * строка @var * / private $ class = 'App \ Entity \ Post'; / ** * @var EntityManager * / личное $ em; публичная функция __construct (EntityManager $ em) { $ this-> em = $ em; } публичная функция create (Post $ post) { $ This-> em-> сохраняются ($ пост); $ This-> Ет> флеша (); } обновление публичной функции (Post $ post, $ data) { $ Пост-> SetTitle ($ данные [ 'название']); $ Post-> setBody ($ данных [ 'тело']); $ This-> em-> сохраняются ($ пост); $ This-> Ет> флеша (); } публичная функция PostOfId ($ id) { вернуть $ this-> em-> getRepository ($ this-> class) -> findOneBy ([ 'id' => $ id ]); } публичная функция удаления (Post $ post) { $ This-> em-> удалить ($ пост); $ This-> Ет> флеша (); } / ** * создать сообщение * @return Post * / приватная функция prepareData ($ data) { вернуть новое сообщение ($ data); }}
« `
Doctrine EntityManager
работает как точка доступа для полного управления вашими сущностями. Затем создайте App/Http/Controllers/PostController.php
Controller App/Http/Controllers/PostController.php
:
« `php namespace App \ Http \ Controllers; используйте App \ Repository \ PostRepo в качестве репозитория; используйте App \ Validation \ PostValidator;
класс PostController extends Controller {private $ repo;
публичная функция __construct (repo $ repo) { $ this-> repo = $ repo; } редактирование публичной функции ($ id = NULL) { return View ('admin.index') -> with (['data' => $ this-> repo-> postOfId ($ id)]); } публичная функция editPost () { $ all = Input :: all (); $ validate = PostValidator :: validate ($ all); if (! $ validate-> pass ()) { 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'); } еще { $ This-> repo-> создать ($ this-> repo-> perpare_data ($ все)); Session :: flash («msg», «добавить успех»); } return redirect () -> back (); } публичная функция retrieve () { return View ('admin.index') -> with (['Data' => $ this-> repo-> retrieve ()]); } публичная функция delete () { $ id = Input :: get ('id'); $ data = $ this-> repo-> postOfId ($ id); if (! is_null ($ data)) { $ This-> repo-> удалить ($ данных); Session :: flash («msg», «операция успешно»); return redirect () -> back (); } еще { return redirect () -> back () -> withErrors ('operationFails'); } }} `` `Вид и маршрутизация такие же, как обычно.
Я предпочитаю создавать свой собственный Validator, основанный на классе Validator от Laravel. Вот App\Validation\PostValidator.php
Validator App\Validation\PostValidator.php
:
« `php namespace App \ Validation; использовать валидатор;
class PostValidator {общедоступная статическая функция validate ($ input) {$ rules = [‘title’ => ‘Обязательный | Мин: 4 | Макс: 80 | alpha_spaces’, ‘body’ => ‘Обязательный’,]; return Validator :: make ($ input, $ rules); }} « `
Вывод
Если вы ранее не работали с Doctrine 2, надеюсь, эта статья была интересной и информативной. Laravel 5 не использует Doctrine, но, как вы можете видеть, есть несколько пакетов, которые позволяют нам легко использовать его с Laravel. Я создал простое приложение для блогов с Laravel 5 и Doctrine ORM, и я надеюсь, что это поможет вам создать желаемое приложение. Я приветствую ваши комментарии.