Ejemplo DB4o

7
Introducción OODB son las siglas de "Base de Datos Orientada a Objetos" y RDB es "Base de Datos Relacional". Existe una gran variedad de RDB, no así tantos de OODB. db4o (DB for Objects) es una implementación de OODB libre (bajo GPL - General Public Licence, por lo tanto de código abierto) que se encuentran actualmente en el mercado. db4o representa una alternativa a las bases de datos relacionales utilizadas tradicionalmente. Nota: varios autores llaman ODBMS y RDBS a lo que en esta página se menciona como OODB y RDB. Contenidos Diferencias principales entre OODB y RDB La diferencia entre un tipo de base de datos y el otro radica en la naturaleza con la que se guardan, consultan y manejan los datos. En las bases de datos relacionales los datos están en registros de tablas, que almacenan datos propiamente dichos o referencias a registros de otras tablas. En el modelo relacional el mapeo entre los objetos del modelo de negocio y las tablas debe establecerse y configurarse en tiempo de desarrollo. En cambio usando db4o y las demás bases de datos orientadas a objetos esto es transparente al desarrollador, quien sólo llama desde su código a métodos del objeto que administra la base de datos para realizar una consulta, dar un alta, una modificación o eliminar algún objeto de la base de objetos. El tiempo de desarrollo es mucho menor en una solución orientada a objetos si se utiliza una OODB. Ventajas principales de OODB frente a RDB Mayor velocidad de desarrollo (tranparencia) o No hay mapeos entre objetos y tablas o No hay que crear componentes que accedan a las bases de datos o El código de acceso a la base es muy sencillo y entendible (métodos get, set y delete) en el caso de db4o. Mejor performance con objetos de negocio complejos (árboles, estructuras anidadas, relaciones N a N, relaciones recursivas) Fácil Backup (la base completa está en un solo archivo) No necesita administración o Tiene un recolector de basura - garbage collector - que borra los objetos que no son referenciados o Al cambiar algo en las clases no se necesita modificar nada en la base de objetos

Transcript of Ejemplo DB4o

Page 1: Ejemplo DB4o

IntroducciónOODB son las siglas de "Base de Datos Orientada a Objetos" y RDB es "Base de Datos Relacional". Existe una gran variedad de RDB, no así tantos de OODB. db4o (DB for Objects) es una implementación de OODB libre (bajo GPL - General Public Licence, por lo tanto de código abierto) que se encuentran actualmente en el mercado. db4o representa una alternativa a las bases de datos relacionales utilizadas tradicionalmente.

Nota: varios autores llaman ODBMS y RDBS a lo que en esta página se menciona como OODB y RDB.

ContenidosDiferencias principales entre OODB y RDB

La diferencia entre un tipo de base de datos y el otro radica en la naturaleza con la que se guardan, consultan y manejan los datos. En las bases de datos relacionales los datos están en registros de tablas, que almacenan datos propiamente dichos o referencias a registros de otras tablas. En el modelo relacional el mapeo entre los objetos del modelo de negocio y las tablas debe establecerse y configurarse en tiempo de desarrollo. En cambio usando db4o y las demás bases de datos orientadas a objetos esto es transparente al desarrollador, quien sólo llama desde su código a métodos del objeto que administra la base de datos para realizar una consulta, dar un alta, una modificación o eliminar algún objeto de la base de objetos. El tiempo de desarrollo es mucho menor en una solución orientada a objetos si se utiliza una OODB.

Ventajas principales de OODB frente a RDB

Mayor velocidad de desarrollo (tranparencia)o No hay mapeos entre objetos y tablaso No hay que crear componentes que accedan a las bases de datoso El código de acceso a la base es muy sencillo y entendible

(métodos get, set y delete) en el caso de db4o.

Mejor performance con objetos de negocio complejos (árboles, estructuras anidadas, relaciones N a N, relaciones recursivas)

Fácil Backup (la base completa está en un solo archivo)

No necesita administracióno Tiene un recolector de basura - garbage collector - que borra los objetos que no

son referenciadoso Al cambiar algo en las clases no se necesita modificar nada en la base de objetos

Las búsquedas se hacen directamente usando objetos.o Búsquedas usando objetos, sencillas (QBE, "Query By Example")o Búsquedas Nativas (la manera recomendada para buscar)o Búsquedas usando la "SODA Query API" (búsquedas de bajo nivel)

Los cambios en los objetos (agregar o quitar atributos a una clase) se aplican directamente en la base, sin tener que migrar datos ni reconfigurar nada.

Page 2: Ejemplo DB4o

Descarga y utilización de db4o (para Java) Primero hay que bajar el archivo que contiene el jar con las clases de db4o. Se puede

encontrar tanto en la sección de Community  o como en la secciónTestDrive  de la página oficial del producto.

Para usar el jar, simplemente hay que extraerlo del zip en el que viene comprimido (dentro del directorio lib) y colocarlo donde más nos guste. Luego simplemente se importa desde el código y se empieza a usar :)

Herramientas para el manejo de bases de datos de db4o

Se pueden bajar dos herramientas para el manejo de bases de objetos, desde la sección de descargas  del sito oficial de db4o.

ObjectManager (para navegar el contenido de la base de objetos y hacer consultas) Plugin para Eclipse (idem ObjectManager , pero dentro del Eclipse)

Ejemplo de uso

A continuación se expone un sencillo ejemplo práctico de utilización de db4o hecho en Java.

ObjectOrientedDataBase se trata de una clase que encapsula los métodos de Db4o get, set y delete, brindando las opciones de insertar un objeto en la base de objetos, actualizarlo y borrarlo de la base de datos, así como también hacer tres tipos de búsqueda: usando un objeto con datos filtros, usando la clase (NombreClase.class) (para obtener todos los objetos de dicha clase que existan) o con una consulta (String).

Esta implementación trabaja con objetos de la clase Object, por lo que se puede utilizar con cualquier clase que se quiera persistir. A su vez, hereda de una clase abstracta simplificada (AbstractDataBase).

El ejemplo realizado con la clase ObjectOrientedDataBase es una aplicación que da de alta y modifica varios pilotos de carreras, tal como lo hace el tutorial oficial de db4o. Dista de ser algo demasiado elaborado y tiene cosas por corregir, pero apunta a mostrar la simplicidad con la que se puede trabajar con db4o.

Tips para empezar

Para hacer una actualización, primero hay que hacer un get y recién luego, con el (o los) objeto(s) encontrado(s), llamar a set, previa modificación. Se puede observar una implementación de actualización en el método "actualizar()" de la clase ObjectOrientedDataBase.

De la misma forma, para borrar un objeto de la base, primero hay que hacer un get y recién luego, con el (o los) objeto(s) encontrado(s), llamar a delete. Se puede observar

Page 3: Ejemplo DB4o

una implementación de borrado en el método "borrar()" de la clase ObjectOrientedDataBase.

Para que se tomen todos los cambios de objetos complejos en una actualización, hay que setearlo llamando a cascadeOnUpdate(true), dado que por defecto sólo se actualizan los atributos del objeto que son de tipos base y los atributos String. Ejemplo:

Db4o.configure().objectClass("com.epidataconsulting.epidata.colmena.db.db4o.ejemplo.Piloto").cascadeOnUpdate(true);

Activation en db40 (Lazy Inicialization)

db4o implementa el concepto de Lazy Inicialization (inicialización tardía) de una manera muy elegante: se maneja con la activation (activación) de atributos, con niveles. Por defecto se levantan de la base sólo los atributos de los objetos anidados hasta 5 niveles a partir del objeto solicitado (con get). A partir del sexto nivel, los valores son llenados con null (en las referencias a objetos) o con valores nulos (en los atributos de tipos básicos).

Esto se hace así para evitar colocar en memoria una estructura demasiado grande que pueda generar una OutOfMemoryException .

Si se quisiera usar un objeto que se encuentre en un nivel posterior al quinto (o al establecido) habrá que activarlo, mediante el método activate() del ObjectContainer .

