Páginas

6/11/15

HSQLDB Tutorial

HSQLDB Tutorial.

Tutorial de HSQLDB con Java.




HyperSQL (HSQLDB) es una base de datos relacional, es hecha 100% en Java y corre en la maquina virtual de Java (JVM), hay muchas características que hacen de HSQLDB una base de datos atractiva para los desarrolladores, podemos usarla sin la necesidad de un servidor, para hacer pruebas en memoria utilizando la memoria RAM, es de código abierto, con solo importar el JAR a tu proyecto puedes comenzar a trabajar, bien sea para pruebas o para hacer funcionar tu aplicación en un ambiente de producción, claro que también trae su Database Manager en SWING para hacerle consultas a nuestras tablas por fuera de nuestra aplicación.

En este Tutorial vamos a centrarnos en el funcionamiento de HSQLDB desde Java. Lo que necesitamos es un IDE, en este caso yo utilizo JBoss Developer Studio o lo que es lo mismo eclipse y la última versión de HSQLDB que en este momento es la 2.3.3.


1. Descargar HSQLDB-2.3.3.


Vamos a ir a la página de sourceforge y descargamos el archivo hsqldb-2.3.3.zip. Lo descomprimimos (De preferencia en la raíz de C:) y podemos ver que dentro trae una gran cantidad de archivos, directorios... Algo así deberíamos ver:
imagen archivosHSQLDB
Directorio HSQLDB
En la carpeta lib, se encuentra el archivo hsqldb.jar que vamos a importar al classpath de nuestro proyecto.

2. Bases de Datos en HSQLDB.


Hay varios tipos, en HSQLDB las bases de datos son llamadas "Catalogos", hay tres tipos de catálogos:
  • mem: este tipo de catalogo se guarda directamente en la memoria RAM, no hay ningún tipo de persistencia, se cierra el proyecto de Java y se borran todos los datos ingresados anteriormente.
  • file: se guarda en archivos en la raíz del proyecto Java.
  • res: se guarda en el mismo proyecto Java, como un archivo JAR o ZIP.
mem: todo en la memoria, este tipo de catalogos se pueden usar para hacer pruebas de datos, hay que recordar que este tipo de bases de datos no crea nigún archivo.

file: este tipo de catálogos consiste en crear varios archivos, todos con el mismo nombre pero con diferentes extensiones, localizados en el mismo directorio. Por ejemplo si la base de datos la llamamos "prueba", estos son los archivos que se van a crear:
  • prueba.properties: contiene la configuración de la base de datos.
  • prueba.script: cotiene las definiciones de las tablas y obejtos.
  • prueba.log: contiene los cambios recientes que se la hayan hecho a la base de datos.
  • prueba.data: contiene los datos de las tablas. (A veces no se crea)
  • prueba.backup: contiene un backup del ultimo estado consistenete de la base de datos. (A veces no se crea)
res: este sirve para abrir un catalogo ya existente en una ruta especifica dentro de nuestra aplicación, cuando abrimos la conexión se descomprime el catalogo, y al cerrar la aplicación se comprime de nuevo. Este tipo de catálogos no se usa con gran cantidad de datos, en ese caso es recomendable usar el catalogo file.

3. Acceder a los catálogos de Bases de Datos en HSQLDB.


