{"id":1394,"date":"2013-07-12T10:58:46","date_gmt":"2013-07-12T08:58:46","guid":{"rendered":"https:\/\/inlab.fib.upc.edu\/?p=1394"},"modified":"2013-07-12T10:58:46","modified_gmt":"2013-07-12T08:58:46","slug":"implementando-bases-de-datos-orientadas-objetos","status":"publish","type":"post","link":"https:\/\/inlab.fib.upc.edu\/es\/uncategorized-ca\/implementando-bases-de-datos-orientadas-objetos","title":{"rendered":"Implementando Bases de Datos Orientadas a Objetos"},"content":{"rendered":"<p>En la l&iacute;nea de les metodolog&iacute;as &aacute;giles y la innovaci&oacute;n en modelos de bases de datos, la incorporaci&oacute;n de una base de datos orientada a objetos en un nuevo sistema software puede accelerar de forma significativa el desarrollo de un proyecto, adem&aacute;s de simplificar toda la l&oacute;gica a implementar.<\/p>\n<p><!--more--><\/p>\n<h1>OODBs: un cambio de paradigma<\/h1>\n<p>Las bases de datos orientadas a objetos (OODB, en adelante) no son un paradigma nuevo en el mundo de la persistencia de datos. Los primeros sistemas de gesti&oacute;n de estas BDs se remontan a los a&ntilde;os 80, con la aparici&oacute;n de Term Object Database y Versant Object Database, pero todos persiguen un mismo objetivo: llevar la orientaci&oacute;n a objetos hasta la misma <em>capa de datos<\/em> de las aplicaciones, lo que se traduce en no tener que convertir los objetos que tienen que persistir en un esquema relacional.<\/p>\n<p>Con una OOBD, los desarrolladores podemos simplificar mucho el dise&ntilde;o de los m&eacute;todos de acceso, modificado y borrado de objetos en la base de datos. No hace falta que nos preocupemos de las referencias entre unos y otros objetos, ya no hacen falta atributos de identificaci&oacute;n ni claves primarias ni for&aacute;neas. Con una OODB no tenemos que pensar c&oacute;mo mapear los atributos de los objetos, porque guardamos los propios objetos!<\/p>\n<h1>db4o<\/h1>\n<p>Entre otros sistemas de gesti&oacute;n para bases de datos de objetos, nos encontramos con <strong>db4o<\/strong>, el cual mantiene y desarrolla Versant despu&eacute;s de comprarlo en 2008. Se trata de una OODB ligera que, adem&aacute;s, se puede utilizar de manera integrada (<em>embedded<\/em>) en el resto de la aplicaci&oacute;n que se est&eacute; utilizando; no es necesario, por tanto, un servidor externo donde la aplicaci&oacute;n haga una conexi&oacute;n.<\/p>\n<p>Antes de usar db4o, har&aacute; falta que aprendamos un poco sobre su funcionamiento (est&aacute; bastante bien documentado en <a href=\"http:\/\/community.versant.com\/documentation\/reference\/db4o-8.1\/java\/reference\/index.html\" target=\"_blank\" rel=\"noopener\">http:\/\/community.versant.com\/documentation\/reference\/db4o-8.1\/java\/reference\/index.html<\/a>). En primer lugar, cabe decir que db4o mantiene un <em>contenedor de objetos<\/em>, que podemos entender como una conexi&oacute;n a la base de datos. Todas las consultas que hacemos, las haremos contra este contenedor, el cual nos permite mantener las propiedades ACID, dado que cada contenedor tiene su propia transacci&oacute;n.<\/p>\n<p>Un concepto importante que hay que tener en cuenta es el de <a href=\"http:\/\/community.versant.com\/documentation\/reference\/db4o-8.1\/java\/reference\/Content\/basics\/identity_concept.htm\" target=\"_blank\" rel=\"noopener\"><em>identidad<\/em><\/a>. Db4o mantiene la identidad de los objetos sin necesitar atributos o relaciones que los identifiquen un&iacute;vocamente, de forma similar a como se mantienen los objetos en memoria normalmente. As&iacute;, si pedimos un objeto de diversas maneras, db4o siempre nos retornar&aacute; el mismo objeto, la misma referencia. Tambi&eacute;n hemos de saber que db4o mantiene una <em><a href=\"http:\/\/community.versant.com\/documentation\/reference\/db4o-8.1\/java\/reference\/Content\/basics\/indentity_concept\/reference_cache.htm\" target=\"_blank\" rel=\"noopener\">cach&eacute; de referencias<\/a><\/em> en memoria: una tabla donde las referencias a los objetos se corresponden con la representaci&oacute;n de las mismas en disco, para poder identificar en todo momento cu&aacute;l es el objeto que se ha de modificar, borrar o leer.<\/p>\n<p>Finalmente, db4o implementa lo que se conoce como <a href=\"http:\/\/community.versant.com\/documentation\/reference\/db4o-8.1\/java\/reference\/Content\/basics\/activation.htm\"><em>activation depth<\/em><\/a> (profundidad de activaci&oacute;n). Si, por el motivo que sea, no queremos que la OODB nos cargue todos los objetos persistidos en memoria, db4o nos ofrece una soluci&oacute;n alternativa: cargar s&oacute;lo aquellas partes del grafo de objetos que nos son de inter&eacute;s. Es decir, cuando hacemos una consulta se activar&aacute;n (cargar&aacute;n) aquellos objetos que hemos pedido, as&iacute; como todos aquellos que est&eacute;n referenciados por estos, y as&iacute; de forma transitiva hasta una cierta <em>profundidad<\/em>, que es, simplemente, la cantidad de referencias que saltamos desde los objetos pedidos originalmente. Db4o nos permite configurar esta profundidad de forma global, espec&iacute;fica para alagunas clases o autom&aacute;tica, en cascada, seg&uacute;n se requiera.<\/p>\n<p>Lo que explicamos aqu&iacute; es una mera introducci&oacute;n bastante superficial de db4o. Este sistema de gesti&oacute;n es evidentemente mucho&nbsp; m&aacute;s complejo y queda al gusto del lector profundizar en los conceptos y el uso de esta OODB.<\/p>\n<h2>&quot;Querying db4o&quot;<\/h2>\n<p>Db4o soporta diversos mecanismos de consulta: <a href=\"http:\/\/community.versant.com\/documentation\/reference\/db4o-8.1\/java\/reference\/Content\/basics\/querying\/native_queries.htm\" target=\"_blank\" rel=\"noopener\"><em>queries nativas<\/em><\/a>, <em><a href=\"http:\/\/community.versant.com\/documentation\/reference\/db4o-8.1\/java\/reference\/Content\/basics\/querying\/query_by_example.htm\" target=\"_blank\" rel=\"noopener\">queries basadas en ejemplo<\/a><\/em> y <a href=\"http:\/\/community.versant.com\/documentation\/reference\/db4o-8.1\/java\/reference\/Content\/basics\/querying\/soda_query.htm\"><em>SODA queries<\/em><\/a>. Cada uno tienes sus ventajas e inconvenientes: podemos realizar f&aacute;cilmente queries usando un objeto de ejemplo, pero no siempre podemos afinar los requisitos de las consultas con estos stubs. Por otra parte, las queries nativas nos permiten programarlas en el lenguaje de programaci&oacute;n con el que implementamos la aplicaci&oacute;n, manteniendo as&iacute; la coherencia en todo el proyecto y ayudando a mejorar el mantenimiento posterior. Por &uacute;ltimo, las SODA queries nos permiten realizar consultas complejas de forma muy potente, aunque primero nos tendremos que familiarizar con esta API, ciertamente poco documentada, que b&aacute;sicamente, nos permite hacer recorridos por el grafo de objetos que tenemos persistidos. En <a href=\"http:\/\/www.ibm.com\/developerworks\/java\/library\/j-db4o2\/index.html\" target=\"_blank\" rel=\"noopener\">este tutorial<\/a> se dan unos buenos ejemplos de queries de ejemplos y queries nativas para aprender a hacer consultas b&aacute;sicas.<\/p>\n<h1>Implementando db4o<\/h1>\n<p>En inLab hemos implantado db4o en el proyecto <a href=\"http:\/\/inlab.fib.upc.edu\/es\/somupc-integracion-de-las-intranets-de-la-upc\" target=\"_blank\" rel=\"noopener\">SomUPC<\/a> con entusiasmo despu&eacute;s de hacer unas primeras pruebas, para ver si realmente nos era &uacute;til y sencillo llevarlo hacia adelante. Despu&eacute;s de todo, podemos decir que ha resultado mucho m&aacute;s f&aacute;cil implementar la capa de persistencia del proyecto con db4o que con Hibernate y una BD relacional cl&aacute;sica, nuestra primera elecci&oacute;n en este sentido. Veremos algunos de los m&eacute;todos que nos permiten configurar la base de datos y acceder, modificar y eliminar los objetos que guardamos.<\/p>\n<p>Para abrir la base de datos podemos utilizar una clase auxiliar, que nos haga la gesti&oacute;n de la conexi&oacute;n y desconexi&oacute;n, as&iacute; como el mantenimiento del contenedor de objetos en el cual cargamos los resultados de las consultas que hacemos:<\/p>\n<p>&nbsp;<\/p>\n<pre>\r\npublic class Db4oHandler {\r\n    private ObjectContainer db;\r\n    public void openDatabase(String path) {\r\n        EmbeddedConfiguration conf = Db4oEmbedded.newConfiguration();\r\n        db = Db4oEmbedded.openFile(conf, path);\r\n    }\r\n    public void close() {\r\n        try {\r\n            db.commit(); \/\/commit the last in-mem cached (not persisted) changes!\r\n            db.close();\r\n        } catch(Exception e){\r\n            \/\/exception handling here!\r\n        }\r\n    }\r\n    public ObjectContainer getDb() {\r\n        return db;\r\n    }\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Con estas pocas l&iacute;neas podemos tener una base de datos db4o operativa y funcionando, en el fichero que definamos en el path indicado. Una vez abierta la BD; guardar un objeto de la clase <em>Foo<\/em> es tan sencillo como esto:<\/p>\n<pre>\r\npublic class Foo {\r\n    private String bar; \/\/this will be stored\r\n    private transient String temp; \/\/this will NOT be stored (it&#39;s transient!)    \r\n    private List&lt;Object&gt; list; \/\/the list and all the objects it contains will be stored\r\n    public Foo() {}\r\n}\r\n\r\n    \/\/ &hellip;\r\n\r\n    Foo foo = new Foo();\r\n    ObjectContainer db = dbHandler.getDb();\r\n    db.store(foo);\r\n    db.commit();<\/pre>\n<p>Y borrarlo tan simple como:<\/p>\n<pre class=\"rteindent1\">\r\ndb.delete(foo); \/\/foo was stored in the database\r\ndb.commit();<\/pre>\n<p>Como vemos, no hace falta mantener un c&oacute;digo lleno de anotaciones o un complejo fichero de configuraci&oacute;n que nos defina los <em>mappings<\/em> de los atributos de nuestras clases: s&oacute;lo POJOs, f&aacute;ciles de leer, modificar y mantener. El &uacute;nico c&oacute;digo repetitivo (en la parte de persistencia de datos) que quedar&aacute; en nuestros ficheros ser&aacute; aquel que el propio lenguaje o nuestra propia traza requieran. De hecho, si nos aseguramos de que la base de datos se cerrar&aacute; correctamente con la aplicaci&oacute;n, es decir, que se ejecutara la funci&oacute;n <em>close() <\/em>&nbsp;del <em>Db4oHandler, <\/em>no har&aacute; falta hacer <em>db.commit()<\/em> cada vez que se haga una operaci&oacute;n en la BD.<\/p>\n<h2>db4o y Android<\/h2>\n<p>Finalmente, dado que es una base de datos integrada, f&aacute;cilmente accesible y configurable, comprobamos que es muy &uacute;til para desplegar en aplicaciones m&oacute;viles, en plataformas como Android: <a href=\"http:\/\/java.dzone.com\/articles\/using-db4o-android-application\" target=\"_blank\" rel=\"noopener\">http:\/\/java.dzone.com\/articles\/using-db4o-android-application<\/a>. As&iacute; podemos aprovechar el potencial de esta OOBD y la rapidez de desarrollo que nos facilita para llevar a cabo los proyectos de apps m&aacute;s ambiciosos que queramos.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En la l&iacute;nea de les metodolog&iacute;as &aacute;giles y la innovaci&oacute;n en modelos de bases de datos, la incorporaci&oacute;n de una base de datos orientada a objetos en un nuevo sistema software puede accelerar de forma significativa el desarrollo de un proyecto, adem&aacute;s de simplificar toda la l&oacute;gica a implementar.<\/p>\n","protected":false},"author":594,"featured_media":1390,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"experteses":[],"class_list":["post-1394","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized-ca"],"acf":[],"_links":{"self":[{"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/posts\/1394","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/users\/594"}],"replies":[{"embeddable":true,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/comments?post=1394"}],"version-history":[{"count":0,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/posts\/1394\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/media\/1390"}],"wp:attachment":[{"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/media?parent=1394"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/categories?post=1394"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/tags?post=1394"},{"taxonomy":"experteses","embeddable":true,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/experteses?post=1394"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}