ORM - миф. Когда остановиться?

Духовность™

Продвинутый новичок
ORM - миф. Когда остановиться?

Написал ORM систему для одной записи таблицы, совместив её с партерном DataMapper. Ну или типа того..

Итого я имею:

PHP:
$user_mapper = new User_Mapper();

$object = $user_mapper->creteFromPost($_POST); // создали из POST-a

$object = $user_mapper->createNew(); // создали пустой объект 

$user_mapper->save($object); // сохранили объект 

$user_mapper->delete($object); // удалили объект 

$user_mapper->findById(5); // нашли объект по ID 
// теперь распечатаем 
echo 'Привет, '.$object->getName().', 
последний раз ты заходил '.
$object->getDaleLastVisit()->format('H:i:s'); 

$user_mapper->findByParams(5); // нашли объект по массиву $params 

// нашли список объектов по массиву $params 
$objects_list = $user_mapper->findObjectsList($params); 
foreach ($objects_list as $object)
{
    echo $object=>getName().'<br />';
}
всё это работает черезвычайно здорово, красиво, оопшно, классно, рульно и т.д. Особенно это всё удобно использовать тогда, когда нужно делать какие-то простые выборки, например, для админ-части, при работе с записью и списком строк из таблицы.

Но ценность и практичность всего этого убывает, когда нужно делать сложные выборки. Например, вывести список пользователей в колонки, и рядом города/страны/регионы, в которых они проживают. Т.е. сделать JOIN таблиц - user, country, region, city.

При возникновении такой задачи есть несколько основных способов решения:

1. Использовать "полноценный" готовый ORM
Я не хочу использовать стороннюю наработку, т.к. это фактически движок, очень важная вещь в проекте и если что-то пойдет не так, то все накроется медным тазом. Т.е. я за полный контроль над своим кодом. В конце-концов, существующие ORM меня просто пугают своим огромным "клиентским" кодом (объекты Criteria и т.д).

2. Писать свой ORM дальше, до попытки создать систему, которая будет делать что-то из разряда танца с бубном и выдавать нужный результат.
Очень нетривиальная идея. А судя по многим мнениям, полноценного решения все равно не получится, или получится глючный монстр.

3. Совмещение Object-модели и plain SQL в ORM
Это то, что я вижу гораздо чаще в решениях. Суть такова, что ORM/Mapper поддерживает базовый объектный функционал, такой как я привел выше, а все сложные запросы оформляются в виде методов в ORM/Mapper-классах в виде SQL:
PHP:
class my_super_orm {
    // методы для работы с объектами
    object public function save($object) {...}
    object public function findById($object) {...}
    object public function delete($object) {...}

    // методы оперирующие "сложными" SQL-запросами 

    // возвратить список пользователей и города/регионы/страны 
    // в которых они проживают (реальный SQL) 
    array public function getUsersListWithResidence()
    {
        $sql = 'SELECT SQL_CALC_FOUND_ROWS
                    user.id,
                    user.user_active,
                    IFNULL(user.user_first_name, user.user_login) AS user_first_name,
                    user.user_last_name,
                    user.user_regdate,
                    user.user_visitdate,
                    user.user_mail,
                    user.user_url, 
                    user_icq,
                    user.user_city,
                    user.user_region,
                    user.user_country,
                    country.country_name,
                    region.region_name,
                    city.city_name
                FROM
                    user, country, region, city .... ';

        // .....
    }
В данном случае метод getUsersListWithResidence вернет уже НЕ объекты, а простой массив записей, результат mysql_fetch_assoc().

Собственно вот - задача, которая является, на мой взгляд, одной из основных в программировании. Как её решать, в какую сторону двигаться?

С одной стороны, хочется универсальности.
С другой стороны, смешение plain SQL и ОО-моделей приводит к какой-то неуклюжей архитектуре. Ну как так - один метод объект возвращает, другой массив строк. WTF?
А стремление угнаться за ОО-моделью приводит к появлению сложных решений, один только вид их запросов приводит в ужас.

Как быть?
 

fixxxer

К.О.
Партнер клуба
а что мешает для plain sql возвращать такой же объект?
 

HraKK

Мудак
Команда форума
А я в последнее время предпочитаю решать проблемы, а не думать над красотой кода. старею :(
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
я не юзаю ORM. времени экономит мало, а мороки и дебага с ним много
впрочем, иногда думаю, что, возможно, я не разобрался
 

zerkms

TDD infected
Команда форума
А я в последнее время предпочитаю решать проблемы, а не думать над красотой кода.
как ни странно - но ОРМ позволяет их решать быстрее и чаще всего эффективнее :)

Я не хочу использовать стороннюю наработку, т.к. это фактически движок, очень важная вещь в проекте и если что-то пойдет не так, то все накроется медным тазом.
очень странно это слышать от человека, который использует разработанный другими ЯП, крутящийся под разработанным сторонней компанией вебсервером, который запущен на ОС, которую также написала сторонняя компания. и это всё добро работает на железе, которое "спаяли" сторонние компании.
 

melo

однажды
я бы взял, а я и взял готовую ORM. Запаришся все время, все сам писать. Доктрину, например, не дураки делали. Сначала помучаешся, поворчишь, но в конечном результате будешь доволен.
 

tz-lom

Продвинутый новичок
сложно судить что вам сделать с велосипедом,ибо никакого описания велика тут как бы и нет
В данном случае метод getUsersListWithResidence вернет уже НЕ объекты, а простой массив записей, результат mysql_fetch_assoc().
и смысл тогда от ОРМ ?
а вообще есть такая извечная тема как велосипедостроение,суть в том что сначала получается класный велик,а потом он не вписывается в повороты,а дорабатывать/дебажить времени нет,ибо надо двигаться дальше
мораль: не надо писать велики без анализа того ,какую проблему они будут решать
 

Wicked

Новичок
я тоже за готовую орм, но все же за пропел 1.5. Функционал почти тот же, что и в доктрине 1.х, но при этом он сильно меньше глючит - в доктрине, например, долгое время не было валидации dql, из-за чего даже совсем невалидные запросы обрезались в удобном месте и исполнялись, вместо того, чтобы падать. Это вроде исправили в доктрине 2.0, но она требует пхп5.3, так что я пока пас :)

