Рубрики
Без рубрики

Как получить метаданные базы данных в виде Java POJOs

API Java Database Connectivity (JDBC) обеспечивает доступ к данным и метаданным из стандартных реляционных… С тегом database, java.

API Java Database Connectivity (JDBC) обеспечивает доступ к данным и метаданным из стандартных систем реляционных баз данных (СУБД). Однако существует внутреннее несоответствие между объектной моделью домена приложения и реляционной моделью базы данных. Различные классы операторов API JDBC, которые позволяют выполнять операторы SQL, отражают реляционную модель базы данных, а ее классы результирующего набора возвращают табличные данные. Кроме того, JDBC требует от программистов управления внешними ресурсами, такими как подключения к базе данных, и обработки исключений.

Поскольку API JDBC так близко имитирует реляционную модель, при его использовании программистами возникает “несоответствие импеданса” . Встроенные операторы SQL, блоки try-catch-finally и отображение из табличных наборов результатов в простые старые объекты Java (POJOs) – все это отражает это. Однако отличные фреймворки, такие как Hibernate, в значительной степени скрывают несоответствие импеданса от большинства прикладных программистов.

Иногда, однако, программистам необходимо получить доступ к метаданным базы данных, чтобы динамически генерировать инструкции SQL при программном определении возможностей данной СУБД или поиске имен и типов таблиц и столбцов в базе данных. Поскольку получение метаданных базы данных не очень распространено в приложениях, для их получения не существует хороших фреймворков или API, как и для получения самих данных.

Программисты могут получать метаданные базы данных с помощью JDBC, но с молотком raw JDBC API все выглядит как гвоздь — даже метаданные базы данных. Программисты по-прежнему отвечают за управление ресурсами, отображение в структуры объектов и обработку исключений. В следующем разделе более подробно объясняются недостатки JDBC для поиска метаданных базы данных.

Получение метаданных базы данных с помощью необработанного JDBC сопряжено с рядом проблем. Сначала вы получаете метаданные базы данных из JDBC с помощью статических вызовов, которые возвращают результирующие наборы с зашифрованными именами столбцов. Например, предположим, что вы хотите получить список таблиц из базы данных. Вам нужно будет вызвать java.sql.DatabaseMetaData.getTables(String, String, String, String[]) , который вернет результирующий набор со следующими столбцами:

  • TABLE_CAT
  • ТАБЛИЦА_СХЕМА
  • ИМЯ_ТАБЛИЦЫ
  • TABLE_TYPE ТИП ТАБЛИЦЫ
  • замечания
  • TYPE_CAT
  • ТИП_СХЕМА
  • ИМЯ_ТИПА
  • SELF_REFERENCING_COL_NAME
  • ПОВТОРНАЯ ГЕНЕРАЦИЯ

Вам пришлось бы прочитать Javadocs, найти, какой вызов возвращает нужную вам информацию, а затем выяснить, как интерпретировать возвращаемую информацию — довольно сложная задача. Вам также нужно будет убедиться, что вызов getTables не вернет никакой информации о столбцах, и определить, как интерпретировать столбцы данных: является ли TABLE_TYPE строкой, целым числом или чем-то еще? Что это значит, если значение равно null? Кроме того, вы будете обрабатывать исключения и управлять ресурсами, убедившись, что вы освободили ресурсы результирующего набора, когда закончили просмотр результатов, и при необходимости закрыли соединение.

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

Вы можете предположить, что как только вы привыкнете к программированию с помощью JDBC API, вы сможете очень быстро создавать код. Это было бы верно, если бы API был последовательным. Например, если вы хотите найти тип таблицы, вы должны посмотреть на TABLE_TYPE , который будет иметь строковое значение. Ваша следующая мысль будет заключаться в том, что вам следует посмотреть на PROCEDURE_TYPE , чтобы найти процедуры. Хорошая догадка, но то, что вы получаете обратно, – это целое число, а не строка. Далее, для типа столбца, вы должны искать COLUMN_TYPE , верно? Нет, потому что его не существует. Так что, возможно, вы могли бы использовать SQL_DATA_TYPE , но это поле, хотя и возвращается, не используется по причинам, известным только разработчикам API. Наконец, вы останавливаетесь на DATA_TYPE , который представляет собой целое число, которое необходимо интерпретировать.

