1. 概要

JDBC は、データベーステーブルに格納されている実際のデータを読み取るためのJavaAPIを提供します。 これに加えて、同じAPIを使用してデータベースに関するメタデータを読み取ることもできます。 メタデータとは、テーブル名、列名、列タイプなどのデータに関するデータを意味します。

このチュートリアルでは、DatabaseMetaDataインターフェイスを使用してさまざまなタイプのメタデータを抽出する方法を学習します。

2. DatabaseMetaDataインターフェース

DatabaseMetaData は、データベースに関する包括的な情報を取得するためのさまざまなメソッドを提供するインターフェースです。 この情報は、ユーザーがさまざまなデータベースの構造を探索できるデータベースツールを作成するのに役立ちます。基盤となるデータベースが一部の機能をサポートしているかどうかを確認する場合にも役立ちます。

この情報を取得するには、DatabaseMetaDataのインスタンスが必要です。 それでは、Connectionオブジェクトからこれを取得する方法をコードで見てみましょう。

DatabaseMetaData databaseMetaData = connection.getMetaData();

ここで、connectionJdbcConnectionのインスタンスです。 したがって、 getMetaData()メソッドは、DatabaseMetaDataインターフェイスを実装するJdbcDatabaseMetaDataのオブジェクトを返します。

次のいくつかのセクションでは、このオブジェクトを使用してさまざまなタイプのメタデータをフェッチします。 その後、データベースが特定の機能をサポートしているかどうかを確認する方法についても学習します。

3. テーブルのメタデータ

すべてのユーザー定義テーブル、システムテーブル、またはビューの名前を知りたい場合があります。 また、表に関する説明的なコメントを知りたい場合があります。 これはすべて、 DatabaseMetaDataオブジェクトのgetTables()メソッドを使用して実行できます。

まず、既存のすべてのユーザー定義テーブルの名前を抽出する方法を見てみましょう。

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"); 
  }
}

ここで、最初の2つのパラメーターはカタログスキーマです。 3番目のパラメーターは、テーブル名のパターンを取ります。 たとえば、「CUST%」を指定すると、名前が「CUST」で始まるすべてのテーブルが含まれます。 最後のパラメーターは、テーブルのタイプを含むString配列を取ります。 ユーザー定義テーブルにTABLEを使用します。

次に、システム定義のテーブルを検索する場合は、テーブルタイプを「SYSTEMTABLE」に置き換えるだけです。

try(ResultSet resultSet = databaseMetaData.getTables(null, null, null, new String[]{"SYSTEM TABLE"})){
 while(resultSet.next()) { 
    String systemTableName = resultSet.getString("TABLE_NAME"); 
 }
}

最後に、既存のすべてのビューを見つけるには、タイプを「VIEW」に変更するだけです。

4. 列のメタデータ

同じDatabaseMetaDataobjectを使用して特定のテーブルの列を抽出することもできます。これを実際に見てみましょう。

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 テーブルには、CUSTOMERテーブルのID列を参照する外部キー列CUST_IDがあります。 上記のコードスニペットは、プライマリテーブルとして「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にあります。