-~{}~ 25.06.10 13:04:

В данном случае метод getUsersListWithResidence вернет уже НЕ объекты, а простой массив записей, результат mysql_fetch_assoc().
в нормальных ормках с этим все ок - http://www.propelorm.org/browser/branches/1.5/runtime/lib/formatter/PropelObjectFormatter.php#L74
 

Alexandre

PHPПенсионер
я не юзаю ORM. времени экономит мало, а мороки и дебага с ним много
впрочем, иногда думаю, что, возможно, я не разобрался
+1
лично я использую подход 3
все действия с объектом данных заварачиваю в объект, который уже общается с таблицами (или одной тбл)
 

Krishna

Продался Java
Суть поста ТС - "Не могу разобраться в том, как работают ОРМ"
 

Духовность™

Продвинутый новичок
Суть поста ТС - "Не могу разобраться в том, как работают ОРМ"
Суть моего поста - понять, насколько нужно далеко можно и нужно заходить с ORM, как это делают другие, насколько технология ORM является жизнеспособной.

и смысл тогда от ОРМ ?
смысл в том, что с простыми запросами мы умеем работать, почти как ActiveRecord паттерн. С выборкой через JOIN - нет. И, насколько я понимаю, НЕ существует в мире ни одного ORM, который умел бы каким-то магическим образом исполнять ЛЮБОЙ SQL. Т.е. попытка создать ORM на все случаи жизни - это утопия. Если это утопия, то есть ли смысл идти дальше, объять необъятное, когда можно остановиться на определённом этапе и юзать plain SQL?
 

AmdY

Пью пиво
Команда форума
Внимательно прочти комменты
а что мешает для plain sql возвращать такой же объект?
и смысл тогда от ОРМ ?
Ты идеологически неверно воспринимаешь ORM, который служит не для упрощения и автоматизации выборок, а для того, чтобы возвращался ОБЪЕКТ, который не только умеет работать с БД, но и обладает знаниями чтобы выполнять логику домена (например, когда ты удаляешь пользователя, то он чистит все связанные таблицы, удаляет файлы и т.д.).
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: AmdY
...например, когда ты удаляешь пользователя, то он чистит все связанные таблицы...
и почему мне кажется, что пересечения множества людей, которые "смогли разобраться с ОРМ" с множеством людей, которые не смогли разобраться с внешними ключами непусто?..
 

Farsh

~ on ~ high ~ wave ~
Автор оригинала: zerkms
как ни странно - но ОРМ позволяет их решать быстрее и чаще всего эффективнее :)
Это так, но к батч скриптам это точно не относится. У той же доктрины ВЕЗДЕ memory leak - и в ORM, и в DBAL. Вот там я возненавидел ей.
 

С.

Продвинутый новичок
ORM, который служит не для упрощения и автоматизации выборок, а для того, чтобы возвращался ОБЪЕКТ, который не только умеет работать с БД, но и обладает знаниями чтобы выполнять логику домена
Так в том и вопрос: стоит ли строить объект конкретного домена из громоздкого объекта общего назначения ORM? Может проще построить нормальный объект, оперирующий данными, согласно домену, а в бэкенд ему поместить простые оптимизированные запросы. Там их будет всегда счетное количество, не грех и подправить под нужную БД.

Политика партии сохранена и огород не нагорожен.
 

pilot911

Новичок
Автор оригинала: С.
Так в том и вопрос: стоит ли строить объект конкретного домена из громоздкого объекта общего назначения ORM? Может проще построить нормальный объект, оперирующий данными, согласно домену, а в бэкенд ему поместить простые оптимизированные запросы. Там их будет всегда счетное количество, не грех и подправить под нужную БД.

Политика партии сохранена и огород не нагорожен.
+1... сколько ни делал заходов в Доктрину, так и не нашел преимуществ с точки зрения повышения производительности работы
 

Макс

Старожил PHPClub
Автор оригинала: triumvirat
отсутствие реализации, которая бы позволяла это делать быстро и эффективно АВТОМАТИЧЕСКИ.
у тебя есть результат запроса. Из него можно получить список полей и таблиц (многие db-клиенты позволяют это). Если у тебя одной таблице соответствует один объект, то написать реализацию - не проблема
 

AmdY

Пью пиво
Команда форума
Sad Spirit
Внешние ключи как раз разносят логику между sql базой и моделью. опять же удаляемые звязанные объекты могут требовать не только удаления из таблицы, но и фаловых операций, отсылки сообщения и т.д. Не сделаем, порушим домен.

С.
угу, я к этому и веду, ORM не тупой QueryBuilder, который зачастую мешает. В той же доктрине есть возможность строить произвольный запрос, но указать врапер для возвращаемых данных.
 
Сверху