Программирование на Java. Где должны храниться SQL-запросы?

Где должно поддерживаться JDBC-приложение для хранения SQL-запросов и почему?

До сих пор мне удалось определить эти параметры:

  • Жесткий код в бизнес-объектах
  • Вложенные в SQLJ статьи
  • Инкапсулировать в отдельных классах, например. Объекты доступа к данным
  • Управляемые метаданные (отделить объект схема из схемы данных - описывают отображения между ними в метаданные)
  • Внешние файлы (например, Свойства или Файлы ресурсов)
  • Сохраненные процедуры

Каковы "плюсы" и "минусы" для каждого из них?

Должен ли SQL-код рассматриваться как "код" или "метаданные"?

Должны ли хранимые процедуры использоваться только для оптимизации производительности или они являются законной абстракцией структуры базы данных?

Является ли производительность ключевым фактором решения? Как насчет блокировка поставщика?

Что лучше - свободная муфта или плотная муфта и почему?

EDITED: Спасибо всем за ответы - вот резюме:

Работа с метаданными, то есть объектные реляционные сопоставления (ORM)

Плюсы:

  • Очень абстрактно - сервер БД может быть переключается без необходимости изменения модель
  • Широко распространенный - практически стандартный
  • Сокращает объем необходимых SQL
  • Может хранить SQL в файлах ресурсов
  • Производительность (обычно) приемлема
  • Подход, основанный на метаданных
  • (База данных) Независимость поставщика

Минусы:

  • Скрывает SQL и настоящих разработчиков Намерения
  • SQL трудно пересмотреть/изменить от DBA
  • SQL может потребоваться для нечетного случаи
  • Может принудительно использовать запатентованный язык запросов, например. HQL
  • Не поддается оптимизации (Абстракция)
  • Не хватает ссылочной целостности
  • Замены из-за отсутствия знаний SQL или отсутствие заботы о кодировании в БД
  • Никогда не сопоставлять собственную базу данных производительность (даже если она приближается)
  • Код модели очень плотно связан с модель базы данных

Жестко закодированный/инкапсулированный в слое DAO

Плюсы:

  • SQL хранится в объектах, которые данные доступа (инкапсуляция)
  • SQL легко писать (скорость развитие)
  • SQL легко отслеживать, когда необходимы изменения
  • Простое решение (без проблем) архитектура)

Минусы:

  • SQL не может быть просмотрен/изменен администратором базы данных
  • SQL, скорее всего, станет специфичным для БД
  • SQL может стать трудно поддерживать

Сохраненные процедуры

Плюсы:

  • SQL хранится в базе данных (рядом с данные)
  • SQL анализируется, компилируется и оптимизируется по СУБД
  • SQL для администратора баз данных легко просматривать/изменять
  • Снижает сетевой трафик.
  • Повышенная безопасность

Минусы:

  • SQL привязан к базе данных (поставщик блокировка в)
  • SQL-код сложнее поддерживать

Внешние файлы (например, Свойства или файлы ресурсов)

Доводы

  • SQL может быть изменен без необходимости перестроить приложение.
  • Отделяет логику SQL от бизнес-логика приложений
  • Центральный репозиторий всех SQL заявления - легче поддерживать
  • Легче понять

Минусы:

  • Код SQL может стать не поддерживаемым
  • Сложнее проверить код SQL для (синтаксис).

Вложенные в предложения SQLJ

Плюсы:

  • Лучшая проверка синтаксиса

Минусы:

  • Слишком близко к Java
  • Более низкая производительность, чем JDBC
  • Отсутствие динамических запросов
  • Не так популярны

Ответ 1

Как правило, чем больше приложение растет с точки зрения размера и/или многократного использования, тем больше необходимость в экстернализации/абстракции операторов SQL.

Hardcoded (как статические конечные константы) - это первый шаг. Сохраненный в файле (свойства/xml файл) является следующим шагом. Метаданные, управляемые (как это делает ORM, например Hibernate/JPA), являются последним шагом.

