Говоря как кто-то, кто потратил довольно много времени на работу с JPA (Java Persistence API, в основном стандартизированный ORM API для Java / J2EE / EJB), который включает Hibernate, EclipseLink, Toplink, OpenJPA и другие, я поделюсь некоторыми из моих наблюдения.
- ОРМ не быстр. Они могут быть адекватными, и в большинстве случаев адекватными - это нормально, но в среде с большими объемами и малой задержкой их нет - нет;
- В языках программирования общего назначения, таких как Java и C #, вам нужно очень много магии, чтобы заставить их работать (например, ткачество во время загрузки в Java, инструментарий и т. Д.);
- При использовании ORM вместо того, чтобы идти дальше от SQL (что, похоже, и задумано), вы будете удивлены, сколько времени вы тратите на настройку XML и / или аннотаций / атрибутов, чтобы ваш ORM генерировал производительный SQL;
- Для сложных запросов действительно нет замены. Как и в JPA, есть некоторые запросы, которые просто невозможны, которые находятся в сыром SQL, и когда вам нужно использовать сырой SQL в JPA, это не очень красиво (C # /. Net, по крайней мере, имеет динамические типы - var - что много лучше, чем массив объектов);
- При использовании ORM очень много "ловушек". Это включает непреднамеренное или непредвиденное поведение, тот факт, что вам необходимо встроить возможность обновления SQL в вашей базе данных (с использованием refresh () в JPA или аналогичными методами, поскольку JPA по умолчанию кэширует все, поэтому он не перехватывает прямую базу данных). update - выполнение прямых обновлений SQL является распространенным видом деятельности поддержки производства);
- Несоответствие между объектами и отношениями всегда вызывает проблемы. В любой такой проблеме есть компромисс между сложностью и полнотой абстракции. Временами я чувствовал, что JPA зашел слишком далеко и достиг реального закона убывающей доходности, когда сложность не оправдывалась абстракцией.
Есть еще одна проблема, которая требует немного большего объяснения.
Традиционная модель для веб-приложения состоит в том, чтобы иметь уровень персистентности и уровень представления (возможно, между службами или другими уровнями между ними, но это важные два для этого обсуждения). ORM обеспечивают строгий просмотр от вашего уровня персистентности до уровня представления (т.е. ваших сущностей).
Одна из критических замечаний относительно более сырых методов SQL заключается в том, что вы в конечном итоге получаете все эти VO (объекты значений) или DTO (объекты передачи данных), которые используются просто одним запросом. Это рекламируется как преимущество ORM, потому что вы избавляетесь от этого.
Дело в том, что эти проблемы не исчезают с ORM, они просто переходят на уровень представления. Вместо создания VO / DTO для запросов вы создаете пользовательские объекты презентации, обычно по одному для каждого представления. Как это лучше? ИМХО это не так.
Я написал об этом в ORM или SQL: мы уже там? ,
Моя постоянная технология выбора (на Java) в эти дни - ibatis. Это довольно тонкая оболочка для SQL, которая делает на 90% больше того, что может сделать JPA (она может даже выполнять ленивую загрузку отношений, хотя и не очень хорошо документирована), но с гораздо меньшими накладными расходами (с точки зрения сложности и реального кода).
Это появилось в прошлом году в приложении GWT, которое я писал. Много переводов из EclipseLink в объекты презентации в реализации сервиса. Если бы мы использовали ibatis, было бы гораздо проще создать соответствующие объекты с помощью ibatis, а затем передавать их все время вверх и вниз по стеку. Некоторые пуристы могут утверждать, что это Bad ™. Возможно, так (в теории), но я скажу вам, что: это привело бы к более простому коду, более простому стеку и большей производительности.