Будьте в спящем режиме или JDBC

Можно сделать некоторые интересные вещи со стеком. Например, у Вас есть функции как alloca (предполагающий, что можно закончить обильные предупреждения относительно его использования), который является формой malloc, который конкретно использует стек, не "кучу", для памяти.

Тем не менее стековые ошибки памяти являются некоторыми худшими, которые я испытал. Если Вы используете память "кучи", и Вы переступаете через границы своего выделенного блока, у Вас есть достойный шанс инициирования отказа сегментов. (Не 100%: Ваш блок может быть случайно непрерывным с другим, что Вы ранее выделили.), Но так как переменные, созданные на стеке, всегда непрерывны друг с другом, писание за пределы может изменить значение другой переменной. Я узнал, что каждый раз, когда я чувствую, что моя программа прекратила подчиняться законам логики, это - вероятно, переполнение буфера.

68
задан topchef 30 August 2009 в 06:23
поделиться

6 ответов

Хороший вопрос без единого простого ответа.

Раньше я был большой поклонник Hibernate после его использования в нескольких проектах в течение нескольких лет. Раньше я считал, что любой проект должен по умолчанию переходить в спящий режим.

Сегодня я не так уверен.

Спящий режим (и JPA) отлично подходит для некоторых вещей, особенно на ранних этапах цикла разработки. Намного быстрее приступить к работе с Hibernate, чем с JDBC. Вы получаете множество функций бесплатно - кэширование, оптимистическую блокировку и т. Д.

С другой стороны, это связано с некоторыми скрытыми расходами. Hibernate обманчиво прост, когда вы запускаете . Следуйте руководству, добавьте аннотации к своему классу - и вы проявите настойчивость. Но это непросто, и для того, чтобы писать на нем хороший код, требуется хорошее понимание как его внутренней работы, так и структуры базы данных. Если вы только начинаете, возможно, вы не знаете о некоторых проблемах, которые могут вас укусить позже, поэтому вот неполный список.

Производительность

Производительность во время выполнения достаточно хорошая, мне еще предстоит увидеть ситуацию, когда спящий режим был причиной плохой производительности в производстве . Проблема заключается в производительности запуска и в том, как она влияет на время выполнения модульных тестов и производительность разработки. Когда спящий режим загружается, он анализирует все сущности и выполняет много предварительных кэширования - это может занять около 5-10-15 секунд для не очень большого приложения. Итак, ваш 1-секундный модульный тест теперь займет 11 секунд. Не весело.

Независимость от базы данных

Это очень круто, если вам не нужно делать некоторую тонкую настройку базы данных.

Сеанс в памяти

Для каждой транзакции Hibernate будет сохранять объект в памяти для каждой строки базы данных, которую он "касается". Это хорошая оптимизация, когда вы делаете простой ввод данных. Однако, если вам по какой-то причине нужно обработать большое количество объектов, это может серьезно повлиять на производительность, если вы явно и тщательно не очистите сеанс в памяти самостоятельно.

Каскады

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

Ленивая загрузка

Ленивая загрузка означает, что каждый раз, когда вы загружаете объект, спящий режим не будет загружать все связанные с ним объекты, а вместо этого предоставит заполнители, которые будут разрешены как только вы попытаетесь получить к ним доступ. Отличная оптимизация, правда? Это так, за исключением того, что вам нужно знать об этом поведении, иначе вы получите загадочные ошибки. Google "LazyInitializationException" для примера. И будьте осторожны с производительностью. В зависимости от порядка загрузки объектов и графа объектов вы можете нажать «n + 1 выбирает проблему». Для получения дополнительной информации погуглите.

Обновления схемы

Hibernate позволяет легко изменять схему путем простого рефакторинга кода Java и перезапуска. Это здорово, когда начинаешь. Но потом вы выпускаете первую версию. И если вы не хотите потерять клиентов, вам необходимо предоставить им сценарии обновления схемы. Это означает, что больше не будет простого рефакторинга, поскольку все изменения схемы должны выполняться на SQL.

Представления и хранимые процедуры

Для Hibernate требуется эксклюзивный доступ на запись к данным, с которыми он работает. Это означает, что вы не можете использовать представления, хранимые процедуры и триггеры, поскольку они могут вызывать изменения данных, когда спящий режим не знает о них. Некоторые внешние процессы могут записывать данные в базу данных в виде отдельных транзакций. Но если вы это сделаете, в вашем кеше будут недопустимые данные. Это еще одна вещь, о которой нужно позаботиться.

Однопотоковые сеансы

Сеансы гибернации являются однопоточными. К любому объекту, загруженному через сеанс, можно получить доступ (включая чтение) только из того же потока. Это приемлемо для серверных приложений, но может усложнить ненужные вещи, если вы работаете с приложением на основе графического интерфейса.

Я полагаю, что моя точка зрения состоит в том, что бесплатного питания не существует.

Hibernate - хороший инструмент, но это сложный инструмент, и для его правильного понимания требуется время. Если вы или члены вашей команды не обладаете такими знаниями, может быть проще и быстрее использовать чистый JDBC (или Spring JDBC) для одного приложения.

184
ответ дан 24 November 2019 в 14:01
поделиться

