Sunteți pe pagina 1din 20

Db4o

Muchasvecescuandosepresentaunartculotantcnico,seloorientahaciaunpblico
especializadooavanzado,yelenfoqueesmostrarlosltimosdetallesdelproductode
turno, sin embargo si hicieramos esto aqu dejaramos afuera a los lectores que
descubren db4o. Tal vez no entenderan cundo ser viable su uso o bien qu es
realmentelograndiosodedb4o.Encambiosielenfoquefueraarranquemosdesde
cero,losdesarrolladoresavanzados,oinclusointermedios,seaburriranydejarande
ladoelartculobuscandolasltimasnovedades.Porellolesrecomiendamosaquienes
estnavanzados,queenelcasodenoresponderasusdudas,consultenhaciaelfinalde
esteartculoendondeseencuentranlasdireccionesURLderecursos,entreelloslosde
lagrancomunidaddeusuariosdedb4o,dondepuedenrealizarconsultasespecficas.
Tanto si usted ha tenido alguna experiencia con bases de objetos (ODBMS), los
conocidoscomomapeadoresobjetosrelacionales(ORDBMS),esdelaviejaguardia
delasbasesrelacionales(RDBMS),comosijamshatenidoexperienciapersistiendo
informacinyquiereaveriguarsidb4oesparausted,creemosqueesteartculopuede
serledeayuda.

Qunoencontraraqu
Laeleccindeunesquemadepersistencia,ancuandodeberasertcnicamenteunade
las cuestiones menos polmicas debido a la enorme cantidad de documentacin y
comparativas realizadas y disponibles pblicamente, ha sido desde hace unos aos
objeto de mltiples controversias. Sin embargo, el objetivo de este artculo no est
centrado en los aspectos netamente comparativos, ni en convencer al lector de
abandonarsupreferenciaporlasbasesrelacionalesoherramientasdemapeo,tareasque
deporsrequerirandeunartculoaparteyciertadisposicinespecialalcambio.La
ideaaquespresentarunvistazoalascaractersticasfundamentalesdedb4o,dejandoa
los lectoreslaposibilidaddegenerar nuevasentregas,ahondandoencuestionesque
considerendesuinters.

Introduccin
Vamosaverentoncesalgunascaractersticasclavesdedb4o,labasedeobjetosnativade
alto rendimiento para .Net y Java. A continuacin mostraremos cmo instalar y
comenzar a utilizar este motor de persistencia. Y seguidamente incluiremos cmo
resolveralgunastareassimplesenC#(muyfcilmenteadaptablesaJava),unapequea
conclusinydaremosfuentesparamsinformacin.
Agrandesrasgos,lascaractersticasfundamentalesdedb4oson:
Alto rendimiento: Ofreciendo notables ventajas con sistemas que utilizan
objetos anidados o compuestos, o en donde existen referencias cruzadas,
herenciaointeraccionesricasentrelosobjetos.

Por su bajo consumo de recursos, (de 600Kb a 800Kb de footprint) es


especialmente apta para dispositivos mviles y entornos Clientes/Servidor,
aunquenonecesariamentelimitadasloaellos.
Doblelicencia:GPL(OpenSource)yComercial(queincluyesoporte).
Grancomunidaddeusuarios.Altonivelderespuestayparticipacin.
Documentacin: Clara, amplia y ordenada. Orientada a ejemplos y de fcil
lectura.
Dosmodosdetrabajo:EmbebidoyCliente/Servidor.
TransparenciaPersistente/ConsultasNativas.
Soportedeversionado.
Portabilidadentre.Net,MonoyJava.
TransaccionesACID:Atomicidad,Consistencia,Aislamiento,Durabilidad.
Clientesdepesoavalansuuso:BMW,Intel,Boeing,Ricoh,Seagate,Bosch,
Novell,etc.

Instalacin
Para empezar a utilizar db4o, es necesario descargar la versin apropiada para su
equipo.Actualmenteexistenversionespara.NET1.xy2.0,paraJavayparaMono.

.NET
Loprimeroquenecesitasaberesquversinde.NETestinstaladaensucomputadora.
Una comprobacin rpida es observar si existe un directorio parecido a
"c:\WINDOWS\Microsoft.NET\Framework\",alldentrodeberatenerunsubdirectorio
conelnmerodeversin(vertablaabajo)porcadaversininstalada.Laversinms
profesionaldeestaverificacinesejecutarelsiguientescript.VBS:
strComputer="."
SetobjWMIService=GetObject("winmgmts:\\"&strComputer&
"\root\cimv2")
SetcolItems=objWMIService.ExecQuery("Select*fromWin32_Product")
ForEachobjItemincolItems
IfInStr(objItem.Name,"Microsoft.NETFramework")>0Then
Wscript.EchoobjItem.Version
EndIf
Next

*Deberaapareceruncuadrodedilogoporcadaversininstalada.

Sinohaactualizadoelframework.NETseparadamente,lasiguientetablapuededarle
unaideadelaversininstaladaensuequipo:
VisualStudio.NET NombredeVersin
2002
1.0Beta1
2002
1.0Beta2

Nmerodeversin
1.0.????.0
1.0.2914.0

2002
2002
2002
2002
2003
2003
2003*
2005
2005

1.0RTM
1.0SP1
1.0SP2
1.0SP3
1.1RTM
1.1SP1
1.1SP1
2.0Beta1
2.0RTM
3.0RTM

