Doctrine 2
Шатов Максим
Разработчик
Maxim.Shatov@softline.ru
2013.01.25
Doctrine 2 состоит из трех основных библиотек

Common
общие компоненты, которые используются в других
библиотеках/пакетах

DBAL
слой абстракции от БД

ORM
инструменты объектно-реляционного отображения
Doctrine Common

Загрузчик классов
основан на широко используемых соглашениях о пространствах имен,
имен классов и структуре каталогов

Аннотации
аннотации в стиле DocBlock к классам PHP

Кеширование
«из коробки» доступны:
ApcCache, ArrayCache, FilesystemCache, FilesystemCache,
MemcachedCache, PhpFileCache, RedisCache, WinCacheCache,
XcacheCache, ZendDataCache
Аннотации

namespace Entities;
/**
* @Entity @Table(name="users")
*/
class User
{
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
/** @Column(length=50) */
private $name;
/** @OneToOne(targetEntity="Address") */
private $address;
}
Doctrine DBAL

Конструктор запросов
Управление транзакциями
Менеджер схемы БД
Менеджер событий
Обеспечение безопасности
(защита от sql-инъекций)

Поддержка различных БД
Кеширование
Doctrine ORM

Позволяет отображать объекты PHP в таблицы
базы данных
Использование аннотаций, XML или YAML для
метаданных
Связи между объектами отображаются как
внешние ключи
Отношение объекта ко многим обрабатывается
как коллекция
Выборка из базы данных при помощи
менеджера объектов, репозитория или
запроса любой сложности на языке
DQL(Doctrine Query Language)
Интерфейс командной строки

Создание «геттеров» и «сеттеров»
Создание таблиц/схемы для БД
Миграции
Фикстуры
Импорт отображения объектов из существующей
базы данных
Очистка кеша метаданных/запросов/результатов
Выполнение запросов
Отображение объектов в базу данных

Отображаются
Объекты
Связи
Отношения
наследование/суперклассы, переопределение
связей/полей

Способы задания
Аннотации
XML
YAML
PHP
Использование суперклассов и подклассов

/** @MappedSuperclass */
class MappedSuperclassBase
{
/** @Column(type="integer") */
private $mapped1;
/** @Column(type="string") */
private $mapped2;
/**
* @OneToOne(targetEntity="SuperclassRelated1")
* @JoinColumn(name="related1_id",
referencedColumnName="id")
*/
private $mappedRelated1;
// ... more fields and methods
}
Использование суперклассов и подклассов

/** @Entity */
class EntitySubClass extends MappedSuperclassBase
{
/** @Id @Column(type="integer") */
private $id;
/** @Column(type="string") */
private $name;
// ... more fields and methods
}
Наследование с использованием дискриминаторов

/**
* @Entity
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"person" = "Person", "employee" =
"Employee"})
*/
class Person
{
// ...
}
/**
* @Entity
*/
class Employee extends Person
{
// ...
}
Работа с объектами

Базовое
Сущности
Связи
События

Запросы
DQL
Конструктор запросов
Нативный SQL

Внутренняя структура
Отслеживание изменения объектов
Несколько слоёв ORM
Двунаправленные связи
Обновление связанных объектов
Вставка записей используя Doctrine

for ($i = 0; $i < 20; ++$i) {
$user = new User;
$user->name = 'Иванов А.Д.';
$em->persist($user);
}
$s = microtime(true);
$em->flush();
$e = microtime(true);
echo $e - $s;
Вставка записей используя «сырой» код PHP

