Una classe astratta per l’esecuzione delle query

21 agosto 2017

Continuiamo la realizzazione dell’architettura introdotta nel capitolo precedente con la realizzazione di una classe astratta (AbstractDAO) come implementazione base del pattern DAO.

Desideriamo che AbstractDAO incapsuli una logica di servizio comune a tutte le operazioni di interazione con i database: costruzione di oggetti connessione e di oggetti per l’esecuzione di query e operazioni CRUD.

La classe sarà di tipo generico e specializzata dalle sottoclassi in base alle tabelle e alle funzionalità. AbstractDAO utilizzerà inoltre la classe DBManager per fornire i servizi base richiesti dalle sottoclassi.

Si delinea così un’architettura a strati alla cui base abbiamo DBManager sulla quale poggia AbstractDAO che, a sua volta, è il mattone base per tutte le classi DAO utilizzate dagli strati superiori del sistema.

Il codice di AbstractDAO è il seguente:

public abstract class AbstractDAO<T> {

	private DBManager dbManager;

	public AbstractDAO() {
		try {
			dbManager = DBManager.getInstance();
		} catch (DBManagerException e) {
			System.err.println("AbstractDAO:" + e.getMessage());
		}
	}

	protected Connection getConnection() throws SQLException {
		if (dbManager != null) {
			return dbManager.getConnection();
		}
		return null;
	}
	
	protected PreparedStatement prepareStatement(Connection conn, String queryId) throws SQLException {
		return conn.prepareStatement(dbManager.getQuery(queryId));
	}
	
	protected  List<T> rsReader(ResultSet rs) throws SQLException {
	   ArrayList<T> beans = new ArrayList<>(); 
	   while(rs.next())  beans.add(makeBean(rs)); 
	   return beans;
	}
	
	protected String getQuery(String queryId) {
		return dbManager.getQuery(queryId);
	}
	
	protected abstract T makeBean(ResultSet rs) throws SQLException;
}

T indica classe bean legata ad una specifica tabella. Notiamo come essa utilizzi DBManager in modo trasparente alle sottoclassi per fornire servizi di connessione, costruzione di oggetti PreparedStatement per query da compilare, lettura di oggetti ResultSet risultato di query per la costruzione di liste Java e recupero delle stringhe di query.

Alle sottoclassi è richiesta l’implementazione del metodo makeBean() per la costruzione dell’oggetto Java rappresentando un record del risultato di interrogazione.

Supponiamo di avere una tabella persona i cui campi siano in corrispondenza per nome e tipo con la seguente classe Persona:

	public class Persona {
    
		private int    id;
		private String nome;
		private String cognome;
		private String professione;
		private int    eta;
		
		public Persona(String nome, String cognome, String professione, int eta) {
			this.nome = nome;
			this.cognome = cognome;
			this.professione = professione;
			this.eta = eta;
		}
		..
	}
	

Editiamo il file query.properties in modo che contenga le query:

lista_persone=select nome, cognome, professione, eta from persona
lista_persone_eta_maggiore=select nome, cognome, professione, eta from persona where eta>=?

Specializziamo la classe AbstractDAO<T> come AbstractDAO<Persona> dando vita alla seguente classe DAO:

    public class PersonaDAO extends AbstractDAO<Persona> {

	@Override
	protected Persona makeBean(ResultSet rs) throws SQLException{		
		return new Persona(rs.getString("nome"), rs.getString("cognome"),
				rs.getString("professione"), rs.getInt("eta"));
	}

	public List<Persona> getPersone(){
		try( Connection conn = getConnection();
			 Statement  stmt = conn.createStatement()){
			 return rsReader(stmt.executeQuery(getQuery("lista_persone")));
		} catch(SQLException e){
			e.printStackTrace();
		}
		return new ArrayList<Persona>();
	}
	
	public List<Persona> getPersoneByEtaMag(int eta){
		try( Connection conn = getConnection();
			 PreparedStatement  pstmt = 
					 conn.prepareStatement(getQuery("lista_persone_eta_maggiore"))){
			pstmt.setInt(1, eta);
			return rsReader(pstmt.executeQuery());
		} catch(SQLException e){
			e.printStackTrace();
		}
		return new ArrayList<Persona>();
	}
}
    

makeBean() realizza l’oggetto Persona leggendo i dati dal ResultSet. getPersone() ottiene una connessione tramite getConnection() ereditato da AbstractDAO e recupera la stringa della query da eseguire con il metodo getQuery() sempre ereditato da AbstractDAO.

La classe Statement consente l’esecuzione della query restituendo un oggetto ResultSet che per la navigazione dei record contenuti nel risultato. Un ResultSet mette infatti a disposizione il metodo next() per muovere il cursore in avanti nella lista dei record.

Tutte le lezioni

1 ... 66 67 68 ... 130

Se vuoi aggiornamenti su Una classe astratta per l'esecuzione delle query inserisci la tua e-mail nel box qui sotto:
Tags:
 
X
Se vuoi aggiornamenti su Una classe astratta per l'esecuzione delle query

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy