Где JDBC-совместимое приложение должно хранить свои операторы SQL и почему?
Пока мне удалось выделить эти варианты:
- Жестко закодированы в бизнес-объектах
- Встроено в предложения SQLJ
- Инкапсулировать в отдельные классы, например, объекты доступа к данным
- Управляемые метаданными (отделите схему объекта от схемы данных - опишите сопоставления между ними в метаданных)
- Внешние файлы (например, файлы свойств или ресурсов)
- Хранимые процедуры
Каковы «плюсы» и «против» каждого из них?
Следует ли считать код SQL «кодом» или «метаданными»?
Следует ли использовать хранимые процедуры только для оптимизации производительности или они являются законной абстракцией структуры базы данных?
Является ли производительность ключевым фактором при принятии решения? А как насчет привязки к поставщику ?
Что лучше - слабая связь или тугая и почему?
РЕДАКТИРОВАТЬ: Спасибо всем за ответы - вот резюме:
Управляемые метаданными, то есть объектно-реляционные сопоставления (ORM)
Плюсы:
- Очень абстрактно - сервер БД можно переключить без изменения модели
- Широкое распространение - практически стандарт
- Сокращает количество необходимого SQL
- Может хранить SQL в файлах ресурсов
- Производительность (обычно) приемлемая
- Подход, основанный на метаданных
- (База данных) независимость от поставщика
Минусы:
- Скрывает SQL и истинные намерения разработчиков
- SQL сложно проверить / изменить администратором баз данных
- SQL может все еще понадобиться в нечетных случаях
- Может принудительно использовать собственный язык запросов, например HQL
- Не поддается оптимизации (абстракция)
- Может не хватать ссылочной целостности
- Заменители из-за незнания SQL или недостаточной заботы о коде в БД
- Никогда не соответствовать производительности собственной базы данных (даже если она близка)
- Код модели очень тесно связан с моделью базы данных
Жестко закодированы / инкапсулированы в слое DAO
Плюсы:
- SQL хранится в объектах, которые обращаются к данным (инкапсуляция)
- SQL легко писать (скорость разработки)
- SQL легко отследить, когда требуются изменения
- Простое решение (без запутанной архитектуры)
Минусы:
- SQL не может быть просмотрен / изменен администратором баз данных
- SQL, скорее всего, станет специфичным для БД
- SQL может стать трудно поддерживать
Хранимые процедуры
Плюсы:
- SQL хранится в базе данных (близко к данным)
- SQL анализируется, компилируется и оптимизируется СУБД
- SQL легко проверить / изменить
- Снижает сетевой трафик
- Повышенная безопасность
Минусы:
- SQL привязан к базе данных (привязка к поставщику)
- Код SQL сложнее поддерживать
Внешние файлы (например, файлы свойств или ресурсов)
Плюсы
- SQL можно изменить без необходимости перекомпоновки приложения
- Отделяет логику SQL от бизнес-логики приложения
- Центральный репозиторий всех операторов SQL - проще в обслуживании
- Легче понять
Минусы:
- Код SQL может стать не обслуживаемым
- Сложнее проверить код SQL на наличие (синтаксических) ошибок
Встроено в предложения SQLJ
Плюсы:
- Лучшая проверка синтаксиса
Минусы:
- Слишком тесно связан с Java
- Производительность ниже, чем у JDBC
- Отсутствие динамических запросов
- Не так популярно
Ответы:
Обычно, чем больше приложение растет с точки зрения размера и / или возможности повторного использования, тем больше возникает потребность во внешнем / абстракционном выражении операторов SQL.
Жесткое программирование (как статические конечные константы) - это первый шаг. Следующий шаг - сохранение в файле (properties / xml file). Управление метаданными (как это делает ORM, например Hibernate / JPA) - это последний шаг.
Жесткий код имеет недостаток, заключающийся в том, что ваш код, вероятно, станет специфичным для БД, и вам нужно переписывать / перестраивать / распространять при каждом изменении. Преимущество в том, что он у вас в одном месте.
Сохранение в файле имеет тот недостаток, что он может стать недоступным для обслуживания по мере роста приложения. Преимущество в том, что вам не нужно переписывать / перестраивать приложение, если вам не нужно добавлять дополнительный метод DAO.
У управляемой метаданными есть недостаток, заключающийся в том, что код вашей модели очень тесно связан с моделью базы данных. Для каждого изменения в модели базы данных вам необходимо переписывать / перестраивать / распространять код. Преимущество состоит в том, что он очень абстрактный и вы можете легко переключиться с сервера БД без необходимости менять свою модель (но спросите себя сейчас: как часто компания будет переключаться с сервера БД? Вероятно, не реже одного раза в 3 года, не так ли? разве это?).
Я не буду называть хранимые процедуры "хорошим" решением этой проблемы. У них совсем другое предназначение. Хотя ваш код будет зависеть от используемой БД / конфигурации.
источник
Я не знаю, оптимально ли это, но, по моему опыту, они в конечном итоге жестко закодированы (т.е. строковые литералы) на уровне DAO.
источник
Я не думаю, что кто-то даст вам подробные сведения за / против, поскольку это довольно большой вопрос. Итак, вот то, что я использовал в прошлом, и то, что я буду использовать в будущем.
Я использую SQL, жестко закодированный в DAL. Я думал, что это нормально, пока администраторы баз данных не захотели поиграть с SQL. Затем вам нужно откопать его, отформатировать и передать администраторам баз данных. Кто над этим посмеется и все заменит. Но без красивых вопросительных знаков или вопросительных знаков в неправильном порядке, и вам придется снова вставить это в код Java.
Мы также использовали ORM, и хотя это здорово для разработчиков, наши администраторы баз данных ненавидели его, так как для них нет SQL, над которым можно было бы посмеяться. Мы также использовали странный ORM (заказной от стороннего поставщика), который имел привычку убивать базу данных. С тех пор я использовал JPA, и это было здорово, но получить что-либо сложное с его использованием после DBA - это битва в гору.
Теперь мы используем хранимые процедуры (с жестко запрограммированным оператором вызова). Теперь первое, на что все будут жаловаться, это то, что вы привязаны к базе данных. Ты. Однако как часто вы меняли базу данных? Я точно знаю, что мы просто не могли даже попробовать это, количество другого кода, зависящее от этого, плюс переподготовка наших администраторов баз данных плюс перенос данных. Это была бы очень дорогая операция. Однако, если в вашем мире требуется срочное изменение баз данных, SP, скорее всего, отсутствуют.
В будущем я хотел бы использовать хранимые процедуры с инструментами генерации кода для создания классов Java из пакетов Oracle.
Изменить 2013-01-31 : несколько лет спустя и администраторы баз данных, и теперь мы используем Hibernate, переходя на SQL (сохраненные процессы в БД) только в случае крайней необходимости. Думаю, это лучшее решение. В 99% случаев базам данных не нужно беспокоиться о SQL, а в 1% случаев они делают это в том месте, где им уже комфортно.
источник
Надеемся, что при использовании ORM (например, спящего режима) вам не о чем будет беспокоиться о операторах SQL. Производительность обычно приемлемая, и вы также получаете независимость от поставщика.
источник
Код.
Хранимые процедуры допускают повторное использование, в том числе внутри других хранимых процедур. Это означает, что вы можете совершить одно обращение к базе данных и заставить ее выполнять вспомогательные инструкции - в идеале наименьший объем трафика. ORM или sproc, время на проводе, идущем к db & back, - это то, что вы не можете окупить.
ORM не поддается оптимизации из-за своей абстракции. IME, ORM также означает отсутствие ссылочной целостности, что затрудняет создание отчетов по базе данных. То, что было сохранено в сложности, теперь увеличилось, чтобы можно было получать данные в работоспособном виде.
Нет, простота есть. Блокировка поставщика также происходит с базой данных - SQL относительно стандартизирован, но все еще существуют способы, специфичные для поставщика.
источник
Страх перед привязкой к поставщику в мире Java интересен.
Я надеюсь, что вы не заплатили 50000 долларов за ЦП за Oracle Enterprise, а затем использовали только наименьший общий знаменатель, чтобы в любую минуту переключиться на Mysql. Любой хороший администратор баз данных скажет вам, что между разными широко известными базами данных есть тонкие различия, особенно в отношении моделей блокировки и того, как они обеспечивают согласованность.
Итак, не принимайте решение о том, как реализовать ваши SQL-вызовы, только на основе принципа независимого от поставщика SQL - имейте для этого реальную (деловую) причину.
источник
SQL внутри хранимых процедур оптимизируется системой баз данных и компилируется для обеспечения скорости - это его естественный дом. SQL понимается системой баз данных, анализируется системой баз данных. По возможности сохраните свой SQL в базе данных; оберните его в хранимые процедуры или функции или любые единицы логики, которые предоставляет система баз данных, и сделайте простые вызовы, используя любой из инструментов, упомянутых вами или кем-либо еще.
Зачем хранить код SQL для системы баз данных вне базы данных? Часто для скорости разработки. Зачем использовать ORM-отображение? - Некоторые говорят, что отображение ORM обеспечивает совместимость с различными системами баз данных; однако редко в реальном мире приложение когда-либо отходит от платформы базы данных после того, как оно было построено, особенно когда оно начинает использовать расширенные функции, такие как репликация, и в редких случаях бывает, что система базы данных заменяется, некоторая работа оправдана . Я считаю, что одним из недостатков ORM он часто заменяет недостаток знаний SQL или недостаточное внимание к кодированию в базе данных. Кроме того, ORM никогда не будет соответствовать производительности собственной базы данных, даже если она близка.
Я стою на стороне сохранения кода SQL в базе данных и выполнения простых обращений к нему через любой API или интерфейс, который вы хотите использовать. Также абстрагируйтесь от точки, в которой выполняются вызовы вашей базы данных, помещая эти вызовы за абстрактный класс или объектно-ориентированный интерфейс (выраженный методами), поэтому, если вы когда-нибудь сделаете обмен в новом виде источника данных, он будет бесшовным для бизнес-уровня .
источник
Единственный вопрос, на который вы задаете однозначный ответ, - это «Код SQL или метаданные?» Это определенно код, и поэтому он должен храниться в каком-то элементе управления исходным кодом и иметь систему для простого обновления до последней версии и отката, когда нет , если что - то пойдет не так.
Я видел три способа выполнения SQL в приложении, и у каждого из них есть свои плюсы и минусы. Нет лучшего способа, но лучше всего просто выбрать тот, который хорошо работает с вашим приложением, и придерживаться его.
источник
Нам довелось использовать преобразователь SQL iBatis, который ближе к металлу, чем ORM, например Hibernate. В iBatis вы помещаете операторы SQL в файлы ресурсов (XML), которые должны находиться в пути к классам.
Ваш список подходов кажется довольно полным, если вы добавите опцию ORM @ ocdecio. Я бы сказал, что использование ORM и использование сопоставителя SQL и файлов ресурсов - два лучших подхода. Я бы держался подальше от SQLJ, который не получил большого распространения и слишком тесно связывает вас с Java. Также держитесь подальше от хранимых процедур, поскольку они привязывают вас к конкретному поставщику базы данных (стандарты для хранимых процедур практически отсутствуют).
источник
Как и большинство из нас, я видел весь спектр, но нам нужно рассматривать SQL как первоклассный язык. Я даже видел, как SQL хранится в БД, который удаляется, а затем выполняется обратно.
Самые успешные системы, которые я видел, используют хранимые процедуры, функции и представления.
Сохраненные процедуры сохраняют текст SQL обратно в БД и позволяют относительно немедленное изменение с помощью РАЗВЕРТЫВАНИЯ и НАСТРОЙКИ (что требует большого количества правильного дизайна для его поддержки).
Все прогнозы должны быть через представления и простые выборки по тем же причинам, вся логика проектирования должна содержаться в представлении.
источник
Я предлагаю использовать DAO с заводской компоновкой. Итак, вам понадобятся следующие примеры объектов:
Этот стиль включает в себя взаимодействие данных, поэтому вам нужно будет изменить только один уровень кода, если вы переключаете базы данных или переходите на технологии ORM.
источник
Между этими тремя нет существенной разницы:
Я предполагаю, что вы собираетесь встроить код SQL в строковой форме непосредственно в свой код Java. Хотя 1 и 3, вероятно, будут использовать JDBC напрямую (или какой-либо инструмент, например Apache DbUtils ), 2 добавляет технологию препроцессора в стек, генерируя соответствующий код JDBC перед компиляцией.
Итак, по сути, если эти решения включают в себя встраивание SQL, вы также можете использовать любую из этих технологий:
Также могут быть другие инструменты, которые помогут вам встраивать SQL в Java более безопасным способом, чем через SQLJ или посредством фактической конкатенации строк.
источник
Судя по моему опыту, жесткое кодирование операторов sql в объектах DAO широко используется, хотя я считаю, что это наименее предпочтительный метод. Лучше всего хранить инструкции sql в файле свойств. И получите операторы в объекте DAO через интерфейс к файлам свойств, скажем java.util.Properties . Операторы sql могут перемежаться знаками '?' Для передачи параметров в рамках подхода с использованием подготовленных операторов .
Такой подход помогает отделить логику sql от бизнес-логики приложения. Это делает доступным центральный репозиторий всех операторов sql, что упрощает модификацию, устраняя необходимость поиска операторов базы данных в логике приложения. Также улучшается понятность.
источник
Мои попадают в пакеты ресурсов. Я знаю, что это ненормально, но мне и всем "кроме меня" легче всего поддерживать его. Все просто и логично.
Мне вообще любопытно посмотреть, использует ли кто-нибудь мой подход.
источник
Поскольку rexem написал, что SQL-состояния являются кодом - они должны рассматриваться как код, а не извлекаться извне (если у вас нет веской причины), а помещаться в код, который обрабатывает данные SQL из / в эти операторы. Сегодняшние фреймворки ORM / iBatis предлагают множество упрощений для повседневной разработки JDBC.
Некоторые ответы на ваш вопрос вы найдете в этом вопросе :) Проблема того, как будут храниться ваши SQL-данные, зависит от вашего приложения. Что вам нужно? Высокая безопасность, простота написания кода или обслуживания, кроссплатформенность или привязка к поставщику? Следующий вопрос: нужен ли вам чистый SQL или ORM-фреймворк?
Самое простое решение (P), сложное в обслуживании (C)
Лучшая проверка синтаксиса (P), отсутствие динамических запросов (C), более низкая производительность, чем JDBC (C), не такая популярная (C)
Это должен быть конкретный случай, когда вы должны это сделать (C) или, если вы имеете в виду ORM (P);)
Легко обслуживать (P), но сложнее проверить на наличие ошибок (C)
Высокая безопасность (P), код, который трудно решить, проблемы привязки к поставщику (C)
источник