Hardcoded имеет тот недостаток, что ваш код, скорее всего, станет специфичным для БД, и что вам нужно переписать/перестроить/перераспределить при каждом изменении. Преимущество в том, что у вас есть это в 1 месте.

Сохранение в файле имеет тот недостаток, что он может стать недостижимым, когда приложение растет. Преимущество в том, что вам не нужно переписывать/перестраивать приложение, если вам не нужно добавлять дополнительный метод DAO.

Приведенные метаданные имеют тот недостаток, что ваш код модели очень плотно связан с моделью базы данных. Для каждого изменения в модели базы данных вам необходимо переписать/перестроить/перераспределить код. Преимущество в том, что оно очень абстрактно и что вы можете легко переключаться с сервера БД без необходимости менять свою модель (но спросите себя: как часто компания переключается с сервера БД? Вероятно, по крайней мере, один раз в 3 года, t it?).

Я не буду называть хранимые процедуры "хорошим" решением для этого. У них совершенно другая цель. Несмотря на то, что ваш код будет зависеть от используемой DB/конфигурации.

Ответ 2

Я не знаю, оптимально ли это, но по моему опыту они заканчиваются жестко закодированными (т.е. строковыми литералами) на уровне DAO.

Ответ 3

Используя ORM (например, спящий режим), вы, надеюсь, не будете иметь операторов SQL, о которых можно беспокоиться. Производительность обычно приемлема, и вы также получаете независимость поставщика.

Ответ 4

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

Я использую SQL, жестко закодированный в DAL. Я думал, что это нормально, пока администраторы баз данных не захотят играть с SQL. Затем вам нужно выкопать его, отформатировать и передать его администратору баз данных. Кто будет смеяться над ним и заменить все это. Но без хороших вопросительных знаков или вопросительных знаков в неправильном порядке, и оставляйте вас вставлять его обратно в код Java.

Мы также использовали ORM, и в то время как это отлично подходит для разработчиков, наши администраторы баз данных ненавидели его, поскольку для них не существует смеха над SQL. Мы также использовали нечетный ORM (пользовательский от стороннего поставщика), который имел привычку убивать базу данных. Я использовал JPA с тех пор и был отличным, но с помощью чего-то сложного, использующего его в прошлом, администраторы баз данных - это битва на вершине холма.

Теперь мы используем хранимые процедуры (с жестким кодом оператора вызова). Теперь первое, на что все будут жаловаться, это то, что вы привязаны к базе данных. Вы. Однако как часто вы меняли базу данных? Я знаю, что мы просто не могли даже попробовать, количество другого кода, зависящего от него, плюс переподготовка наших администраторов баз данных и перенос данных. Это была бы очень дорогостоящая операция. Однако если в вашем мире изменяются БД при падении шляпы, то SPs, скорее всего, отсутствуют.

В будущем я хотел бы использовать хранимые процедуры с инструментами генерации кода для создания классов Java из пакетов Oracle.

Редактировать 2013-01-31: несколько лет и администраторы баз данных позже, и теперь мы используем Hibernate, перейдя на SQL (хранимые procs в БД) только тогда, когда это абсолютно необходимо. Это я считаю лучшим решением. 99% случаев, когда БД не нужно беспокоиться о SQL, а 1% они делают это в удобном для них месте.

Ответ 5

Интересен страх перед блокировкой поставщика в java-мире.

Надеюсь, вы не заплатили $50000 pr CPU для Oracle Enterprise, а затем использовали только наименьший общий знаменатель, чтобы переключиться на Mysql в любую минуту. Как скажет вам любой хороший администратор базы данных, существуют тонкие различия между различными крупными базами имен, особенно в отношении моделей блокировки и того, как они достигают согласованности.

