Introduzione a pBeans: un’alternativa a Hibernate (seconda parte)
In questo secondo articolo viene approfondita con diversi esempi di codice la libreria pBeans
Ciao a tutti, anche se un poco in ritardo rispetto alla prima parte dell’articolo, mi sembra il momento di concludere il nostro viaggio all’interno di pBeans. In questa seconda ed ultima parte dell’articolo vedremo come operare sul database tramite la classe che mappa la tabella del nostro database.
Come prima cosa dobbiamo ricordarci che, uno dei vantaggi che il pacchetto ci mette a disposizione è quello di poter selezionare il tipo di database usato, la username e la password per la connessione, tramite un file di properties che deve essere formattato nel seguente modo.
1 2 3 4 5 |
dataSourceClass=net.sourceforge.pbeans.data.GenericDataSource driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost/DB?user=myUser&password=myPassword |
Come si può notare abbiamo tre voci molto interessanti.
- DataSourceClass: permette di determinare il database usato. Se si volesse stare sul generico basterebbe inserire la stringa net.sourceforge.pbeans.data.GenericDataSource che rappresenta il percorso della classe GenericDataSource che identifica il tipo database che si sta usando, in modalità del tutto trasparente. Consiglio questa soluzione.
- DriverClassName: il driver del database che si usa per la connessione.
- Url: l’url del nostro database con username e password. User e password possono essere anche voci separate dall’url.
Dopo tutto questo siamo pronti a scrivere l’ultima parte del nostro applicativo. Ora vediamo il codice che ci interessa.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
package jce.database; import java.beans.IntrospectionException; import java.lang.reflect.InvocationTargetException; import java.util.Properties; import javax.sql.DataSource; import jce.util.AppProperties; import net.sourceforge.pbeans.Store; import net.sourceforge.pbeans.StoreException; import net.sourceforge.pbeans.util.BeanMapper; /** * * La classe implementa le operazioni di base sul database. * * @author Mattia Zuliani * */ public class Database { private Store theStore; private Properties configuration; private Class dataSourceClass; /** Costruttore di base della classe. */ public Database(String nomeFile) { Properties app = new Properties(); try { app.load(new FileInputStream("nomeFile")); } catch(java.lang.Exception e) {} init(app); } /** Costruttore di base della classe */ public Database(AppProperties app) { init(app); } /** Il metodo inizializza i costruttori di base */ private void init(Properties app) { try { dataSourceClass = Class .forName(app.getPropertiy("dataSourceClass")); } catch (ClassNotFoundException cnfe) { System.err.println(cnfe.getMessage()); } try { DataSource source = (DataSource) dataSourceClass.newInstance(); BeanMapper.populateBean(source, app); theStore = new Store(source); } catch (InstantiationException ie) { ie.printStackTrace(); } catch (IllegalAccessException iae) { iae.printStackTrace(); } catch (InvocationTargetException ite) { ite.printStackTrace(); } catch (IntrospectionException ine) { ine.printStackTrace(); } catch (StoreException se) { se.printStackTrace(); } } /** * Il metodo restituisce lo store ottenuto. * * @return Lo store. * */ public Store getStore() { return this.theStore; } } |
Nella prima parte qui riportata si vede come vengono caricati i parametri di configurazione dal file di configurazione e viene creato un oggetto Store che sarà l’anima della nostra applicazione. L’oggetto in effetti mette a disposizione del programmatore una serie di metodi che consentono di operare sulle tabelle selezionate del nostro DB.
Come vedete io preferisco dividere il codice per la connessione al DB da quello che opera sulla tabella. La classe Database può essere usata ogni volta che dovremo creare la mostra classe di navigazione per ridurre i tempi di sviluppo.
Ecco la classe per la navigazione. Come vi ricorderete la volta scorsa abbiamo creato una classe che mappa una tabella con login e password.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
public class LoginOperation { private Database database; private Store theStore = null; /** * Costruttore di base. * * @param propertyFile * File contenete le proprietà * per la connessione al DB. * */ public CatalogoOperation(String propertyFile) { database = new Database(propertyFile); theStore = database.getStore(); } /** * Inserimento del dati nel database. * * @param user Username. * @param pw Password. * */ public void commit(String user, String pw) { try { LOGIN login = new LOGIN(user, pw); theStore.save(login); } catch (StoreException se) { se.printStackTrace(); } } /** * Inserimento record * * @param login Oggetto persistente da inserire. * */ public void commit(LOGIN login) { try { theStore.save(login); } catch (StoreException se) { se.printStackTrace(); } } /** * Il metodo restituisce un interfaccia ResultsIterator * contente tutti gli oggetti presenti nel database. * * @return Tutti i record del database. * */ public ResultsIterator selectAll() { ResultsIterator logins = null; try { logins = theStore.select(LOGIN.class); } catch (StoreException se) { se.printStackTrace(); } return logins; } /** * Ottiene un solo oggetto persistente ottenuto dalla ricerca. * * @param filter Filtro. * */ public LOGIN selectSingle(Map filter) { LOGIN login = null; try { login = (LOGIN) theStore.selectSingle(LOGIN.class, filter); } catch (StoreException se) { se.printStackTrace(); } return login; } /** * Cancella gli elementi contrassegnati dal elemento mappato * * @param filter Fitro per l'inserimento degli elementi da cancellare. * */ public void delete(Map filter) { try { theStore.delete(LOGIN.class, filter); } catch (StoreException se) { se.printStackTrace(); } } /** * Cancella l'elemento persistente dal database. * * @param login Elemento persistente da cancellare. * */ public void delete(LOGIN login) { try { theStore.delete(login); } catch (StoreException se) { se.printStackTrace(); } } } |
Come vedete l’oggetto Store che viene rappresentato da theStore consente di operare con metodi molto semplici sulle nostre tabelle del database. I metodi più interessanti da usare sono:
- Save(Oggetto mapClass): consente di salvare un nuovo record o di sostituirne uno già inserito.
- Select(Oggetto mapClass): seleziona tutti i record della tabella. Viene restituito un oggetto ResultsIterator che conterrà tutti gli oggetti della nostra tabella.
- SelectSingle(Oggetto mapClass, Map filter): restituisce solo un oggetto della ricerca fatta.
- Delete(Oggetto mapClass): Cancella un record dalla tabella.
Credo che ormai siamo pronti. Le nostre classi sono pronte ora dobbiamo solo inserirle nelle nostre applicazioni.
Buon Lavoro.