Hay 2 maneras de acceder:
  • 3.1 En proceso (IN-PROCESS):

    Utilizando JDBC podemos conectarnos a la Base de Datos, después solo tenemos que indicar el directorio donde se encuentra el catalogo y ya podemos hacer nuestras consultas.
    Para ingresar a un catalogo de tipo file tenemos que obtener la conexión de esta manera:
         Connection connection = DriverManager.getConnection("jdbc:hsqldb:file:prueba", "sa", "");
        
    Ahí obtenemos la conexión, si estaba creado obtiene la conexión a ese catalogo y si no simplemente lo crea.
    Si es un catalogo de tipo mem, la ruta es simplemente un "nombre", recuerda que este tipo de catalogos no crea archivos ni nada de eso, podemos poner lo que sea y comenzar hacer pruebas. Para conectarnos lo hacemos de esta manera:
         Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:pruebamem", "sa", "");
        
    Para conectarnos a un catalogo de tipo res, como es un recurso Java (JAR, ZIP...), tenemos que indicar la ruta del recurso como si se tratará de una clase, por ejemplo supongamos que nuestro catalogo se encuentra en esta ruta: "datojava/hsqldb/prueba", tenemos que conectarnos al catalogo de esta manera:
         Connection connection = DriverManager.getConnection("jdbc:hsqldb:res:datojava.hsqldb.prueba", "sa", "");
        
    Acceder de esta manera (IN_PROCESS) a los catálogos es bastante rápido ya que no hay que estar pasando datos entre redes o algo por el estilo, pero tienes que tomar en cuenta que solo un proceso Java (una aplicación, un Database Manager...) puede acceder a un catalogo de tipo file, si quieres que varias aplicaciones accedan al mismo tiempo a este tipo de catálogos (IN-PROCESS), tenemos que hacer el catalogo file de solo lectura (read-only), o cambiar a un catalogo de tipo res que son de tipo read-only.
  • 3.2 Modo Servidor:

    Es el que recomiendo, primero porque podemos conectarnos desde distintas aplicaciones Java al mismo catalogo, podemos ver y actualizar los datos que tengamos en el catalogo desde el Database Manager (viene incluido en el archivo que descomprimimos en el paso 1), mientras las demás aplicaciones están utilizando la base de datos, hay varias maneras de acceder en modo servidor, yo solo me voy a centrar en una manera de correr el servidor, se llama HyperSQL HSQL Server y es la más usada y la más rápida, para correr el servidor lo podemos hacer desde la línea de comandos o desde la misma aplicación.
    Para correr el servidor desde la línea de comandos tenemos que ubicarnos en el directorio donde descomprimimos hsqldb-2.3.3, y ejecutar el siguiente comando:

    java -cp hsqldb/lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:DatoJava/HSQLDB/miBaseDeDatos --dbname.0 mdb

    En ese comando estamos diciendo que vamos acceder o crear (en el caso de que no exista) ese catalogo llamado miBaseDeDatos en el directorio "DatoJava/HSQLDB/" con el alias mdb.
    Al ejecutar ese comando deberíamos ver en la consola un mensaje como este:
  • Server Mode HSQLDB
    Server Mode HSQLDB

    Eso nos indica que ya podemos acceder al catalogo desde el Database Manager o bien desde cualquier aplicación Java mediante JDBC.
    Para verificar que ese comando creo ese directorio con ese catalogo vamos a la ruta "C:\hsqldb-2.3.3\hsqldb-2.3.3" y deberíamos ver algo como esto:
    Directorio Creado HSQLDB
    Directorio Creado HSQLDB
    Ahora podemos ingresar con el Database Manager al mismo catalogo de esta manera, si queremos iniciar el Database Manager desde la consola, tenemos que ubicarnos en el directorio "C:\hsqldb-2.3.3\hsqldb-2.3.3" y ejecutar este comando en la consola:

    java -cp hsqldb/lib/hsqldb.jar org.hsqldb.util.DatabaseManagerSwing


    O podemos ir directamente a la ubicación del archivo batch del Database Manager (runManagerSwing.bat), que está en el directorio C:\hsqldb-2.3.3\hsqldb-2.3.3\hsqldb\bin y ejecutarlo. Las dos opciones inician el Manager.
    Database Manager HSQLDB
    Database Manager HSQLDB
    Para conectarnos al mismo catalogo que hemos creado anteriormente tenemos que configurar la conexión de esta manera:
    • Setting Name: ingresamos el nombre "DatoJava"
    • Type: HSQL Database Engine Server
    • Driver: org.hsqldb.jdbcDriver
    • URL: jdbc:hsqldb:hsql://localhost/mdb
    • User: SA
    • Password:
    Ya con esa configuración podemos hacer consultas/actualizaciones en nuestro Catalogo:
    Database Manager HSQLDB
    Database Manager HSQLDB
    Por ejemplo si queremos crear una tabla nueva en nuestro catalogo "miBaseDeDatos", ejecutamos este script en el Database Manager:
        CREATE TABLE usuario (
         ID varchar(6) PRIMARY KEY,
         nombre varchar(20) NOT NULL, 
         apellido varchar(20) NOT NULL,
         login varchar(20) NOT NULL,
         clave varchar(20) NOT NULL,
        );
       
    Podemos ver en la imagen que ya fue creada la tabla.
    Create Table HSQLDB
    Create Table HSQLDB
    Para cerrar la Base De Datos tenemos que ejecutar SHUTDOWN, al ejecutar ese script todos los archivos se guardan de tal forma que la próxima vez que volvamos a conectarnos al catalogo, este abrirá rápidamente. La mejor opción de cerrar la Base De Datos es con SHUTDOWN COMPACT, este script sobrescribe el archivo .data que contiene información en CACHE acerca de las tablas y lo comprime al tamaño mínimo, se usa casi siempre y más aún cuando hacemos muchos inserts, updates, deletes, ya que ese archivo guarda esa información y el tamaño del archivo suele crecer rápidamente. Al ejecutarlo se cierra la conexión al catalogo:
    SHUTDOWN COMPACT HSQLDB
    SHUTDOWN COMPACT HSQLDB
    Ya no podremos hacer nada a la base de datos porque el servidor no está corriendo.

    Para correr el servidor desde una aplicación Java hay que crear una instancia del Servidor y asignarle las propiedades correspondientes. Con este código podemos iniciar el servidor desde nuestra aplicación:
        //....
        HsqlProperties hsqlProperties = new HsqlProperties();
        hsqlProperties.setProperty("server.database.0",
          "file:C:/hsqldb-2.3.3/hsqldb-2.3.3/DatoJava/HSQLDB/miBaseDeDatos");
        hsqlProperties.setProperty("server.dbname.0", "mdb");
        
        Server server = new Server();
        server.setProperties(hsqlProperties);
        server.setTrace(false); // No queremos loguear todo
        server.start();
        
        //...
       
    Como vemos nos estamos conectando al mismo catalogo que creamos anteriormente (C:/hsqldb-2.3.3/hsqldb-2.3.3/DatoJava/HSQLDB/miBaseDeDatos). Mientras no ejecutemos el script "SHUTDOWN COMPACT" la conexión queda abierta y cualquier aplicación se puede conectar, incluyendo el Database Manager.

