Preparare la certificazione Java Programmer OCPJP7: le API JDBC per la gestione dei database

JDBC per la gestione dei database

  • I vari metodi getXXX() relativi ai vari tipi di dati possono accettare il nome della colonna del ResultSet di cui estrarre il valore e tale valore è CASE INSENSITIVE.
  • Si possono cancellare le modifiche effettuate con uno statement di update utilizzando il metodo cancelRowUpdates(). Esso però deve essere invocato prima del metodo updateRow().
  • Se si esegue una commit esplicita utilizzando connection.commit() quanto l’autocommit è abilitato, si ottiene una SQLException.
    • La stessa cosa avviene per il ROLLBACK ed i SAVEPOINT.
  • Il metodo getConnection nella classe DriveManager prende 3 parametri: URL, USERNAME e PASSWORD.
    • L’URL è nel formato: <protocol>:<subprotocol>://<server>:<port>/
    • Esempio: jdbc:mysql://localhost:3306/
  • Un’applicazione si può connettere ad un database in uno dei 2 seguenti modi:
    • java.sql.DriverManager
    • java.sql.DataSource
  • RowSet ha diverse sottoclassi:
    • JdbcRowSet
    • CachedRowSet
    • FilteredRowSet
    • WebRowSet
    • JoinRowSet
  • RowSet è scrollabile ed updatabile di default
  • Un JdbcRowSet può essere creato in diversi modi:
    • Tramite il costruttore di default: JdbcRowSet jdbsrs = new JdbcRowSetImpl();
    • Tramite il costruttore che prende come parametro la connessione: JdbcRowSet jdbcrs = new JdbcRowSet(conn);
    • Tramite un’istanza di RowSetFactory create dalla classe RowSetProvider: JdbcRowSet jdbcrs = RowSetProvider.newFactory().createJdbcRowSet();
  • Connection, Statement e ResultSet implementano tutti l’interfaccia AutoCloseable e quindi possono essere utilizzati in uno statement try-with-resources.
  • La classe ResultSet fornisce il metodo getInt() per recuperare un valore intero e NON getInteger().
  • I metodi get della classe ResultSet si riferiscono ad eventuali ALIAS quando sono presenti, invece che al nome del campo.
    • Se, ad esempio, eseguo la query: SELECT user_id, email AS _EMAIL
    • Per recuperare la colonna email devo utilizzare l’alias: rs.getString(“_EMAIL”);
  • Dopo la chiamata updateRow() ci deve essere la chiamata acceptChange() per far persistere le modifiche ad un RowSet.
  • Statement.executeUpdate(String) ritorna un intero che indica il numero di righe interessate dall’esecuzione di uno statement di INSERT, UPDATE o DELETE.
  • java.sql.SQLException è l’unica eccezione scatenata dalle API JDBC.
  • Il metodo releaseSavepoint(Savepoint) è un metodo dell’oggetto Connection e NON dell’oggetto Statement:
    • Connection.releaseSavepoint(Savepoint)
  • Gerarchia degli oggetti Statement:
    • Statement: per l’invio di statement senza parametri, tramite il metodo create Statement()
    • PreparedStatement: accetta parametri IN ed è più efficiente di Statement. Il metodo da utilizzare è preparedStatement()
    • CallableStatement: da utilizzare per l’esecuzione di stored procedure e può gestire parametri IN, OUT e INOUT. Il metodo da invocare in questo caso è prepareCall()
  • Esecuzione degli statement:
    • executeQuery -> SELECT -> ritorna un ResultSet
    • executeUpdate -> INSERT, UPDATE, DELETE -> ritorna il numero di righe interessate dallo statement
    • execute() -> generico -> Ritorna più ResultSet o più contatori oppure oggetti di entrambi i tipi insieme
  • Il ResultSet viene scorso tramite un cursore, invocando il metodo next() che ritorna un boolean.
  • Metodi disponibili nel ResultSet per spostare il cursore:
    • void beforeFirst()
    • void afterFirst()
    • boolean absolute(int rowNumber) o boolean relative(int rowNumber) o boolean next()
    • boolean prevous()
  • Per recuperare i valori di una colonna della riga corrente il ResultSet mette a disposizione dei metodi di get per ogni tipo di dato. Es: getDouble()
  • Le colonne possono essere identificate in due modi:
    • Tramite indice di colonna: getDouble(int colNum)
    • Tramite nome della colonna: getDouble(String colName)
  • Gli indici di colonna in un ResultSet partono da 1 e NON da 0
  • Se si utilizza un indice di colonna che NON esiste per recuperare i dati da un ResultSet si ottiene una: SQLException: Column index out of range
  • Nel caso non si conosca il numero di colonne presenti nel ResultSet lo si può ricavare tramite: o resultSet.getMetadata().getColumnCount()
  • E’ possibile modificare dei valori nel database direttamente tramite il ResultSet; occorre però dichiararlo come modificabile nel create Statement in questo modo: createStatement(ResultSet.CONCUR_UPDATABLE)
  • Per effettuare una modifica al ResultSet occorre eseguire l’update del tipo corretto, indicando il nome della colonna da modificare o il suo indice e poi il nuovo valore da scrivere.
    • Dopo aver fatto questo, per rendere effettive le modifiche, occorre chiamare il metodo updateRow().
    • Se NON viene invocato il metodo updateRow() le modifiche al ResultSet non sono salvate e vengono perse.
  • Per inserire un nuovo record nel database tramite il ResultSet si deve chiamare il metodo moveToInsertRow() che posiziona il cursore nel punto giusto per l’inserimento e crea il buffer per i valori da inserire. A questo punto occorre fare i vari update delle colonne con i valori da inserire ed infine si invoca il metodo insertRow().
  • Per eliminare un record si scorre il cursore del ResultSet fino al record desiderato e poi si invoca il metodo deleteRow()
  • Tramite il metodo executeUpdate() è possibile eseguire anche uno statement di CREATE TABLE per creare oggetti da programma.
  • Nel caso si fornisca uno statement SQL sintatticamente non corretto si ottiene una SQLSyntaxErrorException.
  • L’interfaccia Connection mette a disposizione il metodo getMetaData() per recuperare le informazioni relative al db.
    • Tale metodo ritorna un oggetto di tipo DatabaseMetaData
  • Il metodo boolean absolute(int index) sposta il cursore alla riga indicata come parametro.
    • Se il valore del parametro è positivo il cursore si posizione al valore indicato
    • Se invece il valore del parametro è negativo il cursore si posizione sulla riga che sta alla fine del ResultSet meno il valore passato.
    • Esempio: se il ResultSet ha 10 righe e si passa al metodo absolute il parametro -3, absolute(-3), il cursore si posiziona alla riga 7, data da 10-3.
    • Se viene fornito un valore, positivo o negativo, al di fuori del range del ResultSet, il cursore si posiziona alla fine o all’inizio del ResultSet. o absolute(1) equivale a chiamare il metodo first()
    • absolute(-1) equivale a chiamare il metodo last()
  • Auto-commit di default è settato a true. Per disabilitarlo occorre invocare il metodo setAutoCommit(false) sull’oggetto Connection.
  • I savepoints possono anche NON avere un nome esplicito. In questo caso possono essere identificati tramite l’id assegnato dal data source sottostante.
  • Savepoint è un’interfaccia e NON una classe astratta.
  • Se in un ResultSet ci sono 2 colonne con lo stesso nome, per recuperarne i valori NON si possono usare i nome delle colonne ma si devono utilizzare gli indici.
  • Un PreparedStatement può gestire solo dei parametri di tipo IN
  • Un CallableStatement può gestire parametri IN, OUT ed INOUT
  • Per istanziare un oggetto Statement si fa: Statement stat = connection.createStatement();
  • Per aggiungere un record ad un ResultSet occorre:
    • invocare il metodo: resultSet.moveToInsertRow()
    • modificare i valori da inserire con il metodo resultSet.updateString() o effettuare l’inserimento effettivo con il metodo resultSet.insertRow()
  • Per fare il load di un driver JDBC 3.0 occorre fare
    • Class.forName(“com.mysql.jdbc.Driver”).newInstance();
    • Dalla versione 4 in poi questo statement NON è più necessario e si può fare direttamente la get della connessione in questo modo:
    • Connection conn = DriverManager.getConnection(“…driver string…”, “user”,”password”);
  • Quando si fa il rollback() senza specificare un Savepoint si annulla l’intera transazione e NON si torna ad esempio ad un Savepoint senza nome.
  • Prima di fare la get degli elementi di un ResultSet occorre invocare il metodo next() per posizionarsi sul prossimo record da leggere.
  • E’ possibile utilizzare un JdbcRowSet come un componente JavaBean
  • CachedRowSet cacha gli oggetti in memoria e permette di utilizzarli anche senza essere connessi alla sorgente dati.
  • WebRowSet fornisce un ResultSet in formato XML e non in formato JSON
  • Il filtro in un FilteredRowSet può essere modificato anche dopo la sua creazione tramite il metodo setFilter()
This entry was posted in $1$s. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *