Resúmenes
Apuntes universitarios en formato Markdown desde Obsidian.
Persistenza e JDBC
download Descargar MDLa persistenza è la capacità di un'applicazione di salvare i dati in modo che sopravvivano alla chiusura del programma. Nelle Java Web App, questo avviene solitamente tramite database relazionali (RDBMS) e la libreria JDBC.
Il Conflitto di Impedenza (Impedance Mismatch)
Esiste una differenza strutturale tra il mondo degli oggetti (Java) e quello delle relazioni (SQL):
- Struttura: Java usa oggetti e riferimenti; SQL usa tabelle e chiavi esterne.
- Accesso: In Java navighiamo tra oggetti (
gruppo.getStudenti()); in SQL usiamo leJOIN. - Tipi: Alcuni tipi Java non hanno un corrispettivo diretto in SQL (es. collezioni, tipi personalizzati).
Strategie di Persistenza
1. Forza Bruta
Scrivere query SQL direttamente all'interno della logica di business.
- Svantaggio: Codice disordinato, difficile da mantenere e testare.
2. Pattern DAO (Data Access Object) - Consigliato
Si separa la logica di accesso ai dati dal resto dell'app.
- DTO (Data Transfer Object): Classi semplici (JavaBeans) che contengono i dati (es. classe
Studente). -
DAO: Interfacce e classi che implementano le operazioni CRUD (Create, Retrieve, Update, Delete).
3. ORM (Object-Relational Mapping)
Framework come Hibernate o JPA che automatizzano la conversione tra oggetti e tabelle.
JDBC (Java Database Connectivity)
JDBC è l'API standard di Java per interagire con i database.
Esempio di CRUD (Retrieve)
public Studente findByPrimaryKey(String matricola) { Connection conn = dataSource.getConnection(); Studente s = null; String query = "SELECT * FROM studente WHERE matricola = ?"; try (PreparedStatement st = conn.prepareStatement(query)) { st.setString(1, matricola); ResultSet rs = st.executeQuery(); if (rs.next()) { s = new Studente(); s.setMatricola(rs.getString("matricola")); s.setNome(rs.getString("nome")); // ... } } catch (SQLException e) { e.printStackTrace(); } return s; }Tecniche Avanzate
Lazy Load (Caricamento Pigro)
Per evitare di caricare migliaia di record inutilmente (es. caricare tutti gli studenti ogni volta che guardo un Gruppo), si usa il caricamento on-demand.
- Pattern Proxy: Si restituisce un "finto" oggetto (Proxy) che interroga il DB solo quando viene chiamato il metodo
getStudenti().Chiavi Surrogate e IdBroker
Invece di usare chiavi naturali (come il Codice Fiscale), si preferiscono chiavi numeriche generate dal sistema (chiavi surrogate).
- IdBroker: Una classe o procedura che garantisce la generazione di ID univoci (es. tramite
SEQUENCEin PostgreSQL oAUTO_INCREMENTin MySQL).Aggiornamenti in Cascata
Quando si salva un oggetto complesso (es. un
Gruppocon una lista diStudenti), il DAO deve preoccuparsi di salvare ricorsivamente tutti i figli che non sono ancora presenti nel DB.public void save(Gruppo g) { // 1. Salva il gruppo e ottieni l'ID // 2. Itera sugli studenti del gruppo for (Studente s : g.getStudenti()) { if (studenteDao.exists(s.getMatricola())) { studenteDao.update(s); } else { studenteDao.insert(s); } } }