4. Creación del proyecto Java.


Como la idea del Tutorial es desde una aplicación Java, vamos a crear desde nuestro IDE un simple "Java Project". Para eso recordamos que vamos a la opción de File> New> Java Project.
imagen New Project
Nuevo Java Project.
Le vamos a dar el nombre de HSQLDBDatoJava, importamos el archivo hsqldb.jar que está en el directorio C:\hsqldb-2.3.3\hsqldb-2.3.3\hsqldb\lib al classpath de nuestro proyecto. Ahora vamos a crear un paquete llamado datojava.hsqldb.main y en el mismo vamos a crear una clase llamada DJHSQLDBMain. Hasta ahora la estructura de nuestro proyecto debería verse así:
imagen estructura proyecto
Estructura proyecto
En la clase DJHSQLDBMain vamos hacer lo siguiente:
  • Iniciar el servidor desde la aplicación.
  • Conectarnos al mismo catalogo (miBaseDeDatos).
  • Insertar algunos registros en la tabla usuario.
  • Obtener los registros de la tabla.
Vamos a ir detallando por bloques de código el funcionamiento de la clase, para implementar lo anterior necesitamos algunas variables en nuestra clase:
  package datojava.hsqldb.main;

  import java.beans.Statement;
  import java.sql.Connection;
  import java.sql.ResultSet;

  /**
   * @author http://datojava.blogspot.com
   */
   
  public class DJHSQLDBMain {
   public static void main(String[] args) {
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    
    try {

    } catch (Exception ex) {
     ex.printStackTrace();
    }
   }
  }
 