Hibernate может быть хорошим, но он и другие ORM JPA имеют тенденцию до некоторой степени определять структуру вашей базы данных. Например, составные первичные ключи можно создать в Hibernate / JPA, но это немного неудобно. Есть и другие примеры.

Если вам нравится SQL, я настоятельно рекомендую вам взглянуть на Ibatis . Он может делать более 90% того, что может Hibernate, но гораздо проще в реализации.

Я не могу придумать ни одной причины, по которой я когда-либо выбрал бы прямой JDBC (или даже Spring JDBC) вместо Ibatis. Hibernate - более сложный вариант.

Взгляните на Spring and Ibatis Tutorial .

20
ответ дан 24 November 2019 в 14:01
поделиться

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

Где Hibernate действительно сияет для меня, так это отношения между сущностями / таблицами. Выполнение JDBC вручную может занять много кода, если вы имеете дело с одновременным изменением родительских и дочерних элементов (внуков, братьев и сестер и т.д.). Hibernate может упростить эту задачу (часто достаточно одного сохранения родительской сущности).

Конечно, при работе с Hibernate есть определенные сложности, такие как понимание того, как работает сброс сеанса, и работа с отложенной загрузкой.

5
ответ дан 24 November 2019 в 14:01
поделиться

Прямой JDBC в лучшем случае подходит для самых простых случаев.

Если вы хотите оставаться в рамках Java и OOD, то вам следует выбрать Hibernate или Hibernate / JPA или любой другой-JPA-provider / JPA.

Если вам удобнее работать с SQL, то наличие Spring для шаблонов JDBC и других SQL-ориентированных фреймворков не повредит.

Напротив, помимо управления транзакциями, Spring при работе с JPA не очень помогает.

3
ответ дан 24 November 2019 в 14:01
поделиться

Несомненно, Hibernate имеет свою сложность.

Но что мне действительно нравится в подход Hibernate (некоторые другие тоже) - это концептуальная модель, которую вы можете получить на Java, лучше. Хотя я не считаю объектно-ориентированный подход панацеей и не ищу теоретической чистоты дизайна, я много раз обнаруживал, что объектно-ориентированный объект действительно упрощает мой код. Как вы конкретно просили предоставить подробности, вот несколько примеров:

  • дополнительная сложность не в модели и сущностях, а в вашей структуре, например, для управления всеми сущностями. Для специалистов по сопровождению сложная часть - это не несколько классов фреймворка, а ваша модель, поэтому Hibernate позволяет поддерживать жесткую часть (модель) в самом чистом виде.

  • если поле (например, идентификатор или поля аудита, и т.д.) используется во всех ваших сущностях, тогда вы можете создать с ним суперкласс . Следовательно:

    • вы пишете меньше кода, но, что более важно ...
    • в вашей модели меньше концепций (уникальная концепция уникальна в коде)
    • бесплатно, вы можете писать более общий код, который снабженный сущностью (неизвестно, без переключения типов или приведения), позволяет вам получить доступ к идентификатору.
  • Hibernate также имеет множество функций для работы с другими характеристиками модели, которые могут вам понадобиться (сейчас или позже, добавляйте их только по мере необходимости) . Воспринимайте это как качество расширяемости для вашего дизайна.

    • Вы можете заменить наследование (создание подклассов) композицией (несколько сущностей имеют один и тот же член, который содержит несколько связанных полей, которые могут потребоваться в нескольких сущностях ).
    • Между несколькими вашими объектами может быть наследование. Часто бывает, что у вас есть две таблицы с примерно одинаковой структурой (но вы не хотите хранить все данные в одной таблице, потому что вы потеряете ссылочную целостность для другой родительской таблицы).
  • При повторном использовании между вашими сущностей (но только соответствующее наследование и композиция ), обычно появляются некоторые дополнительные преимущества. Примеры:

    • часто есть способ прочитать данные объектов, которые похожи, но разные. Предположим, я прочитал поле «заголовок» для трех сущностей, но для некоторых я заменяю результат другим значением по умолчанию, если оно равно нулю. Легко иметь подпись "getActualTitle" (в суперклассе или интерфейсе) и реализовывать обработку значений по умолчанию в трех реализациях. Это означает, что код из моих сущностей просто имеет дело с концепцией «фактического заголовка» (я сделал эту функциональную концепцию явной), а наследование метода заботится о выполнении правильного кода (больше никаких переключателей или, если, без дублирования кода) .
    • ...
  • Со временем требования меняются. Будет момент, когда у вашей структуры базы данных возникнут проблемы. При использовании только JDBC любое изменение в базе данных должно повлиять на код (т. Е. Двойная стоимость). С Hibernate многие изменения можно поглотить, изменив только отображение, но не код. То же самое происходит и наоборот: Hibernate позволяет изменять код (например, между версиями) без изменения базы данных (изменения сопоставления, хотя этого не всегда достаточно). Подводя итог, Hibernate позволяет независимо развивать вашу базу данных и код .

12
ответ дан 24 November 2019 в 14:01
поделиться

... Сеанс в памяти ... LazyInitializationException ...

Вы можете посмотреть Ebean ORM , который не использует объекты сеанса ... и где просто работает ленивая загрузка. Безусловно, вариант, не лишний, и его будет проще понять.

0
ответ дан 24 November 2019 в 14:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: