Está en la página 1de 6

Introduccin

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 implementacin de OODB libre (bajo GPL General Public Licence, por lo tanto de cdigo 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 pgina 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 estn 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 dems bases de datos orientadas a objetos esto es transparente al desarrollador, quien slo llama desde su cdigo a mtodos del objeto que administra la base de datos para realizar una consulta, dar un alta, una modificacin o eliminar algn objeto de la base de objetos. El tiempo de desarrollo es mucho menor en una solucin 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 cdigo de acceso a la base es muy sencillo y entendible (mtodos 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) Fcil Backup (la base completa est en un solo archivo) No necesita administracin 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 Las bsquedas se hacen directamente usando objetos. o Bsquedas usando objetos, sencillas (QBE, "Query By Example") o Bsquedas Nativas (la manera recomendada para buscar) o Bsquedas usando la "SODA Query API" (bsquedas 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.

Descarga y utilizacin 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 seccin de Community o como en la seccinTestDrive de la pgina 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 ms nos guste. Luego simplemente se importa desde el cdigo 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 seccin 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 continuacin se expone un sencillo ejemplo prctico de utilizacin de db4o hecho en Java. ObjectOrientedDataBase se trata de una clase que encapsula los mtodos 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 tambin hacer tres tipos de bsqueda: 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 implementacin 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 aplicacin 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 actualizacin, primero hay que hacer un get y recin luego, con el (o los) objeto(s) encontrado(s), llamar a set, previa modificacin. Se puede observar una implementacin de actualizacin en el mtodo "actualizar()" de la clase ObjectOrientedDataBase. De la misma forma, para borrar un objeto de la base, primero hay que hacer un get y recin luego, con el (o los) objeto(s) encontrado(s), llamar a delete. Se puede observar una implementacin de borrado en el mtodo "borrar()" de la clase ObjectOrientedDataBase. Para que se tomen todos los cambios de objetos complejos en una actualizacin, hay que setearlo llamando a cascadeOnUpdate(true), dado que por defecto slo se actualizan los atributos del objeto que son de tipos base y los atributos String. Ejemplo:

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

Activation en db40 (Lazy Inicialization)


db4o implementa el concepto de Lazy Inicialization (inicializacin tarda) de una manera muy elegante: se maneja con la activation (activacin) de atributos, con niveles. Por defecto se levantan de la base slo 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 bsicos). 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 mtodo 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 objetos Nodo siguiente = objeto.getSiguiente(); while (siguiente != null) { objectContainer.activate(siguiente, PROFUNDIDAD_DE_ACTIVACION); // esta constante suele ser 1 procesarNodo(siguiente); siguiente = siguiente.getNext(); }

Tambin se puede configurar Db4o para que el nivel de activacin 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 configuracin de la activation a nivel general o por clase o Para una clase en particular:

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

Para toda las clases persistidas:

Db4o.configure().activationDepth(activationDepth)

EJEMPLO
package com.epidataconsulting.epidata.colmena.db.db4o; import java.util.Iterator; import java.util.List; import import import import import com.db4o.Db4o; com.db4o.ObjectContainer; com.db4o.ObjectSet; com.epidataconsulting.epidata.colmena.db.AbstractDataBase; 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 * * @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 } } 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(); } }