$s = microtime(true);
for ($i = 0; $i < 20; ++$i) {
mysql_query("INSERT INTO users (name) VALUES
('Иванов А.Д.')");
}
$e = microtime(true);
echo $e - $s;
Сравнение результатов

Doctrine 2 0.0094 секунд
mysql_query 0.0165 секунд
Вставка записей используя «сырой» код PHP v2

$s = microtime(true);
mysql_query('START TRANSACTION');
for ($i = 0; $i < 20; ++$i) {
mysql_query("INSERT INTO users (name) VALUES
('Иванов А.Д.')");
}
mysql_query('COMMIT');
$e = microtime(true);
echo $e - $s;
0.0028 секунд
Жизненный цикл и обработчики событий

preRemove
postRemove
prePersist
postPersist
preUpdate
postUpdate
postLoad
loadClassMetadata
/** @Entity @HasLifecycleCallbacks */
class User {
/**
* @Column(type="string", length=255)
*/
public $value;
/** @PrePersist */
public function doStuffOnPrePersist() {
$this->value = date('Y-m-d H:m:s');
}
/** @PrePersist */
public function doOtherStuffOnPrePersist() {
$this->value = 'changed from prePersist callback!';
}
/** @PostLoad */
public function doStuffOnPostLoad() {
$this->value = 'changed from postLoad callback!';
}
}
Спасибо за внимание!
Вопросы?

Doctrine 2

  • 1.
  • 2.
    Doctrine 2 состоитиз трех основных библиотек Common общие компоненты, которые используются в других библиотеках/пакетах DBAL слой абстракции от БД ORM инструменты объектно-реляционного отображения
  • 3.
    Doctrine Common Загрузчик классов основанна широко используемых соглашениях о пространствах имен, имен классов и структуре каталогов Аннотации аннотации в стиле DocBlock к классам PHP Кеширование «из коробки» доступны: ApcCache, ArrayCache, FilesystemCache, FilesystemCache, MemcachedCache, PhpFileCache, RedisCache, WinCacheCache, XcacheCache, ZendDataCache
  • 4.
    Аннотации namespace Entities; /** * @Entity@Table(name="users") */ class User { /** @Id @Column(type="integer") @GeneratedValue */ private $id; /** @Column(length=50) */ private $name; /** @OneToOne(targetEntity="Address") */ private $address; }
  • 5.
    Doctrine DBAL Конструктор запросов Управлениетранзакциями Менеджер схемы БД Менеджер событий Обеспечение безопасности (защита от sql-инъекций) Поддержка различных БД Кеширование
  • 6.
    Doctrine ORM Позволяет отображатьобъекты PHP в таблицы базы данных Использование аннотаций, XML или YAML для метаданных Связи между объектами отображаются как внешние ключи Отношение объекта ко многим обрабатывается как коллекция Выборка из базы данных при помощи менеджера объектов, репозитория или запроса любой сложности на языке DQL(Doctrine Query Language)
  • 7.
    Интерфейс командной строки Создание«геттеров» и «сеттеров» Создание таблиц/схемы для БД Миграции Фикстуры Импорт отображения объектов из существующей базы данных Очистка кеша метаданных/запросов/результатов Выполнение запросов
  • 8.
    Отображение объектов вбазу данных Отображаются Объекты Связи Отношения наследование/суперклассы, переопределение связей/полей Способы задания Аннотации XML YAML PHP
  • 9.
    Использование суперклассов иподклассов /** @MappedSuperclass */ class MappedSuperclassBase { /** @Column(type="integer") */ private $mapped1; /** @Column(type="string") */ private $mapped2; /** * @OneToOne(targetEntity="SuperclassRelated1") * @JoinColumn(name="related1_id", referencedColumnName="id") */ private $mappedRelated1; // ... more fields and methods }
  • 10.
    Использование суперклассов иподклассов /** @Entity */ class EntitySubClass extends MappedSuperclassBase { /** @Id @Column(type="integer") */ private $id; /** @Column(type="string") */ private $name; // ... more fields and methods }
  • 11.
    Наследование с использованиемдискриминаторов /** * @Entity * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) */ class Person { // ... } /** * @Entity */ class Employee extends Person { // ... }
  • 12.
    Работа с объектами Базовое Сущности Связи События Запросы DQL Конструкторзапросов Нативный SQL Внутренняя структура Отслеживание изменения объектов Несколько слоёв ORM Двунаправленные связи Обновление связанных объектов
  • 13.
    Вставка записей используяDoctrine for ($i = 0; $i < 20; ++$i) { $user = new User; $user->name = 'Иванов А.Д.'; $em->persist($user); } $s = microtime(true); $em->flush(); $e = microtime(true); echo $e - $s;
  • 14.
    Вставка записей используя«сырой» код PHP $s = microtime(true); for ($i = 0; $i < 20; ++$i) { mysql_query("INSERT INTO users (name) VALUES ('Иванов А.Д.')"); } $e = microtime(true); echo $e - $s;
  • 15.
    Сравнение результатов Doctrine 20.0094 секунд mysql_query 0.0165 секунд
  • 16.
    Вставка записей используя«сырой» код PHP v2 $s = microtime(true); mysql_query('START TRANSACTION'); for ($i = 0; $i < 20; ++$i) { mysql_query("INSERT INTO users (name) VALUES ('Иванов А.Д.')"); } mysql_query('COMMIT'); $e = microtime(true); echo $e - $s; 0.0028 секунд
  • 17.
    Жизненный цикл иобработчики событий preRemove postRemove prePersist postPersist preUpdate postUpdate postLoad loadClassMetadata
  • 18.
    /** @Entity @HasLifecycleCallbacks*/ class User { /** * @Column(type="string", length=255) */ public $value; /** @PrePersist */ public function doStuffOnPrePersist() { $this->value = date('Y-m-d H:m:s'); } /** @PrePersist */ public function doOtherStuffOnPrePersist() { $this->value = 'changed from prePersist callback!'; } /** @PostLoad */ public function doStuffOnPostLoad() { $this->value = 'changed from postLoad callback!'; } }
  • 19.

Editor's Notes

  • #3 &lt;номер&gt;