Creamos las variables normales para conectarnos, insertar/actualizar registros y obtenerlos, ahora procedemos a correr el servidor desde la aplicación dentro del try-catch:
  try {
   HsqlProperties hsqlProperties = new HsqlProperties();
   hsqlProperties
     .setProperty("server.database.0",
       "file:C:/hsqldb-2.3.3/hsqldb-2.3.3/DatoJava/HSQLDB/miBaseDeDatos");
   hsqlProperties.setProperty("server.dbname.0", "mdb");

   Server server = new Server();
   server.setProperties(hsqlProperties);
   server.setTrace(false); // No queremos loguear todo
   server.start();

  } catch (Exception ex) {
   ex.printStackTrace();
  }
 
Una vez que ya iniciamos el servidor vamos a obtener la conexión:
  try {
   //Iniciamos el servidor
   //...
   
   connection = DriverManager.getConnection(
     "jdbc:hsqldb:hsql://localhost/mdb", "SA", "");
   
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 
Insertamos algunos registros:
  try{
   // Iniciamos el servidor
   // obtenemos la conexion
   // ...
   
   statement = connection.createStatement();

   statement
     .executeUpdate("INSERT INTO usuario VALUES ('1', 'pedro', 'suarez', 'p.suarez', '12345');");
   statement
     .executeUpdate("INSERT INTO usuario VALUES ('2', 'pablo', 'martinez', 'p.martinez', '12345');");
   statement
     .executeUpdate("INSERT INTO usuario VALUES ('3', 'pepe', 'peres', 'p.perez', '12345');");
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 
Obtenemos los registros de la tabla usuario
  try{
   // Iniciamos el servidor
   // obtenemos la conexion
   // Insertamos registros
   // ...
   resultSet = statement.executeQuery("SELECT * FROM usuario");

   while (resultSet.next()) {
    System.out.println("---Usuario---");
    System.out.println("ID: " + resultSet.getString(1));
    System.out.println("Nombre: " + resultSet.getString(2));
    System.out.println("Apellido: " + resultSet.getString(3));
   }
   
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 
Ya con eso terminamos de implementar la clase, como estamos haciendo uso de la clase para aprender a utilizar HSQLDB con Java, sería bueno ejecutar un SHUTDOWN COMPACT, siempre y cuando no vallamos a utilizar el Database Manager en el mismo catalogo, este es el codigo completo de la clase:

DJHSQLDBMain.java
  package datojava.hsqldb.main;

  import java.sql.Statement;
  import java.sql.Connection;
  import java.sql.DriverManager;
  import java.sql.ResultSet;

  import org.hsqldb.Server;
  import org.hsqldb.persist.HsqlProperties;

  /**
   * @author http://datojava.blogspot.com
   */

  public class DJHSQLDBMain {
   public static void main(String[] args) {
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    try {

     HsqlProperties hsqlProperties = new HsqlProperties();
     hsqlProperties
       .setProperty("server.database.0",
         "file:C:/hsqldb-2.3.3/hsqldb-2.3.3/DatoJava/HSQLDB/miBaseDeDatos");
     hsqlProperties.setProperty("server.dbname.0", "mdb");

     Server server = new Server();
     server.setProperties(hsqlProperties);
     server.setTrace(false);
     System.out.println(server.getState() + " "
       + server.getStateDescriptor());
     server.start();

     connection = DriverManager.getConnection(
       "jdbc:hsqldb:hsql://localhost/mdb", "SA", "");

     statement = connection.createStatement();

     statement
       .executeUpdate("INSERT INTO usuario VALUES ('1', 'pedro', 'suarez', 'p.suarez', '12345');");
     statement
       .executeUpdate("INSERT INTO usuario VALUES ('2', 'pablo', 'martinez', 'p.martinez', '12345');");
     statement
       .executeUpdate("INSERT INTO usuario VALUES ('3', 'pepe', 'peres', 'p.perez', '12345');");

     resultSet = statement.executeQuery("SELECT * FROM usuario");

     while (resultSet.next()) {
      System.out.println("---Usuario---");
      System.out.println("ID: " + resultSet.getString(1));
      System.out.println("Nombre: " + resultSet.getString(2));
      System.out.println("Apellido: " + resultSet.getString(3));
     }
     
     // Opcional para detener el Servidor
     statement.executeQuery("SHUTDOWN COMPACT");
    } catch (Exception ex) {
     ex.printStackTrace();
    } finally {
     try {
      if (resultSet != null) {
       resultSet.close();
      }
      if (statement != null) {
       statement.close();
      }
      if (connection != null) {
       connection.close();
      }

     } catch (Exception e) {
      e.printStackTrace();
     }
    }
   }
  }
 
Si compilamos nuestra aplicación podemos observar que esto es lo que imprime en la consola:
[Server@e09713]: [Thread[main,5,main]]: checkRunning(false) entered
[Server@e09713]: [Thread[main,5,main]]: checkRunning(false) exited
16 SHUTDOWN
[Server@e09713]: Initiating startup sequence...
[Server@e09713]: Server socket opened successfully in 5 ms.
[Server@e09713]: Database [index=0, id=0, db=file:C:/hsqldb-2.3.3/hsqldb-2.3.3/DatoJava/HSQLDB/
miBaseDeDatos, alias=mdb] opened sucessfully in 198 ms.
[Server@e09713]: Startup sequence completed in 204 ms.
[Server@e09713]: 2015-11-06 15:23:27.794 HSQLDB server 2.3.3 is online on port 9001
[Server@e09713]: To close normally, connect and execute SHUTDOWN SQL
[Server@e09713]: From command line, use [Ctrl]+[C] to abort abruptly
---Usuario---
ID: 1
Nombre: pedro
Apellido: suarez
---Usuario---
ID: 2
Nombre: pablo
Apellido: martinez
---Usuario---
ID: 3
Nombre: pepe
Apellido: perez
[Server@e09713]: Initiating shutdown sequence...
[Server@e09713]: Shutdown sequence completed in 100 ms.
[Server@e09713]: 2015-11-06 15:23:28.444 SHUTDOWN : System.exit() was not called
 
Lo que quiere decir que inserto los datos correctamente en la tabla usuario y que todo está funcionando bien, este ejemplo fue utilizando un catalogo creado fuera de nuestra aplicación, pero en el caso de que queramos que nuestro catalogo este dentro de la aplicación, tenemos que cambiar la dirección del catalogo al momento de iniciar el servidor.
  HsqlProperties hsqlProperties = new HsqlProperties();
  hsqlProperties
    .setProperty("server.database.0",
      "file:DatoJava/HSQLDB/miBaseDeDatos");
  hsqlProperties.setProperty("server.dbname.0", "mdb");
 
Solo con eso crearemos el catalogo dentro de nuestra aplicación, y así toda la información estará dentro de nuestra aplicación, aquí puedes descargar el proyecto Java de este Tutorial, recuerda que este DatoJava de HSQLDB es básico, queda de tu parte desarrollar más conocimientos acerca del tema, Suerte no olvides comentar y compartir la entrada.

3 comentarios :

  1. Como compilas desde terminal este proyecto

    ResponderEliminar
  2. Respuestas
    1. Excelente Francisco, que bueno que te funciono de maravilla!

      Eliminar