Как стать автором
Обновить

PHPixie 3.0 ORM или новый взгяд на ActiveRecord

Время на прочтение4 мин
Количество просмотров10K
image Уже закончен долгообещанная третья версия PHPixie ORM компонента. Он теперь полностью независим от фреймворка и может спокойно использоваться сам по себе. В связи с этим, пока продолжается работа над другими компонентами и пишется документация, разработчики составили небольшой туториал для того чтобы можно было уже начать работу с ОРМ. Ниже я предоставлю его перевод и добавлю несколько вещей от себя, но сначала давайте посмотрим чем полезным порадует нас эта версия:

  • Большинство ORM используют Model классы, которые используются как для выполнения запросов так и для репрезентации самых записей в базе данных. Например так делают Kohana и Laravel. PHPixie разделила модель на Repository, Entity и Query, каждая из которых имеет строго свое предназначение.
  • Кроме SQL баз данных (SQLite, PostgreSQL, MySQL) полностью поддерживается также Mongo. Вы сможете связать отношениями модели с SQL баз данных с моделями хранящимися в коллекциях Mongo.
  • Чтобы поддерживать связи между разными базами ( например между таблицами в разных базах в MySQL ) много ORM используют отдельные запросы вместо join-ов и субзапросов. PHPixie же использует субзапросы всегда где это возможно.
  • Поддержка встроенных сущностей в Mongo
  • На 97% покрыта юнит тестами ( планируется 100% до конца этой недели), и еще на 75% функционалными тестами.
  • Эффективное использование Query позволяет уменьшить число запросов к базе. Например вам надо связать все топики автора с какими-то тегами. В большинстве ОРМ вам придется сначала найти топики, потом теги и тогда связать их ( 3 запроса к БД ). PHPixie позволяет сделать это за один запрос. Кстати пример этого есть в туториале снизу


Надеюсь я смог вас заинтересовать, теперь посмотрим на пример с ссылки вверху в переводе:


<?php

require_once('vendor/autoload.php');

$config = new \PHPixie\Config();

//Инициализация компонента базы данных
$database = new \PHPixie\Database($config->dataStorage(array(
    'default' => array(
        'driver' => 'pdo',
        'connection' => 'sqlite::memory:'
    )
)));

//И самой ОРМ
$orm = new \PHPixie\ORM($database, $config->dataStorage(array(
    'relationships' => array(
        array(
            //У феи может быть много цветов
            'type'  => 'oneToMany',
            'owner' => 'fairy',
            'items' => 'flower'
        )
    )
)));


//Создание табличек
$connection = $database->get('default');

$connection->execute('
    CREATE TABLE fairies (
      id INTEGER PRIMARY KEY,
      name VARCHAR(255)
    )
');

$connection->execute('
    CREATE TABLE flowers (
      id INTEGER PRIMARY KEY,
      name VARCHAR(255),
      fairy_id INTEGER
    )
');

//Моделей больше не существует
//Их заменяют Repositories, Entities и Query

/*
Мы все ненавидим когда сущности также являются запросами:
$fairy->name = 'Trixie';
$fairy->save();
$fairy->where('name', 'Stella')->find();
*/

//Репозитории создаются автоматически для существующих табличек
$fairyRepository = $orm->get('fairy');
$flowerRepository = $orm->get('flower');

//Это все была инициализация
//А теперь приступим

//Создадим несколько фей

$trixie = $fairyRepository->create();
$trixie->name = 'Trixie';
$trixie->save();

//Версия покороче
$fairyRepository
    ->create(array('name' => 'Stella'))
        ->save();

//А еще нам понадобятся цветки

foreach(array('Red', 'Yellow', 'Green', 'Purple') as $name) {
    $flowerRepository
        ->create(array('name' => $name))
            ->save();
}


//А теперь создадим Query
//аналог WHERE `id` > 1 AND ( `name` = 'Green' OR `name` = 'Red')
$green = $flowerRepository->query()
            ->where('id', '>', 1)
            ->startAndWhereGroup()
                ->where('name', 'Green')
                ->or('name', 'Red')
            ->endGroup()
            ->findOne();

//или лаконичнее
$green = $flowerRepository->query()
            ->where('id', '>', 1)
            ->and(function($q){
                  $q
                      ->where('name', 'Green')
                      ->or('name', 'Red')
             })
            ->findOne();

//Связи
//Каждая связь добавляет свойства в Сущности и Запросы
//В нашем случае свойство 'flowers' предоставляет методы add(), remove() и removeAll()
//Это намного удобнее чем методы addFlower(), removeFlower() и removeAllFlowers() на самом объекте
$trixie->flowers->add($green);

//При связывании объектов, значение кешируется сразу в обе стороны
//чтобы избежать дополнительных запросов к базе
//В даном случае это кажется на таким уж важным, так как добиться такого эффекта
//для oneToMany достаточно просто. Но для manyToMany оно тоже будет работать
assert($green->fairy() == $trixie);

//Теперь попробуем связать все цветы кроме Green c феей Stella
//И уложиться в один запрос

//Зададим запрос который нашел бы Стеллу
$stellaQuery = $fairyRepository->query()
                    ->where('name', 'Stella');

//И запрос который найдет цветы
$allExceptGreen = $flowerRepository->query()
                    ->whereNot('name', 'Green');

//И теперь магия
$stellaQuery->flowers->add($allExceptGreen);


//Также Query позволяет изменять сущности без выборки
//Например переименуем цветок Purple в Blue
$flowerRepository->query()
    ->where('name', 'Purple')
    ->update(array(
        'name' => 'Blue'
    ));

//Можно найти фею у которой есть определенный цветок:
$trixie = $fairyRepository->query()
                    ->relatedTo('flowers', $green)
                    ->findOne();

//А теперь найдем всех фей у которых есть хотя бы один цветок
//И сразу подгрузим все их цветки
$fairies = $fairyRepository->query()
                    ->relatedTo('flowers')
                    ->find(array('flowers')); //так задается прелоудинг связей

//И выведем их как простые объекты
//Удобно для json_encode()
print_r($fairies->asArray(true));


//Больше примеров потом =)


Попробовать этот пример у себя достаточно просто:

git clone https://github.com/phpixie/orm
cd orm/examples
 
#если у вас еще нет Композера
curl -sS https://getcomposer.org/installer | php
 
php composer.phar install
php quickstart.php


Эта ORM разрабатывалась больше года и нам очень интересны все ваши вопросы и замечания, очень ждем комментариев.
Теги:
Хабы:
Всего голосов 28: ↑20 и ↓8+12
Комментарии54

Публикации