Таким образом, не принимайте решение о том, как реализовать ваши SQL-вызовы только на основе принципа агностического SQL-поставщика, для которых существует реальная (деловая) причина.

Ответ 6

Должен ли SQL-код рассматриваться как "код" или "метаданные"?

Код.

Должны ли хранимые процедуры использоваться только для оптимизации производительности или они являются законной абстракцией структуры базы данных?

Хранимые процедуры позволяют повторно использовать, в том числе внутри других хранимых процедур. Это означает, что вы можете совершить одну поездку в базу данных и выполнить инструкции поддержки - наименьшее количество трафика является идеальным. ORM или sproc, время на проводе, идущем к db и обратно, - это то, что вы не можете окупить.

ORM не поддается оптимизации из-за своей абстракции. IME, ORM также означает отсутствие референциальной целостности - затруднить отчет о базе данных. То, что было спасено по сложности, теперь увеличилось, чтобы получить данные в работоспособном виде.

Является ли производительность ключевым фактором решения? Как насчет блокировки поставщика?

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

Ответ 7

SQL внутри хранимых процедур оптимизируется системой базы данных и скомпилирован для скорости - это ее естественный дом. SQL понимается системой базы данных, анализируемой системой базы данных. Сохраните свой SQL в базе данных, если сможете; обернуть его в хранимые процедуры или функции или какие-либо блоки логики, предоставляемые системой базы данных, и сделать простые вызовы с помощью любого из инструментов, которые вы или кто-либо еще упоминали.

Зачем хранить код SQL для системы баз данных вне db? Часто для скорости развития. Зачем использовать сопоставление ORM? - Некоторые говорят, что сопоставление ORM обеспечивает совместимость в разных системах баз данных; однако редко в реальном мире приложение когда-либо смещается от платформы базы данных, когда оно было создано, особенно когда оно начинает использовать расширенные функции, такие как репликация, и в редких случаях случается, что система базы данных заменена, некоторая работа оправдана, Я считаю, что один из недостатков ORM он часто заменяет отсутствие знаний SQL или отсутствие помощи в кодировании в db. ORM никогда не будет соответствовать производительности собственной базы данных, даже если она приблизится.

Я стою на стороне хранения кода SQL в базе данных и делает простые обращения к нему через любой API или интерфейс, который вы хотите использовать. Также абстрагируйтесь от точки, в которой ваши вызовы в базе данных выполняются, помещая эти вызовы за абстрактный класс или интерфейс OO (выраженный методами), поэтому, если вы когда-либо выполняете обмен в новом виде источника данных, он будет беспрепятственным для бизнес-уровня.

Ответ 8

Единственный вопрос, который вы задаете, который имеет определенный ответ: "Является ли код SQL или метаданные?" Это, безусловно, код и как таковой должен храниться в каком-то виде управления исходным кодом и иметь систему для легкого обновления до последней версии и откат, когда нет, если что-то пойдет не так.

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

  • ORM - это сокращает объем SQL, который вам нужно написать, и обрабатывает множество деталей для вас. Вам нужно будет сделать некоторый пользовательский SQL. Убедитесь, что у вас есть ORM, который обрабатывает это изящно.
  • Объекты доступа к данным - держите SQL в объектах, которые обращаются к данным. Это инкапсулирует вашу базу данных и делает ее так, чтобы остальная часть вашего приложения не нуждалась в том, чтобы знать о базовой структуре БД, просто интерфейс к этим объектам.
  • Хранимые процедуры - это сохраняет все ваши SQL в вашей базе данных и упрощает для вашего администратора базы данных возможность узнать, что происходит. Все, что вам нужно сделать, это заставить ваш код вызвать хранимые процедуры

Ответ 9

Мы используем iBatis SQL mapper, который ближе к металу, чем ORM, такие как Hibernate. В iBatis вы помещаете операторы SQL в файлы ресурсов (XML), которые должны быть в пути к классам.

