web 2.0

domingo, 7 de marzo de 2010

DB4O: El poder de las Bases de Datos Orientadas a Objetos



DB40
Hace alrededor de 1 año, conocí a DB40, una Base de Datos Orientada a Objetos Open Source!… ¿Pero qué es DB4O? y sobre todo ¿para que me sirve si ya se utilizar MySQL, SQL Server, Oracle y otro manejador de Base de Datos Relacional?… Estas preguntas son las que trataré de responder a continuación.

¿Qué es DB4O?

Bien, como ya lo dije arriba, DB40 es una Base de Datos Orientada a Objetos de alto rendimiento. En algunos Benchmark realizados, DB4O muestra un rendimiento superior o similar a las Bases de Datos Relacionales, en el caso de Java, utilizando JDBC o algún Framework como Hibernate! Podemos ver estas pruebas en la página de polepos.org

¿Hibernate?… ¿Qué es eso?

Bien, si no sabes que es Hibernate te lo explicare a continuación!
Hibernate es una “herramienta” para Java (NHibernate es la versión para .NET) que nos permite poder conjuntar sin ningún problema al modelo Orientado a Objetos con el Relacional! Debes de saber que ambos modelos no son compatibles!

Pero yo he utilizado Java y MySQL… ¿Como no van a ser compatibles?

Es verdad, el paradigma Orientado a Objetos con el Modelo Relacional son incompatibles. No importa que tu hayas trabajado y desarrollado una aplicación que guarde datos en MySQL mediante Java, C# o algún otro lenguaje OO, en realidad lo único que has hecho, es escribir una simple sentencia SQL y enviarla al manejador de BD pero desde Java.
El hecho de enviar sentencias SQL a algún manejador de BD Relacional, no significa que sean compatibles!… Pero bueno, finalmente ¿A que me refiero cuando digo que son incompatibles?,.. pues bien, veámoslo con un ejemplo.
Persona ximena = new Persona("Ximena", "Rodriguez", 'F');
JDBC.save(ximena);
Si Java fuera compatible con MySQL/PostgreSQL/etc., el código anterior, indudablemente funcionaria! Es decir, sería posible guardar objetos! En lugar de eso, necesitamos utilizar variables escalares que contienen los valores que deseamos guardar, concatenarlas a otra cadena que tiene la sentencia SQL y finalmente enviarlas al manejador de Base de Datos mediante una alguna interfaz que comunique Java con  MySQL/PostgreSQL/etc., como lo es JDBC.
public void guardar(String nombre, String aPaterno, char sexo){
    stmt.executeUpdate(
                "INSERT INTO persona("nombre, paterno, sexo )" +
                    "VALUES(' "+nombre+', ' "+aPaterno+" ', ' "+sexo+" ')");
}
Y para recuperar datos, es lo mismo, debemos enviar una consulta SELECT * FROM y con el resultado que nos devuelve la BD, ir iterando sobre cada registro para guardar el valor en variables o en Listas.
Finalmente podemos ver el esfuerzo requerido para conectar los dos mundos;
import java.sql.*;

