domingo, 3 de junio de 2007

¡ rápido con groovy ! operaciones básicas con base de datos.

Ahora que hemos creado una clase re-utilizable para controlar la conectividad de la base de datos, podemos plantearnos un conjunto de operaciones básicas utilizando SQL, por ejemplo voy a utilizar la conectividad MySql para crear una base de datos, los pasos son (1). lograr la conectividad, (2) crear la base de datos, (3) Activar la base de datos creada, (4) crear una tabla dentro de dicha base de datos, (5) ingresar unos datos a la tabla creada, (6) desplegar los datos, (7) alterar un registro específico en la base de datos, (8) desplegar otra vez los datos, (9) Eliminar un registro, (10) desplegar otra vez los datos y (11) desconectarse de la base de datos.

Miremos primeramente como serían estas operaciones sin el soporte de groovy, utilizando únicamente sentencias SQL:

 -- (2) creación de la base de datos, de nombre  DBGROOVY
 create database DBGROOVY ;

 -- (3) Activar la base de datos creada,
 use DBGROOVY ;

 -- (4) crear una tabla dentro de dicha base de datos, la tabla Libro
 create table Libro (
     Id int,
     version int,
     titulo varchar(30),
     Autor varchar(30)
 ) ;

 -- (5) ingresar unos datos a la tabla creada,
 insert into Libro values (1,1,'Nuestro Hombre en la Habana','Greene') ;
 insert into Libro values (2,1,'La cándida Eréndira...','García Marquez') ;
 insert into Libro values (3,1,'Amares','Galeano') ;

 -- (6) desplegar los datos de la tabla Libro
 select * from Libro ;

 -- (7) alterar un registro específico en la base de datos,
 update Libro set  Autor = 'Graham Green' where Id = 1 ;
 update Libro set  Autor = 'Gabriel García Marquez' where Id = 2;
 update Libro set  Autor = 'Eduardo Galeano' where Id = 3 ;

 -- (8) desplegar otra vez los datos
 select * from Libro ;

 -- (9) Eliminar un registro,
 delete from Libro where Id = 2 ;

 -- (10) desplegar otra vez los datos
 select * from Libro ;

 -- Elimino la base de datos DBGROOVY
 drop database DBGROOVY ;

Al correr este código desde la herramienta "MySql Command Line Client" obtengo el siguiente resultado

 Enter password: *****
 Welcome to the MySQL monitor.  Commands end with ; or \g.
 Your MySQL connection id is 1 to server version: 5.0.18-nt


 mysql> -- (2) creación de la base de datos, de nombre  DBGROOVY
 mysql> create database DBGROOVY ;
 Query OK, 1 row affected (0.20 sec)

 mysql>
 mysql> -- (3) Activar la base de datos creada,
 mysql> use DBGROOVY ;
 Database changed
 mysql>
 mysql> -- (4) crear una tabla dentro de dicha base de datos, la tabla Libro
 mysql> create table Libro (
     ->     Id int,
     ->     version int,
     ->     titulo varchar(30),
     ->     Autor varchar(30)
     -> ) ;
 Query OK, 0 rows affected (0.40 sec)
 
 mysql>
 mysql> -- (5) ingresar unos datos a la tabla creada,
 mysql> insert into Libro values (1,1,"Nuestro Hombre en la Habana","Greene") ;
 Query OK, 1 row affected (0.06 sec)
 
 mysql> insert into Libro values (2,1,"La cándida Eréndira...","García Marquez");
 Query OK, 1 row affected (0.05 sec)
 
 mysql> insert into Libro values (3,1,"Nuestro Hombre en la Habana","Galeano") ;
 Query OK, 1 row affected (0.05 sec)
 
 mysql>
 mysql> -- (6) desplegar los datos de la tabla Libro
 mysql> select * from Libro ;
 +------+---------+-----------------------------+----------------+
 | Id   | version | titulo                      | Autor          |
 +------+---------+-----------------------------+----------------+
 |    1 |       1 | Nuestro Hombre en la Habana | Greene         |
 |    2 |       1 | La cándida Eréndira...      | García Marquez |
 |    3 |       1 | Amares                      | Galeano        |
 +------+---------+-----------------------------+----------------+
 3 rows in set (0.00 sec)
 
 mysql>
 mysql> -- (7) alterar un registro específico en la base de datos,
 mysql> update Libro set  Autor = "Graham Green" where Id = 1 ;
 Query OK, 1 row affected (0.07 sec)
 Rows matched: 1  Changed: 1  Warnings: 0
 
 mysql> update Libro set  Autor = "Gabriel García Marquez" where Id = 2;
 Query OK, 1 row affected (0.04 sec)
 Rows matched: 1  Changed: 1  Warnings: 0
 
 mysql> update Libro set  Autor = "Eduardo Galeano" where Id = 3 ;
 Query OK, 1 row affected (0.06 sec)
 Rows matched: 1  Changed: 1  Warnings: 0
 
 mysql>
 mysql> -- (8) desplegar otra vez los datos
 mysql> select * from Libro ;
 +------+---------+-----------------------------+------------------------+
 | Id   | version | titulo                      | Autor                  |
 +------+---------+-----------------------------+------------------------+
 |    1 |       1 | Nuestro Hombre en la Habana | Graham Green           |
 |    2 |       1 | La cándida Eréndira...      | Gabriel García Marquez |
 |    3 |       1 | Amares                      | Eduardo Galeano        |
 +------+---------+-----------------------------+------------------------+
 

 mysql>
 mysql> -- (9) Eliminar un registro,
 mysql> delete from Libro where Id = 2 ;
 Query OK, 1 row affected (0.04 sec)

 mysql>
 mysql> -- (10) desplegar otra vez los datos
 mysql> select * from Libro ;
 +------+---------+-----------------------------+-----------------+
 | Id   | version | titulo                      | Autor           |
 +------+---------+-----------------------------+-----------------+
 |    1 |       1 | Nuestro Hombre en la Habana | Graham Green    |
 |    3 |       1 | Amares                      | Eduardo Galeano |
 +------+---------+-----------------------------+-----------------+
 2 rows in set (0.00 sec)
 
 mysql>