Ejemplo de activation por cada atributo visitado (recorriendo una lista)o Supongamos una lista simplemente enlazada de objetos de la clase Nodo. Si se

quiere recorrer toda la lista sin obtener un null en el medio, entonces activaremos cada enlace antes de continuar con el recorrido:

ObjectSet resultado = objectContainer.get(Nodo.class);Nodo objeto = (Nodo) resultado.next(); // para obtener el 1er ítem que se obtuvo de la base de objetosNodo siguiente = objeto.getSiguiente();while (siguiente != null) { objectContainer.activate(siguiente, PROFUNDIDAD_DE_ACTIVACION); // esta constante suele ser 1 procesarNodo(siguiente); siguiente = siguiente.getNext();}

También se puede configurar Db4o para que el nivel de activación sea menor o mayor a 5, si la performance no es la esperada en la persistencia de determinado modelo de negocio. Puede setearse para una clase o bien para todas las clases.

Ejemplos de configuración de la activation a nivel general o por claseo Para una clase en particular:

Db4o.configure().objectClass(NombreClase.class).cascadeOnActivate(true);

o Para toda las clases persistidas:

Page 4: Ejemplo DB4o

Db4o.configure().activationDepth(activationDepth)

EJEMPLO

package com.epidataconsulting.epidata.colmena.db.db4o;

import java.util.Iterator;import java.util.List;

import com.db4o.Db4o;import com.db4o.ObjectContainer;import com.db4o.ObjectSet;import com.epidataconsulting.epidata.colmena.db.AbstractDataBase;import com.epidataconsulting.epidata.colmena.db.exceptions.DbException;

/** * Wrapper simplificado de DB4O * * @author EPIDATA * @author Pablo Tortorella * * Copyright Epidata Consulting S.R.L. - 2006 */public class ObjectOrientedDataBase extends AbstractDataBase {

/** * Objeto que se usa como "base de datos" */private ObjectContainer objectContainer;

/** * Directorio en el cual se encuentra el archivo con la DB */private String directorio = "."; // esto deberia ser configurable

/** * Nombre del archivo en el que se guarda la DB */private String nombreArchivo = "oodb.yap"; // esto deberia ser

configurable

/** * Constructor

Page 5: Ejemplo DB4o

* * @param nombreDB */public ObjectOrientedDataBase(String nombreDB) {

super(nombreDB);}

public void configurarDB() throws DbException {/* * TODO : la idea es hacer que la configuracion de cada DB

la tome de un archivo properties. * Tanto el directorio como el nombre del archivo */

}

public void abrirConexion() throws DbException {this.configurarDB();this.objectContainer = Db4o.openFile(this.directorio + "/"

+ this.nombreArchivo);}

public void cerrarConexion() throws DbException {objectContainer.close();

}

public List buscar(Object objeto) throws DbException {ObjectSet resultado = this.objectContainer.get(objeto);return resultado;

}

public List buscar(String consulta) throws DbException {ObjectSet resultado = this.objectContainer.get(consulta);return resultado;

}

public List buscar(Class clase) throws DbException {ObjectSet resultado = this.objectContainer.get(clase);return resultado;

}

public void guardar(Object objeto) throws DbException {this.objectContainer.set(objeto); // inserta el objeto,

aunque exista uno exactamente igual}

public void actualizar(Object objeto) throws DbException {ObjectSet objetos = this.objectContainer.get(objeto);if (!objetos.isEmpty()) {

for (Iterator i = objetos.iterator(); i.hasNext();) {

Object o = (Object) i.next();this.objectContainer.set(objeto);// si existen, actualiza todos los objetos

que machean}

Page 6: Ejemplo DB4o

} else {throw new DbException();

}}

public void borrar(Object objeto) throws DbException {ObjectSet objetos = this.objectContainer.get(objeto);if (!objetos.isEmpty()) {

for (Iterator i = objetos.iterator(); i.hasNext();) {

Object o = (Object) i.next();this.objectContainer.delete(o);// si existen, borra todos los objetos que

machean}

} else {throw new DbException();

}}

public void commit() throws DbException {this.objectContainer.commit();

}}