public class Jdbc10 {
  public static void main(String args[]){
    System.out.println(
                  "Copyright 2004, R.G.Baldwin");
    try {
      Statement stmt;
      ResultSet rs;

      //Register the JDBC driver for MySQL.
      Class.forName("com.mysql.jdbc.Driver");

      //Define URL of database server for
      // database named JunkDB on the localhost
      // with the default port number 3306.
      String url =
            "jdbc:mysql://localhost:3306/JunkDB";

      //Get a connection to the database for a
      // user named auser with the password
      // drowssap, which is password spelled
      // backwards.
      Connection con =
                     DriverManager.getConnection(
                        url,"auser", "drowssap");

      //Display URL and connection information
      System.out.println("URL: " + url);
      System.out.println("Connection: " + con);

      //Get a Statement object
      stmt = con.createStatement();

      //As a precaution, delete myTable if it
      // already exists as residue from a
      // previous run.  Otherwise, if the table
      // already exists and an attempt is made
      // to create it, an exception will be
      // thrown.
      try{
        stmt.executeUpdate("DROP TABLE myTable");
      }catch(Exception e){
        System.out.print(e);
        System.out.println(
                  "No existing table to delete");
      }//end catch

      //Create a table in the database named
      // myTable.
      stmt.executeUpdate(
            "CREATE TABLE myTable(test_id int," +
                  "test_val char(15) not null)");

      //Insert some values into the table
      stmt.executeUpdate(
                "INSERT INTO myTable(test_id, " +
                    "test_val) VALUES(1,'One')");
      stmt.executeUpdate(
                "INSERT INTO myTable(test_id, " +
                    "test_val) VALUES(2,'Two')");
      stmt.executeUpdate(
                "INSERT INTO myTable(test_id, " +
                  "test_val) VALUES(3,'Three')");
      stmt.executeUpdate(
                "INSERT INTO myTable(test_id, " +
                   "test_val) VALUES(4,'Four')");
      stmt.executeUpdate(
                "INSERT INTO myTable(test_id, " +
                   "test_val) VALUES(5,'Five')");

      //Get another statement object initialized
      // as shown.
      stmt = con.createStatement(
               ResultSet.TYPE_SCROLL_INSENSITIVE,
                     ResultSet.CONCUR_READ_ONLY);

      //Query the database, storing the result
      // in an object of type ResultSet
      rs = stmt.executeQuery("SELECT * " +
                "from myTable ORDER BY test_id");

      //Use the methods of class ResultSet in a
      // loop to display all of the data in the
      // database.
      System.out.println("Display all results:");
      while(rs.next()){
        int theInt= rs.getInt("test_id");
        String str = rs.getString("test_val");
        System.out.println("\ttest_id= " + theInt
                             + "\tstr = " + str);
      }//end while loop

      //Display the data in a specific row using
      // the rs.absolute method.
      System.out.println(
                        "Display row number 2:");
      if( rs.absolute(2) ){
        int theInt= rs.getInt("test_id");
        String str = rs.getString("test_val");
        System.out.println("\ttest_id= " + theInt
                             + "\tstr = " + str);
      }//end if

      //Delete the table and close the connection
      // to the database
      stmt.executeUpdate("DROP TABLE myTable");
      con.close();
    }catch( Exception e ) {
      e.printStackTrace();
    }//end catch
  }//end main
}//end class Jdbc10
Código fuente: Using JDBC with MySQL, Getting Started
Con DB4O es tan sencillo conectar a la BD como hacer lo siguiente:
// Crear una base si no existe, abrirla si ya existe.
     File file = new File("testDb4o.yap");
     String fullPath = file.getAbsolutePath();
     ObjectContainer db = Db4oFactory.openFile(file);
     try{
           // realizar alguna acción con db4o
           // Ejemplos :
           db.set(obj);  // Almacena un objeto en la base
           db.commit();       // Realizar la transacción (y arrancar otra)
           db.delete(obj);   // Eliminar un objeto en la base
     }
     finally{
           db.close();         // Cerrar la base y liberar los recursos
}
Existe abundante documentación en ingles y en español sobre el uso de DB4O con Java y C#, al bajar DB4O de la página oficial, encontraremos en dicha carpeta, un completo tutorial en español sobre su uso, además de una guía de referencia! De igual forma, existe un libro “The definitive guide to db4o” que aunque no es la versión actual, sin duda es un excelente comienzo para iniciarse en esta fantástica BD.

Finalmente… Dijiste que Hibernate conjunta los dos mundos, ¿Como lo hace? y si ya lo hace, ¿Para que usar DB4O?

Bueno, Hibernate utiliza archivos XML para “mapear” clases Java con columnas de una Tabla Relacional y mediante este mapeo, es posible hacer algo similar al código que vimos para guardar objetos en DB4O, pero la diferencia es que Hibernate internamente se encargará de hacer dicho “mapeo” por nosotros e insertar en las columnas de la Tabla Relacional! A cambio de esta comodidad de utilizar Java y MYSQL/SQL Server/etc., Hibernate disminuye el rendimiento de la aplicación!
Es causa de mucha polémica decir si DB4O es o no es la opción idónea para aplicaciones empresariales de gran escala, por lo mismo que las Bases de Datos Orientadas a Objetos no tienen un fuerte sustento matemático como si lo tienen las Relacionales, su penetración no ha sido tan fuerte! Por lo anterior, la industria del Software no ha querido experimentar en ambientes reales de gran escala la potencia de DB4O.
Independientemente de lo anterior, DB4O es la mejor opción para aquellos desarrolladores Freelance que desarrollan aplicaciones de escritorio o incluso web que no requieren de almacenar millones de datos!
Algunos recursos sobre el uso de DB4O son:

1 comentarios:

Anónimo dijo...

Me sirvió mucho esta info!!!

Publicar un comentario