1.0.3705.0
1.0.3705.209
1.0.3705.288
1.0.3705.6018
1.1.4322.573
1.1.4322.2032
1.1.4322.2300
2.0.40607
2.0.50727.42
3.0.4506.30

*=(WindowsServer2003Version)

Si tienevarias versionesde.NETinstaladas,esposibleespecificarconqu versin


deseautilizardb4oeditandounarchivodeconfiguracindelaaplicacin[1](quenoes
msqueunXMLconextensin.config),sinembargoestonoesnecesarioyaquepor
omisindb4otomarlaltimaversinde.Netinstalada.
LadistribucindeDb4opara.NETconsisteenunarchivoinstaladorMSI,porloque
debertenerhabilitadoelservicio"WindowsInstaller"parapoderinstalarlo.Ingreseen
la "Consola de administracin de Microsoft" escribiendo services.msc en Inicio >
Ejecutarparapoderhabilitarlosinoestyahabilitado.

Java
ParaempezarsedebetenerinstaladalamquinavirtualJavadeSun(JRE).Porelusode
los generics ymejorasenlaejecucindel for,serecomiendautilizarJava5.0enlo
posible.Db4otambincorresobrelamquinavirtualJavadeMicrosoft,paralacualse
debeutilizarJDK1.1apartirdelaversin6.1deDb4o.
Db4opuedeejecutarsesobrelasplataformasJavaJ2EE,J2SEydialectosJ2MEque
soporten reflexin computacional como CDC, PersonalProfile, Symbian, Savaje y
Zaurus.EstplaneadoelsoportesobredialectossinreflexincomoCLDC,PalmOSy
RIM/Blackberry.
LadistribucinparaJavavieneenformatoZIPquedebemosextraerendondecreamos
conveniente.

