PHPixie 3.0 ORM або новий погляд на ActiveRecord

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 розроблялася більше року і нам дуже цікаві всі ваші питання і зауваження, дуже чекаємо коментарів. А якщо вам цікаво дізнатися про майбутні компонентах і самому фреймворку то не забудьте підписатися на твіттер @phpixie

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.