Pull to refresh

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

Reading time4 min
Views10K
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 разрабатывалась больше года и нам очень интересны все ваши вопросы и замечания, очень ждем комментариев.
Tags:
Hubs:
Total votes 28: ↑20 and ↓8+12
Comments54

Articles