В качестве другого примера предположим, что вы хотите найти все каталоги в базе данных. Итак, вы вызываете get Catalogs() , и он возвращает результирующий набор ровно с одним столбцом. Пока все идет хорошо. Теперь, если вам нужен список строковых функций в базе данных, у вас возникнет соблазн вызвать getStringFunctions() а затем обработать возвращенный результирующий набор, верно? Что ж, вы получаете обратно список функций, разделенных запятыми, в виде одной строки. Вот вам и последовательность. API JDBC обладает особенностями чего-то, над чем работали несколько человек.

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

  • Таблица – это объект, который содержит коллекцию объектов столбцов, не требуя от вас выполнения дополнительных вызовов.
  • Вы могли бы использовать такой метод, как GetType() , будь то для объекта столбца, объекта таблицы или объекта процедуры.
  • Типы таблиц – это перечисления, а не строки, которые оставляют вас в догадках.
  • Списки всегда java.util. Список .
  • У вас есть то же удобство, которое вы получаете с помощью инструментов объектно-реляционного сопоставления, где вы не беспокоитесь о ресурсах или обработке исключений.
  • Вы можете перемещаться с помощью стандартных методов Java от одного объекта столбца к содержащему его объекту таблицы или от одного объекта таблицы к другому с помощью внешнего ключа.

SchemaCrawler – это как раз такой API. Бесплатный API с открытым исходным кодом, доступный по лицензии LGPL, SchemaCrawler написан на Java, что делает его независимым от операционной системы. Поскольку он использует JDBC, он также не зависит от базы данных. В нем намеренно нет никакого специфичного для СУБД кода. Именно по этой причине вы не найдете в нем никаких триггеров; нет никакого способа получить метаданные триггера с помощью JDBC.

Взгляните на некоторые примеры кода, которые демонстрируют, насколько просто использовать SchemaCrawler. Этот код предполагает, что у вас есть javax.sql. Источник данных который способен передавать соединения с базой данных по требованию. Получение схемы базы данных – это вопрос одного единственного вызова:

final SchemaCrawlerOptions options = SchemaCrawlerOptionsBuilder.builder().toOptions();
final Catalog catalog = SchemaCrawlerUtility.getCatalog(getConnection(), options);

Все очень просто. Вы сами решаете, насколько подробной вы хотите, чтобы возвращаемая схема была — например, на базовом уровне информации о схеме вы получаете столбцы и таблицы, но не индексы. Уровень информации о схеме определяет, сколько времени занимает вызов GetSchema. Вы можете отфильтровать определенные таблицы и столбцы с помощью регулярных выражений, которые являются более мощными, чем регулярные выражения SQL, установив правильные параметры SchemaCrawlerOptions . Вы можете исключить таблицы определенных типов, таких как представления, из выходной схемы.

Как только у вас есть объект Catalog , вы можете выполнить итерацию по схеме и найти все таблицы и столбцы, используя стандартные идиомы Java:

for (final Schema schema : catalog.getSchemas())
{
  for (final Table table : catalog.getTables(schema))
  {
    System.out.print("o--> " + table);
    for (final Column column : table.getColumns())
    {
      System.out.println("     o--> " + column);
    }
  }
}

Если простого кода в предыдущем примере недостаточно для ваших нужд, API SchemaCrawler предоставляет несколько четко определенных точек расширения.

Теперь, со всем этим, идите экспериментировать!

Оригинал: “https://dev.to/sualeh/how-to-get-database-metadata-as-java-pojos-24li”