После использования Hibernate в большинстве моих проектов в течение примерно 8 лет я попал в компанию, которая не одобряет его использование и хочет, чтобы приложения взаимодействовали с БД только через хранимые процедуры.
После того, как я делал это в течение нескольких недель, я не смог создать богатую модель предметной области приложения, которое я начинаю собирать, и приложение просто выглядит как (ужасный) транзакционный скрипт.
Некоторые из проблем, которые я нашел:
- Невозможно перемещаться по графу объектов, так как хранимые процедуры просто загружают минимальный объем данных, а это означает, что иногда у нас есть похожие объекты с разными полями. Один из примеров: у нас есть хранимая процедура для получения всех данных от клиента, а другая - для получения информации об учетной записи, а также несколько полей от клиента.
- Большая часть логики заканчивается вспомогательными классами, поэтому код становится более структурированным (с сущностями, используемыми в качестве старых структур Си).
- Более скучный код скаффолдинга, так как нет структуры, которая извлекает наборы результатов из хранимой процедуры и помещает ее в сущность.
Мои вопросы:
- кто-нибудь был в подобной ситуации и не согласен с подходом к процедуре хранения? что ты сделал?
- Есть ли реальная выгода от использования хранимых процедур? кроме глупой точки «никто не может выпустить дроп-стол».
- Есть ли способ создать богатый домен с помощью хранимых процедур? Я знаю, что есть возможность использовать AOP для внедрения DAO / Repositories в сущности, чтобы иметь возможность перемещаться по графу объектов. Мне не нравится этот вариант, так как он очень близок к вуду.
Вывод
Во-первых, спасибо всем за ваши ответы. Я пришел к выводу, что ORM не позволяют создавать модели Rich Domain (как упоминали некоторые люди), но это упрощает объем (часто повторяющихся) работ. Ниже приведено более подробное объяснение заключения, но оно не основано на каких-либо достоверных данных.
Большинство приложений запрашивают и отправляют информацию в другие системы. Для этого мы создаем абстракцию в терминах модели (например, бизнес-событие), а модель домена отправляет или получает событие. Событию обычно требуется небольшое подмножество информации из модели, но не вся модель. Например, в интернет-магазине платежный шлюз запрашивает некоторую информацию о пользователе и общую сумму, которая взимается с пользователя, но не требует истории покупок, доступных продуктов и всей клиентской базы. Таким образом, событие имеет небольшой и конкретный набор данных.
Если мы берем базу данных приложения в качестве внешней системы, то нам нужно создать абстракцию, которая позволяет нам отображать сущности модели домена в базу данных ( как упомянул НимЧимпски , используя средство отображения данных). Очевидное различие заключается в том, что теперь нам необходимо вручную сопоставить для каждой сущности модели базу данных (либо унаследованную схему, либо хранимые процедуры), при этом возникает дополнительная проблема, заключающаяся в том, что, поскольку эти два объекта не синхронизированы, одна сущность домена может отображаться частично к объекту базы данных (например, класс UserCredentials, который содержит только имя пользователя и пароль, сопоставлен с таблицей Users, имеющей другие столбцы), или один объект модели домена может отображаться на более чем один объект базы данных (например, если существует однозначный одно отображение на таблицу, но мы хотим, чтобы все данные были только в одном классе).
В приложении с несколькими сущностями объем дополнительной работы может быть небольшим, если нет необходимости перемещать сущности, но он увеличивается, когда возникает условная необходимость пересечь сущности (и, таким образом, мы можем захотеть реализовать своего рода «ленивый»). загрузка '). По мере того, как в приложении растет число сущностей, эта работа только увеличивается (и у меня есть чувство, что оно увеличивается нелинейно). Здесь я предполагаю, что мы не пытаемся заново изобрести ORM.
Одно из преимуществ обработки БД как внешней системы заключается в том, что мы можем кодировать ситуации, в которых нам нужны 2 разные версии приложения, в которых каждое приложение имеет свое сопоставление. Это становится более интересным в сценарии непрерывных поставок в производство ... но я думаю, что это также возможно с ORM в меньшей степени.
Я собираюсь отклонить аспект безопасности на том основании, что разработчик, даже если он не имеет доступа к базе данных, может получить большую часть, если не всю информацию, хранящуюся в системе, просто путем внедрения вредоносного кода (например, Я не могу поверить, что я забыл удалить строку, которая регистрирует данные кредитной карты клиентов, дорогой лорд! ).
Небольшое обновление (6/6/2012)
Хранимые процедуры (по крайней мере, в Oracle) не позволяют делать что-либо, например, непрерывную доставку с нулевым временем простоя, поскольку любое изменение структуры таблиц приведет к аннулированию процедур и триггеров. Поэтому во время обновления БД приложение также будет недоступно. Oracle предлагает решение для этого, называемого Переопределение на основе редакции , но несколько администраторов баз данных, которых я спрашивал об этой функции, отметили, что она плохо реализована и не поместит ее в рабочую БД.