DB4O: un database Object-Oriented, per Java e dotNet
Se cercate un’alternativa ai Database relazionali, DB4O potrebbe fare al caso vostro. In questo articolo, vedremo come salvare e ricercare entry e soprattutto come viene gestito il refactoring degli oggetti salvati.
Sicuramente gli RDBMS godono di una supremazia difficilmente intaccabile, che rende impensabile una sostituzione, specie per moli di dati considerevoli e per dati dallo schema non elementare. Ma molti sviluppatori sono stufi di scrivere query SQL e soprattutto di trasporre modelli Object Oriented su relazioni e tabelle. Ponti middleware che permettano il mapping Object-relational (ORM), come Hibernate, Castor o Ibatis sono solitamente la migliore soluzione, ma richiedono comunque una fase di apprendimento non indifferente.
DB40 è un database Object Oriented, facilissimo da usare, che permette il salvataggio e la ricerca di oggetti Java a costo praticamente nullo. Vediamone l’utilizzo, con un esempio classico: una classe Person, con 2 campi di tipo String e un int e relativi getter e setter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public class Person{ private String firstName; private String lastName; private int age; public Person(){ } public Person(String firstName, String lastName, int age){ this.firstName = firstName; this.lastName = lastName; this.age = age; } public String getFirstName() { return firstName; } public void setFirstName(String value) { firstName = value; } public String getLastName() { return lastName; } public void setLastName(String value) { lastName = value; } public int getAge() { return age; } public void setAge(int value) { age = value; } } |
Per salvare una istanza della classe Person basta una riga di codice, mentre per effettuare le ricerche si utilizzano le Query by Example:
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 |
import com.db4o.*; public class Hellodb4o{ public static void main(String[] args) throws Exception{ ObjectContainer db = null; try{ db = Db4o.openFile("persons.data"); Person brian = new Person("Brian", "Goetz", 39); Person jason = new Person("Jason", "Hunter", 35); Person brians = new Person("Brian", "Sletten", 38); Person david = new Person("David", "Geary", 55); Person glenn = new Person("Glenn", "Vanderberg", 40); Person neal = new Person("Neal", "Ford", 39); db.set(brian); db.set(jason); db.set(brians); db.set(david); db.set(glenn); db.set(neal); db.commit(); // Trova tutti i "Brians" ObjectSet brians = db.get(new Person("Brian", null, 0)); while (brians.hasNext()) System.out.println(brians.next()); } finally { if (db != null) db.close(); } } } |
Come vedete il tutto è molto semplice, specie nel nostro scenario molto elementare. Bisogna comunque avere alcune accortezze tipiche dei DB Object Oriented, nel salvare i dati, per esempio per garantire l’unicità di alcune chiavi (o coppie di chiavi). Ma questo è ripagato, per esempio, dalla facilità di refactoring degli oggetti, conservando la persistenza. Aggiungiamo, per esempio, un campo enum alla classe Person:
1 2 3 4 5 |
public enum Mood { HAPPY, CONTENT, BLAH, CRANKY, DEPRESSED, PSYCHOTIC, WRITING_AN_ARTICLE } |
La ricerca di elementi, utilizzando la nuova versione della classe, mostra anche gli elementi salvati prima della modifica:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public static void main(String[] args) throws Exception{ ObjectContainer db = null; try{ db = Db4o.openFile("persons.data"); ObjectSet brians = db.get( new Person("Brian", null, 0, null)); while (brians.hasNext()) System.out.println(brians.next()); } finally{ if (db != null) db.close(); } } |
Il cui output è:
1 2 |
[Person: firstName = Brian lastName = Sletten age = 38 mood = null] [Person: firstName = Brian lastName = Goetz age = 39 mood = null] |
Gli svantaggi di un approccio di questo tipo sono evidenti, si rinuncia alla accessibilità totale (per piattaforma e linguaggio di programmazione) che un DB classico offre, si perde probabilmente in prestazioni e soprattutto in scalabilità dell’architettura. Ma i files che contengono il salvataggio sono accessibili da tutte le piattaforme supportate (attualmente Java e DotNet), permettendo ad esempio la sincronizzazione dei dati fra una applicazione Desktop in Visual Basic .net, una server in Java e un per dispositivi mobili in C#.
La licenza di DB4O è doppia, GPL per chi vuole utilizzarlo in ambito Open e Commerciale per chi intende mettere sul mercato i propri prodotti.
Per approfondimenti:
http://www.db4o.com/
The busy Java developer’s guide to db4o: Queries, updates, and identity
The busy Java developer’s guide to db4o: Database refactoring with db4o
Esempio d’uso in C#