Lenguajes
LasiguientetablapresentaloslenguajesyentornossoportadosporDb4o:
Lenguaje/Entorno
C#
Java(JRE)
Java(J#)
VisualBasic.Net
Delphi.NET
C++
Ruby(JRuby)

Soporte
S
S
S
S
S
Administrado(C++/CLI)
Vareflector

Python(IronPython)
Python(Jython)
Boo
ASP.NET
CompactFramework

S
Vareflector
S
S
S

Configuracin
Suficientehastaaquconcuestionesdeinstalacin.Db4oposeedosmodosdetrabajo:
EmbebidoyCliente/Servidor.Alospropsitosdeesteartculosoloveremoselprimer
modo,dejandoafuturasrevisioneselmodocliente/servidor.
Parapoderdistribuiraplicacionescondb4o,slonecesitacopiarunalibrera(.dll)muy
pequeayconfiguraralgunascosasensuentornodedesarrollopreferido(ademsde
escribirelcdigonecesariodesdeluego!).

VisualStudio.NET2005
Estossonlospasosparacomenzaradesarrollarcondb4o6.0bajoesteentorno:
1. Agregarlareferenciadeladllennuestroproyectohaciendoclickconelbotn
derechosobreReferencesenelSolutionExplorer.
2. ElegirAddReferenceyluegoBrowse
3. Seleccionardb4o.dll,OpenyfinalmenteOk
Y listo. No es necesaria la administracin de la base de objetos. Los pasos de
configuracinsonsimilaresparaelentornoSharpDevelop

Eclipse
Slohayqueagregarlasreferenciasal.jarcorrespondientealentornodetrabajo.
1. Abrirlaspropiedadesdelproyectohaciendoclickconelbotnderechosobreel
proyectoenelPackageExploreryseleccionandoProperties.
2. SeleccionarJavaBuildPathyhacerclicksobrelapestaaLibraries.
3. AgregarelJARcorrespondientehaciendoclickenelbotnAddExternalJARsy
navegandohastaencontrarelJARparalaversindeJavaqueestutilizando.

Ejemplo:TiendaderentadeDVDs
Vamosatrabajarconunejemplotpico.Supongamosunclientequehaceunalquileren
nuestratiendaderentadeDVDs.Amododeejemploinstanciemosunapelculaysu
respectivacopiafsicadelDVDennuestrosistema,yposteriormenteunnuevoalquiler
delcliente,asociandolainformacincorrespondiente.Grficamentenuestrasinstancias
quedaranas:

Porahora,supongamostambinqueparaelsiguientecdigodeejemplotenemosun
objetodbsobreelcualsepuedenrealizardosoperaciones,Set()yCommit(),que
persistenlos datos.Elcdigoque generaranuestrasinstanciasseraalgocomolo
siguiente:

Java
//Creamosunanuevapelcula
PeliculaunaPelicula=newPelicula("TheGodfather",FrancisFord
Coppola);
//Creamosunnuevacopiafsicaparalapelcula
//yasociamoslapelculaalacopiafsica
DvdcopiaDVD=newDvd(5,unaPelicula);
//Alquilerpor2das
Alquileralquiler=newAlquiler("JuanPerez",copiaDVD,2);
//Finalmentealmacenamoselalquiler
db.set(alquiler);
db.commit();
(ElproyectoquepruebaesteScriptsellamaConsoleApplicatioDb4oTestSimpleScriptJAVA)

C#
//Creamosunanuevapelcula
PeliculaunaPelicula=newPelicula("TheGodfather",FrancisFord
Coppola);
//Creamosunnuevacopiafsicaparalapelcula
//yasociamoslapelculaalacopiafsica
DvdcopiaDVD=newDvd(5,unaPelicula);
//Alquilerpor2das
Alquileralquiler=newAlquiler("JuanPerez",copiaDVD,2);
//Finalmentealmacenamoselalquiler
db.Set(alquiler);
db.Commit();
(ElproyectoquepruebaesteScriptsellamaConsoleApplicatioDb4oTestSimpleScriptCS)

Sinuncatrabajconbasesdeobjetosesimportantequetengaencuentalosiguiente:En
Db4o,lasreferenciasalosobjetosespecificanla relacin entreellos,porlotantoen
nuestroejemplo,lapelcula(unaPelicula)ylacopiafsica(copiaDVD)sonalmacenados
implcitamente al hacer db.Set(alquiler). El db.Commit() finalmente cierra la
transaccin.Esfundamentalquerecuerdeestaespeciedeprincipioquedeterminael
funcionamientodelasbasesdeobjetos.
Hasta aqu podemos sacar varias conclusiones. Como observamos, con db4o no es
necesariocrearunesquemadepersistencia,esdecir,nohayquehacereldiseodela
basededatosyaqueeselmodelodeclasesdenuestrosistemaloquesepersiste.Esto
nosliberadevariascosas,entreellas,elusodeherramientasdeadministracindebase
dedatos,unadministradordebasededatos,ydeposeerconocimientosbasesdedatos
relacionales(lgebrarelacional,SQL),entreotrastareas.
Paralossiguientesejemplos,puedesertilirinspeccionandolabasemientrassetrabaja
con ella. Db4o posee un explorador con el cual podemos navegar nuestras bases y
realizarcopiasdeseguridad,defragmentaciones,consultas,etc.EstesellamaObject
Manager,ysepuededescargardesdeelCentrodeDescargasdeDb4o(verseccinde

enlaces).Enlaseccindeherramientasdeesteartculoincluimosunlistadodeotras
utilidadesparadb4o.DesdeelObjectManagerentonces,nuestroalquilerrecientemente
almacenadoenlabase,severadelasiguientemanera:

Haciendoclickenelconodelrboldecadatem,semuestraunavistajerrquicadelitemseleccionado.

ParapoderejecutarelObjectManager,debertenerinstaladaunamquinavirtualJava
ensusistema(porejemploelllamadoJavaRuntimeEnvironmentoJRE).Laforma
correctadeejecucinentoncesesllamandoalarchivoporlotes(.bat)queseencuentra

dentrodelacarpetadelObjectManageryeselencargadodeinstanciarelappletdeJava
(.jar).

Entornodetrabajo
EnelCDseencuentrandosproyectosparaVisualStudio:unoqueincluyeaccesovaS.O.D.A.yotro
medianteConsultasNativas,temasquetrataremosacontinuacin.Ambosproyectosestn alaXP,es
decir,seincluyentestsNunitparaverificarsucorrectofuncionamiento.

En principio hagamos algunas consultas muy simples sobre Pelicula, a fin de


familiarizarnos con el acceso a db4o, y luego nos moveremos a algunas ms
interesantes.
TrabajaremosconC#yJavaquesonloslenguajesmspopularesenlacomunidadde
db4o.Enamboscasos,primerodeberincluirlasrutasnecesariasparaqueelenlazador
encuentrelosmtodos:
Java
importcom.db4o.Db4o;
importcom.db4o.Query;

C#

usingDb4objects.Db4o;
usingDb4objects.Db4o.Query;

LaAPIdedb4oessimilarentodosloslenguajessoportados.Usualmentelaformade
trabajoessimilaralsiguientemolde:
Java
//Crearunabasesinoexiste,abrirlasiyaexiste.
Filefile=newFile("testDb4o.yap");
StringfullPath=file.getAbsolutePath();
ObjectContainerdb=Db4oFactory.openFile(file);
try
{
//realizaralgunaaccincondb4o
//Ejemplos:
db.set(obj);
//Almacenaunobjetoenlabase
db.commit(); //Realizarlatransaccin(yarrancarotra)
db.delete(obj);//Eliminarunobjetoenlabase
}
finally
{
db.close();//Cerrarlabaseyliberarlosrecursos
}

C#

//Crearunabasesinoexiste,abrirlasiyaexiste.
IObjectContainerdb=Db4oFactory.OpenFile("testDb4o.yap");
try
{
//realizaralgunaaccincondb4o

//Ejemplos:
db.Set(obj);
//Almacenaunobjetoenlabase
db.Commit(); //Realizarlatransaccin(yarrancarotra)
db.Delete(obj);//Eliminarunobjetoenlabase
}
finally
{
db.Close();//Cerrarlabaseyliberarlosrecursos
}

LabasedeobjetosconstadeunarchivodenominadoYAP,endondesealmacenarnlos
objetosserializados.AniveldeaplicacinselollamaObjectContaineryeselobjeto
sobreelcualserealizarnlasoperacionesdepersistencia(Set(),Get(),Commit(),etc.).
Enlosejemplosacontinuacin,asumiremosqueelcdigoseejecutadentrodelbloque
try{},yestnincluidoslosespaciosdenombrescitadosarribaafindequese
encuentrenlasfuncionesnecesarias.

AccesoaDb4o
AntesdeverlasformasdeaccesoadatosenDb4o,vamosaponernosunpocoen
contexto:Elaccesoalosdatosenunabasedeobjetosesnavigacional.Laeficienciaen
velocidad(unadelascaractersticasnotablesdedb4o)vienedadaporelhechodeque
las referenciassonalmacenadasdirectamenteencadainstancia,mientrasqueenlas
bases de datos tradicionales (que fueron realizadas antes de que el mecanismo de
herenciafueraampliamenteutilizado),elaccesoestabular,yloquegeneralmentese
intentaenestoscasosparasalvarladistanciaconelmundodeobjetos,esutilizar
mapeadoresObjetoRelacionales,queincluyenAPIsolenguajesquedanlailusinde
trabajarconobjetos.
Endb4oexistentresformasderealizarconsultas,cadaunabasadaenunatecnologa
diferente.Estasson:

S.O.D.A.:SimpleObjectDatabaseAccess/AccesoSimpleaBasesdeDatosdeObjetos.
Q.B.E.:QueryByExample/ConsultaporEjemplooPlantilla.
N.Q.:NativeQueries/ConsultasNativas

Enunprincipio,db4opermitaaccedermedianteQ.B.E.yS.O.D.A.[2],siendoesta
ltimalainterfacepreferidaporserunatecnologadesarrolladaporelmismocreador
dedb4o,CarlRosenberg.Laexperienciatomadaconlosusuariosduranteelperodo
2003 2005 ha valido para dar cuenta de sus limitaciones y proponer una nueva
tecnologadeaccesoadatospersistidos,quesuplieraconestaslimitaciones.Apartirde
la versin 6 de db4o, las Consultas Nativas (N.Q.) se convirtieron en la interface
principal de acceso, mientras que S.O.D.A. se ha mantenido por cuestiones de
compatibilidadyparael usode consultasgeneradas dinmicamente.A pesar desu
recienteinclusinendb4o,lasideadetrsdelasConsultasNativasnosonunconcepto
nuevo;lascoleccionesdeSmalltalkyaincluanestacapacidaddesdesuespecificacin
en1983.Veamoscualessonsusventajasydesventajasprincipales:

Tecnologa
QBE

Ventajas

Simplicidad,recomendada
paraprincipiantes.

Desventajas

SODA

NQs

Independenciadellenguaje
deprogramacinutilizado.
APIsimple.Minimizael
usodecadenaspara
consultas
Operasobrepropiedades
Introduceconceptos
relacionadoscongrafosde
nodos(naturalalasbasesde
objetos):Descendery
Restringirpornodosque
puedenserunaomuchas
clases,unatributodeuna
clase,oconsultasmismas.

Interfacerecomendadapara
Db4o
100%seguraentipos:
Verificacindeerrores
semnticosysintcticosen
tiempodecompilacin.
100%refactorizable
100%nativas:nohay
necesidaddeaprender
lenguajesdeconsultaso
APIs

Funcionalidadeslimitadas:Carecede
consultasconjuntores(AND,NOT,
OR,etc).
Senecesitaagregarunconstructor
paracrearobjetossincampos
inicializados.
Nosepuedeconsultarporvalores
nulos
Noseverificantiposentiempode
compilacin
(query.Descend(dirctor)fallaraen
tiempodeejecucin)
Demasiadoexplcita(verbose).
Operasobrecampos,
(pelicula._director)envezde
propiedades(pelicula.getDirector()o
pelicula.Director)
Requiereactualizarlasconsultas
cuandoserefactorizaomodificael
modelodeclases.
Consultasbasadasencadenas
embebidassonblancoparaataques
vainyeccindecdigo.
Lasconsultasdebensertraducidasal
lenguajeoAPIdelmotor,estopuede
penalizarenrendimientoenelcaso
deconsultascomplejas,dondenoes
posiblehacerlosininstanciaralgunos
objetospersistidos.

AccesomedianteS.O.D.A.(SimpleObjectDatabaseAccess):
Altrabajarcondb4o,debemosimaginarnuestrosdatoscomoenungrafoenelque
podemosnavegar(oconsultar),adiferenciadeloqueharamosconunabaserelacional
dondelosdatosestntabuladosylaideapredominanteescombinarresultadosentablas.
ElaccesoconS.O.D.A.serealizamediantelaclaseQuery,queesobtenidaatravsdel
ObjectContainer.Consideremosalgunasoperacionestpicas:
Java

//Instanciamosunobjetoquerypararealizarlasconsultas
Queryquery=db.query();
//Indicamoselobjetocontraelcualserealizarlaconsulta
query.constrain(Pelicula.class);

////////////////////////////////////////////////////////////////
//Configuramosla/sconsulta/senelobjetoquery
////////////////////////////////////////////////////////////////
//Pordatoparticular:Recuperemosla(s)Pelicula(s)llamada(s)
//ElPadrinosiexiste(n).
query.descend("nombre").constrain("ElPadrino");
//Pornegacin:Recuperarlaspelculasquenosellamen
//ElPadrinosiexisten.
query.descend("nombre").constrain("ElPadrino").not();
//Porconjuncin:RecuperarlaspelculasllamadasElPadrinoy
//cuyodirectorseaFrancisFordCoppola
Constraintconstr=query.descend("nombre").constrain("ElPadrino");
query.descend("director").constrain(FrancisFordCoppola).and(constr);

//Pordisyuncin:RecuperarlaspelculasllamadasElPadrinoo
//cuyodirectorsellameFrancisFordCoppola
Constraintconstr=query.descend("nombre").constrain("ElPadrino");
query.descend("director").constrain(FrancisFordCoppola).or(constr);

//Porsimilitud:RecuperarlaspelculasquecontenganGodensuttulo
IConstraintconstr=query.descend("nombre").constrain("God").like();

//Ordenandoresultadosdeformaascendente
query.descend("nombre").orderAscending();
//Ordenandoresultadosdeformadescendente
query.descend("nombre").orderDescending();
//EjecutarlaconsultayMostrarlosresultados
ObjectSetresult=query.execute();
listResult(result);

C#
//Instanciamosunobjetoquerypararealizarlasconsultas
Queryquery=db.Query();
//Indicamoselobjetocontraelcualserealizarlaconsulta
query.Constrain(typeof(Pelicula));
////////////////////////////////////////////////////////////////
//Configuramosla/sconsulta/senelobjetoquery
////////////////////////////////////////////////////////////////
//Pordatoparticular:Recuperemosla(s)Pelicula(s)llamada(s)
//ElPadrinosiexiste(n).
query.Descend("_nombre").Constrain("ElPadrino");
//Pornegacin:Recuperarlaspelculasquenosellamen
//ElPadrinosiexisten.
query.Descend("_nombre").Constrain("ElPadrino").Not();
//Porconjuncin:RecuperarlaspelculasllamadasElPadrinoy
//cuyodirectorseaFrancisFordCoppola
Constraintconstr=query.Descend("_nombre").Constrain("ElPadrino");
query.Descend("_director").Constrain(FrancisFordCoppola).And(constr);

//Pordisyuncin:RecuperarlaspelculasllamadasElPadrinoo

//cuyodirectorsellameFrancisFordCoppola
Constraintconstr=query.Descend("_nombre").Constrain("ElPadrino");
query.Descend("_director").Constrain(FrancisFordCoppola).Or(constr);

//Porsimilitud:RecuperarlaspelculasquecontenganGodensuttulo
IConstraintconstr=query.Descend("_nombre").Constrain("God").Like();

//Ordenandoresultadosdeformaascendente
query.Descend("_nombre").OrderAscending();
//Ordenandoresultadosdeformadescendente
query.Descend("_nombre").OrderDescending();
//EjecutarlaconsultayMostrarlosresultados
ObjectSetresult=query.Execute();
listResult(result);

Observamosenlosejemplospreviosquemedianteunaconsultasedesciendeporlos
nodosespecificandounatributo.Estosnodospuedenreferiratantotiposprimitivos
comoStringenlosejemplosde_nombreo_director,obienreferiraotrosobjetosde
nuestraaplicacin,comoveremosadelanteenelejemplodeaccesoaobjetosanidados.
Finalmente,serestringeporeldatoquequeremosconsultar("ElPadrino",Stanley
Kubrick,Pelicula,DVD,etc).Observemosquelasrestriccionessedanendoslugares:
Al comienzo, cuando especificamos la clase de lo que queremos obtener
(query.Constrain(typeof(Pelicula)))yalfinalmismo(Constrain(FrancisFord
Coppola)).

Asuvez,estasrestricciones(Constraints),sepuedencombinarmediantejuntores(Or,
And, Not) y operadores de comparacin (Equal, Identity, Like, Contains, Smaller,
Greater,etc).
Por lo tanto, descender y restringir son bsicamente las ideas principales con
S.O.D.A.. Descender por una consulta da como resultado otra consulta, a la cual
podemosdescendernuevamenteyrealizarlarestriccinquenosinterese:
Java
//Accesoaobjetosanidados
query.constrain(Alquiler.class);
query.descend("copiaFisica").descend("pelicula").constrain(nombre);

C#
//Accesoaobjetosanidados
query.Constrain(typeof(Alquiler));
query.Descend("copiaFisica").Descend("pelicula").Constrain(_nombre);

Aqu restringimosporAlquiler,descendimosdosnivelespor copiaFisicaypelicula,


paraluegorestringirpornombre.
Estaideadedescenso,conllevadeporslaideadeprofundidad.Veamosuncasoen
dondelaprofundidadesimportante,laactualizacindeobjetos.Pongamosporejemplo
quedeseamosactualizarunaPelcula:
Java

//Obtenemosunapelculautilizandounprototipo
1.Queryquery=db.query();
2.ObjectSetresult=db.get(newPelicula("EllaberintodelFauno"));
3.Peliculafound=(Pelicula)result.next();
//Actualizareldirector
4.found.director=GuillermodelToro;
5.db.set(found);
//Mostrarresultados
6.Result=db.get(newPelicula("EllaberintodelFauno"));
7.listResult(result);

C#
//Obtenemosunapelculautilizandounprototipo
1.Queryquery=db.Query();
2.ObjectSetresult=db.Get(newPelicula("EllaberintodelFauno"));
3.Peliculafound=(Pelicula)result.Next();
//Actualizareldirector
4.found.Director=GuillermodelToro;
5.db.Set(found);
//Mostrarresultados
6.Result=db.Get(newPelicula("EllaberintodelFauno"));
7.listResult(result);

Observamosunaformaalternativaderecuperarunobjeto,especificandounprototipo,el
equivalentedelaslneas2y3sinprototipossera:
C#
1.Queryquery=db.Query();
2.query.Constrain(typeof(Pelicula));
3.query.Descend("_name").Constrain("EllaberintodelFauno");
ObjectSetresult=query.Execute();

Java
1.Queryquery=db.query();
2.query.constrain(Pelicula.class);
3.query.descend("name").constrain("EllaberintodelFauno");
ObjectSetresult=query.execute();

Volviendoalacuestindelaprofundidad:Poromisin,sloseactualizarelobjeto
pasadocomoparmetroalmtodoSet(),esdecir,losmiembrosprimitivosdeeseobjeto,
porellolaprofundidaddeactualizacin(updatedepth)seriguala1.Esimportante
recordarlo ya que en general un modelo de objetos medianamente complejo
seguramenteutilizarmsdeunniveldecontencindeobjetosquenosonprimitivos.
Siquisiramosactualizarlosobjetosmiembros,esdecir,aquellosqueestnasociadosa
unobjeto,debemosconfigurarelobjetorazencuestinparaqueactualiceelgrafoala
profundidaddeseada.
Java

//ActualizarelgrafocompletodeobjetosdesdePelicula
Db4o.configure().objectClass(Pelicula.class).cascadeOnUpdate(true);

C#

//ActualizarelgrafocompletodeobjetosdesdePelicula
Db4o.Configure().ObjectClass(typeof(Pelicula)).CascadeOnUpdate(true);

Engeneralesconvenienterealizarunplandeactualizacindetalformaquealejecutar
lasconsultas,sloserecuperenaquellosobjetosquenecesitenactualizarseynoms,a
findenopenalizarenvelocidaddeacceso.

AccesomedianteConsultasNativas(NQs):
Comovimos,unabasedeobjetosendb4osecreamediantecdigoescritoenelmismo
lenguajededesarrollodelaaplicacin(C#,Java,VisualBasic,etc.),porloquenoes
necesario aprender otros lenguajes como SQL, HQL de Hibernate, OQL, JDOQL,
EJBQL,oSODA(ademsdellenguajededesarrolloelegido)parapersistirnuestros
datos. Estacaractersticaes llamada TransparenciaPersistente,"NativeQueries" o
simplementeNQs,yestmarcandounatendenciaentrelosusuariosdeDb4o. An
cuandoconsiderequeelusooaprendizajedeotrolenguajenoesrealmenterelevante,
existeotragrandificultadconloslenguajesdeconsultas,yesqueestnbasadosen
cadenas.Estascadenasdebenseranalizadaslxicamenteysintcticamenteporelparser
del motor de persistencia, esto desde ya aade tiempo y es un proceso propenso a
errores.S.O.D.Aincluso,queminimizaelusodecadenas,tambintieneladificultadde
queelcompiladornopuedeverificarlavalidezdelatributodeunaclase.
Sinembargo,internamente,lasConsultasNativasfuncionansobreS.O.D.A.,porloque
existeunconversoryunoptimizadordeconsultasllamadoNativeQueryOptimizer
paramaximizarsurendimiento.
Enconcreto,laideatrasNQsesposibilitarlaformamssimpleposiblederealizaruna
consulta.Estaformamssimpletrabajaraconunainstanciaprototpica,esdecir,una
creada como si fuera un ejemplo, pero que representa a todas las de su tipo.
Naturalmenteestoseraalgotansimplecomo:
Java

//ObtenerlaspelculasquecontienenlacadenaPadrino
Pelicula.getNombre().contains(Padrino);

C#

//ObtenerlaspelculasquecontienenlacadenaPadrino
Pelicula.Nombre.Contains(Padrino);

Siempretenemosquetenerencuentaqueloprincipaldelaconsultaesestaexpresin,
querealizalaaccinquenosinteresa.Apartirdeaquenadelanteloqueveremosesde
algnmodo,cmoconformaracadacompiladoryalmotordeDb4oparaqueacepten
estaexpresindelaformamssimpleposible.Estonoesfundamental,nitampocoes
complejo,perosesnecesarioaprenderloparapoderutilizarConsultasNativas.
Paraqueestofuncioneentonces,loprimeroquenecesitaramosesespecificarleeltipo
de esta instancia prototpica (pelcula) a la expresin sobre la cual realizamos la
consulta,ydevolverlosresultadosenalgntipodecontenedor.Algocomo:

Java

//ObtenerlaspelculasquecontienenlacadenaPadrino
(Peliculapelicula){
returnpelicula.getNombre().contains(Padrino);
}

C#

//ObtenerlaspelculasquecontienenlacadenaPadrino
(Peliculapelicula){
returnpelicula.Nombre.Contains(Padrino);
}

Laprximacaractersticaaagregaralaexpresinnecesitaunaintroduccin.Haceun
instante mencionamos que, internamente, db4o realiza un proceso de anlisis,
conversin y posible optimizacin sobre las consultas. Esto agrega un nuevo
requerimientoanuestraexpresin,quedeberaserdetalformaquepuedapasarsecomo
parmetroalmotordelabasedeobjetos,uotroprocesadordeconsultas,yaspoderser
modificada.
Siemprepriorizandolasimplicidadsintctica,necesitaramosentoncesunobjetoque
puedareferenciarunaespeciedemtodoannimoqueseausadocomoparmetroy
seamodificable,yaseabienoptimizndoseosimplementetraducindoseaSODA.Esto
esposibleapartirde.NET2.0utilizandolosllamadosdelegados.Undelegadoescomo
unparobjetomtodoquefuncionacomounaretrollamada(callback),ysirveparatratar
aunmtodocomounobjetodeprimeraclase,yaspasarsecomoparmetroaotros
mtodos. Los delegados son muy usados en el mundo de .NET para realizar
notificacionesdeeventos,ejecucionesencadenadasyalgunosotroscasosenlosquese
necesitereflexincomputacional.
En Java 1.2 1.4y 5.0,es posible emular este comportamiento utilizandola clase
Predicate comounaclaseannima,yescribiendoenunmtodo match laexpresin
dentrodeella,undetallequelerestasimplicidadencomparacinconlaversindeC#.
EnelcasoparticulardeJava5.0,sepuedehacerusodelos generics.Encdigoesto
sera:
Java
//ObtenerlaspelculasquecontienenlacadenaPadrino
newPredicate(){
publicbooleanmatch(Peliculapelicula){
returnpelicula.getNombre().contains(Padrino);
}

C#

//ObtenerlaspelculasquecontienenlacadenaPadrino
delegate(Peliculapelicula){
returnpelicula.Nombre.Contains(Padrino);
}

LamentablementelasintaxisparadefinirmtodosannimosenC#yJavaanesalgo
excesiva(estotalvezcambieenelfuturoconversionesposterioresdeloslenguajes),en
comparacinconsusdefinicionesequivalentesenotroslenguajes,porejemplolas
expresioneslambdaenHaskellolosCompiledMethodsobloquesdeSmalltalk.Anas

peseaestadesventaja,ennuestraopinin,suusoesrecomendableconsiderandosus
contrapartes en lenguajes como SQL o lenguajes de consultas basadas en cadenas,
propensos a errores de tipeo, dificultades para depuracin, y a utilizar cientos de
palabrasclaves.Existentambinalgunasventajasadicionalescomolaposibilidadde
realizarconsultasdinmicasyparametrizadas,temasquepodrantratarseenfuturos
artculos.
Volviendoanuestraexpresin,finalmenteagregamoselcontenedorparalosresultados,
quedando:
Java5.0
List<Pelicula>peliculas=database.query<Pelicula>(
newPredicate<Pelicula>(){
publicbooleanmatch(Peliculapelicula){
returnpelicula.getNombre().contains(ElPadrino);
}
});

Java1.21.4
Listpeliculas=database.query(
newPredicate(){
publicbooleanmatch(Peliculapelicula){
returnpelicula.getNombre().contains(ElPadrino);
}
});

C#.NET2.0

IList<Pelicula>peliculas=db.Query<Pelicula>(
delegate(Peliculapelicula){
returnpelicula.Nombre.Contains(ElPadrino);
});

C#.NET1.1

IList<Pelicula>peliculas=db.Query(newPeliculaQuery());
PublicclassPeliculaQuery:Predicate
{
Publicbooleanmatch(Peliculapelicula){
returnpelicula.Nombre.Contains(ElPadrino);
}
};

VamosahoraareescribirnuestrasconsultasS.O.D.A,alaConsultasNativas:
Java
//Consultapordatoparticular:Recuperarla(s)Pelicula(s)
//llamada(s)ElPadrinosiexiste(n).
List<Pelicula>peliculas=this.db.query(newPredicate<Pelicula>(){
publicbooleanmatch(Peliculapelicula){
returnpelicula.get_nombre().equals(ElPadrino);
}});
//Pornegacin:Recuperarlaspelculasquenosellamen
//ElPadrinosiexisten.

List<Pelicula>peliculas=this.db.query(newPredicate<Pelicula>(){
publicbooleanmatch(Peliculapelicula){

return!pelicula.get_nombre().equals(ElPadrino);
}});
//Porconjuncin:RecuperarlaspelculasllamadasElPadrinoy
//cuyodirectorseaFrancisFordCoppola
List<Pelicula>peliculas=this.db.query(newPredicate<Pelicula>
(){
publicbooleanmatch(Peliculapelicula){
returnpelicula.get_nombre().equals(ElPadrino)&&
pelicula.get_director().equals(FrancisFordCoppola);
}});
//Pordisyuncin:RecuperarlaspelculasllamadasElPadrinoo
//cuyodirectorsellameStanleyKubrick
List<Pelicula>peliculas=this.db.query(newPredicate<Pelicula>(){
publicbooleanmatch(Peliculapelicula){
returnpelicula.get_nombre().equals(ElPadrino)||
pelicula.get_director().equals(StanleyKubrick);

}});
//Porsimilitud:RecuperarlaspelculasquecontenganGodensuttulo

List<Pelicula>peliculas=this.db.query(newPredicate<Pelicula>(){
publicbooleanmatch(Peliculapelicula){
returnpelicula.get_nombre().contains("God");
}});
//Ordenacin:Alfabticamentepornombreespecificandouncriterio
//decomparacinconundelegadoannimo
Comparator<Pelicula>peliculaCmp=newComparator<Pelicula>(){
publicintcompare(Peliculapel1,Peliculapel2){

returnpel1.get_nombre().compareTo(pel2.get_nombre());
}
};

List<Pelicula>peliculas=this.db.query(newPredicate<Pelicula>(){
publicbooleanmatch(Peliculapelicula){
returntrue;
}
},peliculaCmp);

C#
//Consultapordatoparticular:Recuperarla(s)Pelicula(s)
//llamada(s)ElPadrinosiexiste(n).
IList<Pelicula>peliculas=db.Query<Pelicula>(delegate(Pelicula
peliculaDb){
returnpeliculaDb.Nombre(ElPadrino);
});
//Pornegacin:Recuperarlaspelculasquenosellamen
//ElPadrinosiexisten.
IList<Pelicula>peliculas=db.Query<Pelicula>(delegate(Pelicula
peliculaDb){
returnpeliculaDb.Nombre(ElPadrino);

});
//Porconjuncin:RecuperarlaspelculasllamadasElPadrinoy
//cuyodirectorseaFrancisFordCoppola
IList<Pelicula>peliculas=db.Query<Pelicula>(delegate(Pelicula
peliculaDb){
return(peliculaDb.Nombre==ElPadrino)&
(peliculaDb.Director==FrancisFordCoppola);});
//Pordisyuncin:RecuperarlaspelculasllamadasElPadrinoo
//cuyodirectorsellameStanleyKubrick
IList<Pelicula>peliculas=db.Query<Pelicula>(delegate(Pelicula
peliculaDb){
return(peliculaDb.Nombre==ElPadrino)|
(peliculaDb.Director==StanleyKubrick);});
//Porsimilitud:RecuperarlaspelculasquecontenganGodensuttulo

IList<Pelicula>peliculas=db.Query<Pelicula>(delegate(Pelicula
peliculaDb){
return(peliculaDb.Nombre.Contains==God);});
//Ordenacin:Alfabticamentepornombreespecificandouncriteriode
//comparacinconundelegadoannimo

Comparison<Pelicula>peliculaCmp=new
Comparison<Pelicula>(delegate(Peliculap1,Peliculap2)
{
returnp2.Nombre.CompareTo(p1.Nombre);
});

IList<Pelicula>peliculas=db.Query<Pelicula>
(delegate(PeliculapeliculaDb){returntrue;},peliculaCmp);

Debidoalasventajasmencionadasanteriormente,existedentrodelacomunidadDb4o
unamarcadatendenciahacialasConsultasNativasapesardesurecientenovedadenel
mundo de desarrolladores Java y .Net. Una forma conveniente de acostumbrarse al
trabajoconConsultasNativasesprimeroescribirlaexpresindelaconsulta,luego
agregar la coleccindevuelta, yfinalmente encabezado correspondiente al delegado
paraC#oelpredicadoenelcasodeJava,quesuelentenerunaformamssimilarentre
todasellas.
MuchosdesarrolladoresconfiguranyutilizanunosarchivosenformatoXMLllamados
snippets en VisualStudio o templates en Eclipse, que insertan el texto reusable en
nuevoscontextosoaplicaciones(boilerplates)ypuedenserdeespecialutilidadenestos
casos.

Herramientas
Existen algunas herramientas y conectores (plugins) adicionales interesantes,
descargablesdesdeelCentrodeDescargasdeDb4o:

ObjectManagerGUIAdministrationTool:EsunainterfacegrficarealizadaenJava
paramanipularbasesDb4o.
db4o Replication System (dRS): Es una herramienta de compatibilidad basada en
Hibernate(unframeworkdepersistenciaydemapeoobjetorelacionalmuypopular)
quepermitereplicardatosdesdedb4ohaciadb4ooalgnRDBMS,obiendesdeun
RDBMShaciadb4o.
Db4o.Binding.NET: Incluye clases para trabajo con listas en memoria y enlace de
resultados de consultas con controles de Windows Forms y Windows Presentation
Forms(parcialmente).Soportaconsultas,filtros,ordenacin,paginacin,etc.
Db4oEclipse:PlugindocumentadoparaEclipseconaccionespararealizarcopiasde
resguardo,defragmentacin,etc.

Conclusin
Tal vez le haya sorprendido lo poco que hay que aprender con db4o. En la jerga
acadmicaestosellamagapsemntico,loquesignificaenpocaspalabras,esqueel
uso de la tecnologa de objetos (T.O.) est ms cerca del lenguaje naturalde los
humanos,porelsimplehechodequerequierequeustedconozcamenoscuestiones
relacionadasconlamquinaens.Estopermitealosdesarrolladoresconcentrarsems
enelproblemaaresolver,elllamadodominiodelsistema,envezdeinvertirtiempoen
cuestionespropiasdelatecnologaelegida.

Enlaces
Sitio
http://www.db4o.com/espanol(condocumentacinencastellano)
Foro
http://developer.db4o.com/forums/15/ShowForum.aspx(parainteractuarconla
comunidad)
Wiki
http://developer.db4o.com/ProjectSpaces/view.aspx/Espanol(unespaciowebgratuitode
trabajocomunitarioencastellano)
Blog
http://developer.db4o.com/blogs/espanol/default.aspx(paraanunciosynoticias)
CentrodeDescargas:
http://developer.db4o.com/files
DescargasdelaComunidadHispana
http://developer.db4o.com/files/folders/spanish/default.aspx

Referencias

[1]Cmo:Utilizarelarchivodeconfiguracindeunaaplicacinparadeterminarla
versin de .NET Framework que se va a usar: http://msdn2.microsoft.com/es
es/library/9w519wzk(VS.80).aspx
[3]SitiodeS.O.D.A.http://sodaquery.sourceforge.net
[2]DavidTaylor.ObjectTechnology.EditorialAddisonWesley(2daEd.1997)captulo
6.
[3]WilliamR.Cook,CarlRosenberg.NativeQueriesforPersistentObjects.ADesign
WhitePaper.NationalScienceFundation(15defebrerode2006).
[4]AdeleGoldberg,D.Robson.Smalltalk80:theLanguageandItsImplementation.
EditorialAddisonWesley(1983).
[5]JRETest(verificarsiestinstaladayfuncionallamquinavirtualdeJavadeSun)
http://java.com/en/download/help/testvm.xml
[6]MquinaVirtualdeJavadeSun:http://developers.sun.com/downloads/top.jsp
[7]JimPaterson,StefanEdlich,HenrikHorning,ReidarHorning.Thedefinitiveguide
toDb4o.Apress(2006).

S-ar putea să vă placă și