Estrazione dei metadati del database mediante JDBC

1. Panoramica

JDBC fornisce un'API Java per leggere i dati effettivi memorizzati nelle tabelle del database. Oltre a questo, la stessa API può essere utilizzata anche per leggere i metadati sul database. Per metadati si intendono i dati sui dati come nomi di tabelle, nomi di colonne e tipi di colonne.

In questo tutorial impareremo come estrarre diversi tipi di metadati utilizzando l' interfaccia DatabaseMetaData .

2. Interfaccia DatabaseMetaData

DatabaseMetaData è un'interfaccia che fornisce una varietà di metodi per ottenere informazioni complete sul database. Queste informazioni sono utili per creare strumenti di database che consentono agli utenti di esplorare la struttura di diversi database. È anche utile quando vogliamo verificare se il database sottostante supporta alcune funzionalità o meno.

Avremo bisogno di un'istanza di DatabaseMetaData per ottenere queste informazioni. Quindi, vediamo nel codice come possiamo ottenerlo da un oggetto Connection :

DatabaseMetaData databaseMetaData = connection.getMetaData();

Qui, la connessione è un'istanza di JdbcConnection . Pertanto, il metodo getMetaData () restituisce un oggetto di JdbcDatabaseMetaData , che implementa l' interfaccia DatabaseMetaData .

Nelle prossime sezioni, useremo questo oggetto per recuperare diversi tipi di metadati. Successivamente, impareremo anche come verificare se il database supporta una particolare funzionalità.

3. Metadati delle tabelle

A volte, vogliamo conoscere i nomi di tutte le tabelle, tabelle di sistema o viste definite dall'utente. Inoltre, potremmo voler conoscere alcuni commenti esplicativi sulle tabelle. Tutto ciò può essere fatto utilizzando il metodo getTables () dell'oggetto DatabaseMetaData .

Per prima cosa, vediamo come possiamo estrarre i nomi di tutte le tabelle definite dall'utente esistenti:

ResultSet resultSet = databaseMetaData.getTables(null, null, null, new String[]{"TABLE"}); while(resultSet.next()) { String tableName = resultSet.getString("TABLE_NAME"); String remarks = resultSet.getString("REMARKS"); }

Qui, i primi due parametri sono catalog e schema . Il terzo parametro accetta un modello di nomi di tabella. Ad esempio, se forniamo "CUST%", verranno incluse tutte le tabelle il cui nome inizia con "CUST". L'ultimo parametro accetta un array String contenente i tipi di tabelle. Usa TABELLA per le tabelle definite dall'utente.

Successivamente, se vogliamo cercare tabelle definite dal sistema, tutto ciò che dobbiamo fare è sostituire il tipo di tabella con " SYSTEM TABLE ":

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

Infine, per scoprire tutte le visualizzazioni esistenti, dovremmo semplicemente cambiare il tipo in " VIEW ".

4. Metadati delle colonne

Possiamo anche estrarre le colonne di una particolare tabella utilizzando lo stesso oggetto DatabaseMetaData . Vediamolo in azione:

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

Qui, la chiamata getColumns () restituisce un ResultSet che possiamo iterare per trovare la descrizione di ogni colonna. Ogni descrizione contiene molte colonne utili come COLUMN_NAME , COLUMN_SIZE e DATA_TYPE .

Oltre alle colonne normali, possiamo anche trovare le colonne della chiave primaria di una particolare tabella:

ResultSet primaryKeys = databaseMetaData.getPrimaryKeys(null, null, "CUSTOMER_ADDRESS"); while(primaryKeys.next()){ String primaryKeyColumnName = primaryKeys.getString("COLUMN_NAME"); String primaryKeyName = primaryKeys.getString("PK_NAME"); }

Allo stesso modo, possiamo recuperare la descrizione delle colonne della chiave esterna insieme alle colonne della chiave primaria a cui fa riferimento la tabella data. Vediamo un esempio:

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

Qui, la tabella CUSTOMER_ADDRESS ha una colonna chiave esterna CUST_ID che fa riferimento alla colonna ID della tabella CUSTOMER . Lo snippet di codice precedente produrrà "CUSTOMER" come tabella principale e "CUSTOMER_ADDRESS" come tabella esterna.

Nella sezione successiva, vedremo come recuperare le informazioni sul nome utente e sui nomi di schema disponibili.

5. Nome utente e metadati degli schemi

Possiamo anche ottenere il nome dell'utente le cui credenziali sono state utilizzate durante il recupero della connessione al database:

String userName = databaseMetaData.getUserName();

Allo stesso modo, possiamo utilizzare il metodo getSchemas () per recuperare i nomi degli schemi disponibili nel database:

ResultSet schemas = databaseMetaData.getSchemas(); while (schemas.next()){ String table_schem = schemas.getString("TABLE_SCHEM"); String table_catalog = schemas.getString("TABLE_CATALOG"); }

Nella prossima sezione vedremo come recuperare altre informazioni utili sul database.

6. Metadati a livello di database

Vediamo ora come è possibile ottenere le informazioni a livello di database utilizzando lo stesso oggetto DatabaseMetaData .

Ad esempio, possiamo recuperare il nome e la versione del prodotto database, il nome del driver JDBC, il numero di versione del driver JDBC e così via. Diamo ora un'occhiata allo snippet di codice:

String productName = databaseMetaData.getDatabaseProductName(); String productVersion = databaseMetaData.getDatabaseProductVersion(); String driverName = databaseMetaData.getDriverName(); String driverVersion = databaseMetaData.getDriverVersion();

La conoscenza di queste informazioni a volte può essere utile, soprattutto quando un'applicazione è in esecuzione su più prodotti e versioni di database. Ad esempio, una determinata versione o prodotto potrebbe non disporre di una particolare funzionalità o contenere un bug in cui l'applicazione deve implementare una sorta di soluzione alternativa.

Successivamente, vedremo come possiamo sapere se il database manca o supporta una particolare funzionalità.

7. Metadati delle funzionalità database supportate

Database diversi supportano funzionalità diverse. Ad esempio, H2 non supporta i full outer join, mentre MySQL lo fa.

Quindi, come possiamo scoprire se il database che stiamo utilizzando supporta una certa funzionalità oppure no? Vediamo alcuni esempi:

boolean supportsFullOuterJoins = databaseMetaData.supportsFullOuterJoins(); boolean supportsStoredProcedures = databaseMetaData.supportsStoredProcedures(); boolean supportsTransactions = databaseMetaData.supportsTransactions(); boolean supportsBatchUpdates = databaseMetaData.supportsBatchUpdates();

Inoltre, l'elenco completo delle funzionalità che possono essere interrogate è disponibile nella documentazione ufficiale di Java.

8. Conclusione

In questo articolo abbiamo appreso come utilizzare l' interfaccia DatabaseMetaData per recuperare i metadati e le funzionalità supportate di un database.

Il codice sorgente completo per il progetto, inclusi tutti gli esempi di codice usati qui, può essere trovato su GitHub.