1. Обзор
JDBC предоставляет Java API для чтения фактических данных, хранящихся в таблицах базы данных. Кроме того, тот же API можно использовать для чтения метаданных о базе данных. Метаданные означают данные о данных, такие как имена таблиц, имена столбцов и типы столбцов.
В этом руководстве мы узнаем, как извлекать различные типы метаданных с помощью интерфейса DatabaseMetaData .
2. Интерфейс базы данных метаданных
DatabaseMetaData
— это интерфейс, который предоставляет множество методов для получения исчерпывающей информации о базе данных. Эта информация полезна для создания инструментов баз данных, которые позволяют пользователям исследовать структуру различных баз данных. Это также полезно, когда мы хотим проверить, поддерживает ли базовая база данных некоторые функции или нет.
Нам понадобится экземпляр DatabaseMetaData
, чтобы получить эту информацию. Итак, давайте посмотрим в коде, как мы можем получить это из объекта Connection :
DatabaseMetaData databaseMetaData = connection.getMetaData();
Здесь соединение
является экземпляром JdbcConnection
. Поэтому метод getMetaData()
возвращает объект JdbcDatabaseMetaData
, который реализует интерфейс DatabaseMetaData .
В следующих нескольких разделах мы будем использовать этот объект для получения различных типов метаданных. После этого мы также узнаем, как проверить, поддерживает ли база данных определенную функцию.
3. Метаданные таблиц
Иногда нам нужно знать имена всех пользовательских таблиц, системных таблиц или представлений. Кроме того, мы можем захотеть узнать некоторые пояснительные комментарии к таблицам. Все это можно сделать с помощью метода getTables() объекта
DatabaseMetaData
.
Во-первых, давайте посмотрим, как мы можем извлечь имена всех существующих пользовательских таблиц:
try(ResultSet resultSet = databaseMetaData.getTables(null, null, null, new String[]{"TABLE"})){
while(resultSet.next()) {
String tableName = resultSet.getString("TABLE_NAME");
String remarks = resultSet.getString("REMARKS");
}
}
Здесь первые два параметра — catalog
и schema
. Третий параметр принимает шаблон имен таблиц. Например, если мы укажем «CUST%», это будет включать все таблицы, имя которых начинается с «CUST». Последний параметр принимает массив строк
, содержащий типы таблиц. Используйте TABLE
для пользовательских таблиц.
Далее, если мы хотим искать системные таблицы, все, что нам нужно сделать, это заменить тип таблицы на « SYSTEM TABLE
»:
try(ResultSet resultSet = databaseMetaData.getTables(null, null, null, new String[]{"SYSTEM TABLE"})){
while(resultSet.next()) {
String systemTableName = resultSet.getString("TABLE_NAME");
}
}
Наконец, чтобы узнать все существующие представления, мы просто изменим тип на « ВИД
».
4. Метаданные столбцов
Мы также можем извлечь столбцы конкретной таблицы, используя тот же объект DatabaseMetaData
.
Давайте посмотрим на это в действии:
try(ResultSet columns = databaseMetaData.getColumns(null,null, "CUSTOMER_ADDRESS", null)){
while(columns.next()) {
String columnName = columns.getString("COLUMN_NAME");
String columnSize = columns.getString("COLUMN_SIZE");
String datatype = columns.getString("DATA_TYPE");
String isNullable = columns.getString("IS_NULLABLE");
String isAutoIncrement = columns.getString("IS_AUTOINCREMENT");
}
}
Здесь вызов getColumns()
возвращает ResultSet
, который мы можем повторить, чтобы найти описание каждого столбца. Каждое описание содержит много полезных столбцов, таких как COLUMN_NAME
, COLUMN_SIZE
и DATA_TYPE
.
Помимо обычных столбцов, мы также можем узнать столбцы первичного ключа конкретной таблицы:
try(ResultSet primaryKeys = databaseMetaData.getPrimaryKeys(null, null, "CUSTOMER_ADDRESS")){
while(primaryKeys.next()){
String primaryKeyColumnName = primaryKeys.getString("COLUMN_NAME");
String primaryKeyName = primaryKeys.getString("PK_NAME");
}
}
Точно так же мы можем получить описание столбцов внешнего ключа вместе со столбцами первичного ключа, на которые ссылается данная таблица. Давайте посмотрим пример:
try(ResultSet foreignKeys = databaseMetaData.getImportedKeys(null, null, "CUSTOMER_ADDRESS")){
while(foreignKeys.next()){
String pkTableName = foreignKeys.getString("PKTABLE_NAME");
String fkTableName = foreignKeys.getString("FKTABLE_NAME");
String pkColumnName = foreignKeys.getString("PKCOLUMN_NAME");
String fkColumnName = foreignKeys.getString("FKCOLUMN_NAME");
}
}
Здесь таблица CUSTOMER_ADDRESS
имеет столбец внешнего ключа CUST_ID
, который ссылается на столбец ID
таблицы CUSTOMER .
Приведенный выше фрагмент кода создаст «CUSTOMER» в качестве основной таблицы и «CUSTOMER_ADDRESS» в качестве внешней таблицы.
В следующем разделе мы увидим, как получить информацию об имени пользователя и доступных именах схем.
5. Метаданные имени пользователя и схемы
Мы также можем получить имя пользователя, чьи учетные данные использовались при получении подключения к базе данных:
String userName = databaseMetaData.getUserName();
Точно так же мы можем использовать метод getSchemas()
для получения имен доступных схем в базе данных:
try(ResultSet schemas = databaseMetaData.getSchemas()){
while (schemas.next()){
String table_schem = schemas.getString("TABLE_SCHEM");
String table_catalog = schemas.getString("TABLE_CATALOG");
}
}
В следующем разделе мы увидим, как получить другую полезную информацию о базе данных.
6. Метаданные уровня базы данных
Теперь давайте посмотрим, как можно получить информацию уровня базы данных, используя тот же объект DatabaseMetaData .
Например, мы можем получить имя и версию продукта базы данных, имя драйвера JDBC, номер версии драйвера JDBC и так далее. Давайте теперь посмотрим на фрагмент кода:
String productName = databaseMetaData.getDatabaseProductName();
String productVersion = databaseMetaData.getDatabaseProductVersion();
String driverName = databaseMetaData.getDriverName();
String driverVersion = databaseMetaData.getDriverVersion();
Знание этой информации иногда может быть полезно, особенно когда приложение работает с несколькими продуктами и версиями баз данных. Например, в определенной версии или продукте может отсутствовать определенная функция или содержать ошибку, из-за которой приложение должно реализовать какое-то обходное решение.
Далее мы увидим, как узнать, отсутствует ли в базе данных определенная функция или поддерживается ли она.
7. Метаданные поддерживаемых функций базы данных
Разные базы данных поддерживают разные функции. Например, H2 не поддерживает полные внешние соединения, в отличие от MySQL.
Итак, как мы можем узнать, поддерживает ли используемая нами база данных определенную функцию или нет? Давайте посмотрим несколько примеров:
boolean supportsFullOuterJoins = databaseMetaData.supportsFullOuterJoins();
boolean supportsStoredProcedures = databaseMetaData.supportsStoredProcedures();
boolean supportsTransactions = databaseMetaData.supportsTransactions();
boolean supportsBatchUpdates = databaseMetaData.supportsBatchUpdates();
Также полный список возможностей, которые можно запрашивать, можно найти в официальной документации по Java .
8. Заключение
В этой статье мы узнали, как использовать интерфейс DatabaseMetaData
для получения метаданных и поддерживаемых функций базы данных.
Полный исходный код проекта, включая все использованные здесь примеры кода, можно найти на GitHub .