Ваш список подходов выглядит довольно всеобъемлющим, если вы добавляете опцию ORC @ocdecio. Я бы сказал, что использование ORM и использование карт-карт SQL и файлов ресурсов - два наилучших подхода. Я бы избавился от SQLJ, который не видел большого понимания и слишком тесно связан с Java. Также избегайте хранимых процедур, поскольку они привязывают вас к конкретному поставщику базы данных (для хранимых процедур практически не существует стандартов).

Ответ 10

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

Самые успешные системы, которые я видел, используют хранимые процедуры, функции и представления.

Сохраненные procs сохраняют текст SQL обратно в БД и позволяют относительно немедленное изменение этими DEPLOYING и CUSTOMIZING (для этого требуется много правильного дизайна).

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

Ответ 11

Я предлагаю использовать DAO с макетом factory. Таким образом, объекты примера, которые вам нужны, будут:

public class CoolBusinessObject
public class DAOFactory.java
public implementation CoolBusinessOjectDAO
public class CoolBusinessOjectDAOOracleImpl implements CoolBusinessOjectDAO

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

Ответ 12

На самом деле нет существенной разницы между этими тремя:

Я предполагаю, что вы собираетесь внедрить SQL-код в строковой форме прямо в ваш Java-код. Хотя 1 и 3, вероятно, будут использовать JDBC напрямую (или какой-то инструмент вроде Apache DbUtils), 2 добавляет в стек технологию препроцессора, генерируя соответствующий JDBC кода перед компиляцией.

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

  • JPA Criteria API, моделирующий JPQL как внутренний язык, специфичный для домена в Java
  • jOOQ, моделирование SQL как внутреннего языка, специфичного для домена, на Java

Также могут быть другие инструменты, которые помогут вам внедрить SQL в Java более типичным образом, чем через SQLJ или посредством фактического конкатенации строк.

Ответ 13

Из какого опыта у меня были, жесткие кодировки SQL-операторов в объектах DAO - это то, что широко используется, хотя, я думаю, это должен быть наименее предпочтительный метод. Лучшей практикой должно быть сохранение операторов sql в файле свойств. И получить инструкции в объекте DAO через интерфейс к файлам свойств, например java.util.Properties. Операторы sql могут перемежаться с помощью '? для передачи параметров через подход "Подготовленный отчет".

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

Ответ 14

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

Мне действительно интересно узнать, использует ли кто-нибудь мой подход.

Ответ 15

Как rexem написал SQL-статусы, это код - они должны рассматриваться как код, а не экстернализированы (у вас есть веская причина), но помещены с кодом, обрабатывающим данные SQL из/в эти утверждения. Сегодняшние рамки ORM/iBatis предлагают множество упрощений для повседневной разработки JDBC.

Некоторые ответы на ваш вопрос вы найдете в этом вопросе:) Проблема, связанная с сохранением ваших данных SQL, зависит от вашего приложения. Каковы ваши потребности? Высокая безопасность, простота написания кода или обслуживания, кроссплатформенность или блокировка поставщика? Следующий вопрос: нужен ли вам простой SQL или ORM-инфраструктура?

* Hardcoded in business objects
* Encapsulate in separate classes e.g. Data Access Objects

Простейшее решение (P), трудно поддерживаемое (C)

* Embedded in SQLJ clauses

Проверка синтаксиса Beter (P), отсутствие динамических запросов (C), более низкая производительность, чем JDBC (C), не так популярна (C)

* Metadata driven (decouple the object schema from the data schema - describe the mappings between them in metadata)

Это должен быть конкретный случай, когда вы должны это сделать (C), или если вы имеете в виду ORM (P);)

* External files (e.g. Properties or Resource files)

Прост в использовании (P), но сложнее проверить наличие ошибок (C)

* Stored Procedures

Высокий уровень безопасности (P), код трудно усмотреть проблемы блокировки поставщика (C)