Potresti (dovresti perlomeno) cercare di applicare il pattern "DAO". Trovi svariata documentazione online a riguardo. In sostanza definisci innanzitutto una interfaccia che descrive i metodi essenziali che sono sensati ed utili per una certa tipologia di dato.
Ad esempio per un Prodotto:
codice:
public interface ProdottoDao {
List<Prodotto> leggiProdotti();
// ... puoi aggiungere altri metodi per ricerche specifiche ....
Prodotto leggiProdottoPerId(Long id);
void inserisciProdotto(Prodotto prodotto);
void aggiornaProdotto(Prodotto prodotto);
void eliminaProdotto(Prodotto prodotto);
}
Poi se hai un DB es. MySQL puoi creare una implementazione (classe) concreta es. MysqlProdottoDaoImpl che implementa concretamente quei metodi.
Se si fa in modo che le implementazioni concrete dei Dao vengano assegnate dove necessario (in altre classi) magari attraverso un meccanismo di injection o magari estratte da una entità condivisa, è anche possibile arrivare ad una applicazione che è completamente "switchabile" come DB (es. da MySQL a Oracle a PostgreSQL) senza cambiare NULLA del resto della applicazione, magari solo cambiando un parametro di configurazione.
Un altro aspetto rilevante è quelle delle eccezioni. Se usi direttamente la API JDBC, essa tratta e lancia fuori solo eccezioni "checked". Generalmente in questo contesto si tende a "lanciar fuori" dai Dao delle eccezioni "unchecked" perché la dichiarazione e la considerazione obbligatoria delle eccezioni checked può spesso diventare un po' noiosa/onerosa.
Quindi sarebbe anche utile definire delle eccezioni unchecked (almeno una generalizzata) che "incapsulano" le eccezioni da JDBC.
C'è ancora un altro aspetto importante per evitare dubbie ripetizioni di codice. Immagina di avere svariate tipologie di dati: Prodotto, Utente, Cliente, ecc...
Se hai già usato JDBC, sai sicuramente cosa vuol dire fare una query per estrarre N record da una tabella e alla fine dare in uscita un List<XYZ> (dove XYZ uno dei tuoi dati). Ci sono infatti una serie di passi ben precisi da fare:
- ottenere una Connection
- create lo Statement
- eseguire la query
- ottenere il ResultSet
- creare una nuova lista parametrizzata <XYZ>
- iterare con il classico idioma while (rs.next()) { ...... }
- estrarre i dati dalle colonne per ciascun record
- creare e impostare un oggetto di tipo XYZ
- aggiungere l'oggetto nella lista
alla fine:
- chiudere in modo appropriato le risorse
- chiudere la Connection (o magari meglio "rilasciarla" in modo che sia ri-usabile ... dipende dal contesto).
Quali di queste operazioni sono standard di JDBC e quali specifiche per la certa tipologia di dato XYZ? Appunto. Se hai svariate tipologie di dati (da 3~4 in su) e NON stai usando framework/librerie di più alto livello rispetto a JDBC, dovresti anche pensare a realizzare un meccanismo di "template" in modo da separare i passi standard per JDBC da quelli specifici per quel tipo di dato.
Se puoi usare un framework/libreria al di sopra di JDBC, potrei consigliarti MyBatis che perlomeno semplifica moltissimo la "mappatura" tra JDBC e le tue classi di dati.
Per questo e per il resto c'è comunque molto da "studiare".