Ahora nos planteamos las mismas sentencias SQL ejecutadas desde Groovy

  1    import DBConnection.*
  2    
  3    // (1) lograr la conectividad a MySql
  4    Connection MySqlCN = ConnectionFactory.getConnection('MySQL')
  5    MySqlCN.connect('localhost','MySql','root','admin')
  6    
  7    // (2) creación de la base de datos, de nombre DBGROOVY
  8    MySqlCN.db.execute 'create database DBGROOVY'
  9    
 10    // (3) Activar la base de datos creada
 11    MySqlCN.db.execute 'use DBGROOVY'
 12    
 13    // (4) crear una tabla dentro de dicha base de datos, la tabla Libro'
 14    MySqlCN.db.execute '''
 15        create table Libro (
 16             Id int,
 17             version int,
 18             titulo varchar(30),
 19             Autor varchar(30)
 20         ) '''
 21    
 22    // (5) ingresar unos datos a la tabla creada
 23    MySqlCN.db.execute "insert into Libro values (1,1,'Nuestro Hombre en la Habana','Greene')"
 24    MySqlCN.db.execute "insert into Libro values (2,1,'La cándida Eréndira...','García Marquez')"
 25    MySqlCN.db.execute "insert into Libro values (3,1,'Amares','Galeano')"
 26    
 27    // (6) desplegar los datos de la tabla Libro
 28    MySqlCN.db.eachRow('select * from Libro') { rs ->
 29        println "$rs.Id.- $rs.version, $rs.titulo, $rs.Autor"
 30    }
 31    
 32    // (7) alterar un registro específico en la base de datos
 33    MySqlCN.db.execute "update Libro set  Autor = 'Graham Green' where Id = 1"
 34    MySqlCN.db.execute "update Libro set  Autor = 'Gabriel García Marquez' where Id = 2"
 35    MySqlCN.db.execute "update Libro set  Autor = 'Eduardo Galeano' where Id = 3"
 36    
 37    // (8) desplegar otra vez los datos
 38    MySqlCN.db.eachRow('select * from Libro') { rs ->
 39        println "$rs.Id.- $rs.version, $rs.titulo, $rs.Autor"
 40    }
 41    
 42    // (9) Eliminar un registro
 43    MySqlCN.db.execute "delete from Libro where Id = 2"
 44    
 45    // (10) desplegar otra vez los datos
 46    MySqlCN.db.eachRow('select * from Libro') { rs ->
 47        println "$rs.Id.- $rs.version, $rs.titulo, $rs.Autor"
 48    }
 49    
 50    // borra la base de datos DBGROOVY
 51    MySqlCN.db.execute 'drop database DBGROOVY'
 52    
 53    db.disconnect()
 54    
 55    return true

Algunas cosas que explicar:

La primera: estamos utilizando la librería de conectividad en DBConnection.groovy

Segunda: uno de los Aureliano Buendía, el que huye de su natal Macondo en "100 años de soledad", llega a los brazos y se enamora de la cándida Eréndira, quien ha sido prostituida por su desalmada Abuela quie a su vez sobrevive a un atentado planeado por los tórtolos! ... "hierva mala nunca muere".

Terecera: sobre la ejecución de sentencias SQL, si éstas no retornan ningún registro o valor escalar entonces se utiliza el método ".execute(...)", si en cambio se ejecuta una consulta que retorna uno o más registros, o un elemento escalar, se utiliza el método ".eachRow(...)". Pasemos a un corto análisis del siguiente código:

 27    // (6) desplegar los datos de la tabla Libro
 28    MySqlCN.db.eachRow('select * from Libro') { rs ->
 29        println "$rs.Id.- $rs.version, $rs.titulo, $rs.Autor"
 30    }
  • El método .eachRow(...) toma como argumento una consulta en SQL.
  • Cada registro es retornado y almacenado en una estructura, que en nuestro ejemplo es "rs".
  • Dinámicamente esta estructura captura y genera los campos equivalentes a la tabla consultada en base de datos, esa es la razón por la cual se observan los elementos "rs.Id", "rs.version", "rs.titulo" y "rs.Autor"
  • La estructura "rs" no es nada parecido a un Registro Activo en el sentido del lenguaje Ruby

eachRow(), por devolver un solo registro a la vez, resulta óptimo a la hora de recuperar y procesar grandes cantidades de datos. Pero si requiere recuperar un conjunto de datos y almacenarlos en una lista existen otras opciones que serán exploradas en el próximo blog. Hece una semanas requerí extrare 57 millones 600 mil datos de una tabla en una base de datos para transformarlo en un archivo CSV, eachRow() trabajó de manera muy óptima en cuanto a velocidad de procesamiento y bajo consumo de memoria.