domingo, 20 de febrero de 2011

Trabajando con NHibernate

Hibernate, NHibernate si estamos trabajando sobre la plataforma NET, es un framework de persistencia, con el que podemos mapear atributos del modelo relacional de una base de datos, con el modelo de objetos de una aplicacion. Basicamente, si tengo la clase Cliente, y estoy utilizando una base de datos para alamacenar información de los clientes, seguramente voy a tener una tabla de este estilo donde voy a persistir toda la información de cada uno.

Una de las grandes ventajas que ofrece Hibernate es que es independiente al motor de base de datos que se utilice. Simplemente, haciendo una modificacion al archivo de configuración, que nos permite conectarnos con la BD, es mas que suficiente. Esto es muy interesante ya que al no trabajar con codigo SQL explícito, no es necesario andar haciendo retoques para que funcione con diferentes motores.

Porsupuesto Hibernate es software libre, por lo cual no tendremos que desembolsar un solo centavo para trabajar con el.

Como primer paso creamos un nuevo proyecto desde Visual Studio. En mi caso voy a utilizar un proyecto del tipo Aplicación de Consola, ya que solamente voy a mostrar un caso bastante sensillo. Desde ya que ustedes pueden implementar Hibernate en una infinidad de proyectos.

Una vez que hemos creado el proyecto, para implementar NHibernate, necesitamos descargar las librerias a las cuales le agregaremos las referencias correspondientes.

Para descargar la última version pueden acceder a la página:

http://sourceforge.net/projects/nhibernate/files/NHibernate/3.0.0.GA/NHibernate-3.0.0.GA-bin.zip/download

Desde este sitio se pueden bajar la última disponible.

Una vez que la descarguen, simplemente le agregan las referencias a las siguientes librerias:

Castle.Core
Castle.DynamicProxy
Iesi.Collections
log4net
NHibernate
NHibernate.ByteCode.Castle

Como podrán observar en este caso voy a utilizar Castle. No necesariamente deben utilizar este framework, ustedes pueden elegir Spring, si así lo desean.

Una vez que agregamos las referencias al proyecto, procedamos a crear dos carpetas. En una vamos a alojar nuestras clases y en otra nuestros archivos de mapeo.

En la carpeta donde guardaremos nuestras clases, voy a generar una clase con el nombre Vehiculo. Esta clase, debe ser Serializable, por lo que debemos marcarla como tal, utilizando el atributo [Serializable]. De esta forma puedo obtener una representacion binaria de la clase que puede ser, por ejemplo escrita en disco. Esto se realiza ya que voy a serializar mi objeto con un archivo xml, que me va a servir como mapeo.

Por último los metodos de mi clase (en mi caso las Properties), tienen que implementar el modificador public virtual, para trabajar con NHibernate, y que este pueda realizar lazy loading.

Este sería un ejemplo de una clase sensilla:


Ahora pasemos a escribir nuestro xml para mapear este objeto.

Al comienzo del archivo estamos indicando el nombre del assembly "NHibernate_1", donde van a estar nuestras clases. Luego el namespace de dicha clase, y comenzamos a tratar las características de la clase que queremos mapear con el atributo class, en este caso Vehiculo. Dentro de los tags <class name="Vehiculo"...> ... </class> vamos a poner todas las configuraciones de dicha clase. Un atributo que no hemos marcado en el mapping pero que viene activado por defecto y vale la pena explicarlo es lazy="true". Con esto activamos el lazy load, de modo que las colecciones no se cargarán hasta que sean utilizadas. Este funcionamiento se logra mediante un proxy y NH se encarga de manejarlo, para nosotros es transparente (por ahora).

Con el tag <id> vamos a indicarle a NH qué property se mapeará con la clave primaria de la tabla, en este caso la property id se va a corresponder con la columna IdVehiculo, será de tipo int y para indicar que un objeto se considera como nuevo y no como que ya existe en la base, pondremos el atributo unsaved-value="0". Tambien hemos asignado al generator el valor identity, con esto le decimos a Hibernate que se encargue de generar los valores de la primary key. Si hubiéramos querido asignarles nosotros el valor, deberíamos reemplazar por el valor assigned. Luego le vamos a decir que la propiedad cantPuertas tiene que corresponderse con el atributo cantPuertas, y lo mismo para cantRuedas.

Con esto ya tenemos nuestro archivo para mapear nuestro objeto.

Lo que debemos hacer ahora es escribir nuestro archivo de configuración para que Hibernate pueda operar con nuestra base de datos. En este ejemplo voy a utilizar SQL Server 2005, desde ya que pueden utilizar cualquier otro motor, como Oracle, MySql, etc.


No hay mucho que explicar, copienlo tal cual, y en todo caso lo único que deberían modificar es el connection_string, para indicar los datos de acceso hacia su base de datos. Este archivo de configuración viene con la versión de NHibernate, por lo que con copiarlo, agregarlo a su proyecto y por último hacer las modificaciones necesarias es suficiente.

Muy bien, ahora continuemos con la instanciación de nuestro objeto, y la persistencia del mismo dentro de nuestra BD.


Como primer paso instanciamos un objeto de la clase Configuration, y le pasamos al metodo Configure, el nombre de nuestro archivo de configuración. En este caso es hibernate.cfg.xml.

Como podran observar creé un metodo que se llama CrearTablas, y que recibe la configuracion que instanciamos. Esto es basicamente, para no tener que ir a crear las tablas a mano a la base de datos, y que lo haga Hibernate por si mismo. Como ustedes quieran.

Continuamos instanciando un objeto de la clase ISessionFactory. Una sesión es un marco de trabajo en el cual NHibernate establece una conversación entre la aplicación y el motor de base de datos relacional. Para construir una sesión, representado por ISession alguien que nos provea la sesión, para esto necesitamos de: ISessionFactory. El ISessionFactory se encarga de crear sesiones en nuestra aplicación. En un momento, la aplicación puede tener 1 o más sesiones abiertas. Cada sesión representa un 1er. nivel de caché, los objetos que son traídos desde la base, o son guardados desde la aplicación se encuentran en la cache de primer nivel. Si se solicita un objeto a la base, primero se busca en la caché, si se encuentra ahí el objeto, se lo devuelve a la aplicación sin solicitarlo al motor. Sino se encuentra en la caché, se realiza la consulta a la base.
Por lo general debemos tener un ISessionFactory por aplicación, sería necesario tener más de uno en el caso de que estemos trabajando con más de una base de datos a la vez.

Instanciamos un objeto de nuestra clase Vehiculo. Le asignamos los valores que querramos, e invocamos al método Save() de nuestro objeto sesion, y le enviamos por parametros el objeto vh1, que es la instancia de nuestra clase Vehiculo. Mediante este metodo persistiremos nuestro objeto en nuestra base de datos.

Si queremos podemos ejecutar nuestro programa para ver los resultados.


Si observamos desde nuestro Motor.



Espero que les haya sido util y que puedan seguir investigando al respecto.

sábado, 18 de diciembre de 2010

Pautas para la Escritura de Requerimientos

Una de mis tareas, definidas en mi trabajo diario, es controlar requerimientos. Los requerimientos, normalmente son confeccionados por Analistas Funcionales, Consultores y Project Leaders.

Este control, se hace en pro de que los requerimientos estén bien redactados y con toda la información necesaria.

De tanto en tanto, me encuentro con requerimientos que no cumplen con las características que mencioné y es por ello que pretendo dejar una "guía", o como quieran llamarle, para que a la hora de redactar tengan en cuenta ciertos puntos básicos, pero fundamentales, a la hora de elaborar un requerimiento.

Si bien la mejor guía para escribir requerimientos es la experiencia… Existen una serie de pautas que pueden ayudar cuando la experiencia está gestándose…

- Escribir oraciones o párrafos cortos siguiendo apropiadamente las reglas gramaticales y ortográficas y cuidando la puntuación.

- Usar la voz activa (“El actor tal ejecutará la función cual”).

- Utilizar los términos explicados en el glosario consistentemente.

- Utilizar el mismo nombre para cada cosa, consistentemente a lo largo de los documentos (Si se decidió por llamar al nuevo software “sistema” no utilizar sinónimos tales como “aplicativo”, “producto”, “software”, etc.)

- Evitar los condicionales (“debería”, “podría”, etc.).

- Utilizar figuras, gráficos y tablas para presentar la información visualmente. La lectura es más interesante si se evitan los párrafos largos y densos de texto exclusivamente.

- Evitar el lenguaje ambiguo.

- Escribir en positivo evitando el negativo (“El sistema hará” y no “El sistema no hará”)

Aceptable, adecuado: definir qué constituye lo “aceptable” o “adecuado” en términos mensurables y verificables.
Ya que entre las pautas que escribí, coloque el tema de la ambigüedad, les voy a dejar un detalle de lo que normalmente veo redactado y como debería redactarse. Suena autoritario, pero léanlo y después me dicen.

Como van a observar, parece que me estoy yendo a un extremo, pero la realidad es que la especificación de requerimientos, luego es leída por el cliente. Imagínense, que ustedes van a adquirir un servicio, y le digan: "El servicio anda muy rápido". Francamente, no se ustedes, "Muy Rápido" para mi pueden ser 2 segundos, y quizás lo que a ustedes les parece "Muy Rápido", en realidad sean 10 minutos. Sin embargo, si me dicen "El servicio tiene un tiempo máximo de 2 minutos, y un tiempo mínimo de 1 minuto", no se da lugar a la libre interpretación. Y por supuesto, nuestro argumento no solo es mas serio, si no que también puede ser plenamente comprobable.

Les dejo entonces algunos terminos con los que frecuentemente me encuentro, y como podriamos hacer para reemplazarlos.


Como mínimo, al menos, como máximo, como mucho: especificar los valores máximos y mínimos aceptables.

Dependiendo de: definir la naturaleza de la dependencia describiendo si se trata de una precondición, de una condición previa mandatoria, si la dependencia es ocasional, etc.

Eficiente, rápido, flexible: definir cada una de estas características y asignarles rangos mensurables y verificables.

Mejor, superior, mejorado: cuantificar cuán superior o mejor será en el nuevo sistema en qué módulo y para qué clase de usuario. 

Idealmente, normalmente: describir las situaciones ideales o normales y no olvidar describir también las condiciones de anormalidad.

Opcionalmente: clarificar si se trata de una decisión que tomará el sistema o el usuario y explicar las alternativas u opciones posibles.

Razonable, cuando sea necesario, cuando sea apropiado: describir cómo se evalúan estas características en términos mensurables y verificables.

Tablas PL/SQL [Parte 2]

Continuando con la temática del posteo anterior, les voy a dejar lo que resta para cerrar el tema de nested table.


Como he mencionado en la Parte 1, una tabla anidada se puede almacenar como una columna de una tabla. Para esto hay que definir la tabla anidada con la orden CREATE TYPE para crear el tipo de la tabla anidada en lugar de TYPE.

Ejemplo:

CREATE TYPE inf_libro AS OBJECT(titulo varchar2(40),
                                nombre_autor varchar2(40),
                                isbn number);

CREATE TYPE isbn_libros AS TABLE OF inf_libro;

CREATE TABLE prestamo(fecha_entrega date,
                      nro_socio number(10),
                      libros_prestados isbn_libros)
NESTED TABLE libros_prestados STORE AS prestados_tabla;

Una tabla anidada almacenada en una tabla de la base de datos se puede manipular en su integridad o pueden manipularse sus filas individuales. Cualquiera de los dos casos, se pueden utilizar órdenes SQL. El índice de la tabla anidada sólo puede utilizarse cuando la tabla está en PL/SQL.

Para insertar una fila en una tabla anidada se utiliza la orden INSERT. Hay que tener en cuenta que la tabla se crea e inicializa en PL/SQL y después se inserta en la base de datos.

Ejemplo:

DECLARE
    libros isbn_libros := isbn_libros(inf_libro('Libro 1', 'Autor1',1234));
BEGIN
    INSERT INTO prestamo VALUES (sysdate, 12, isbn_libros(inf_libro('Libro 2', 'Autor 2',1234),
                                                               inf_libro('Libro 3','Autor 3',3456)));
    INSERT INTO prestamo VALUES (sysdate, 24, libros);
END;
De forma similar, se utiliza UPDATE para modificar la tabla almacenada
Ejemplo:

DECLARE
    libros isbn_libros := isbn_libros(inf_libro('Libro 1',
                                                'Autor 1',
                                                1234567),
                                      inf_libro('Libro 2',
                                                'Autor 2',
                                                 1234));
BEGIN
    UPDATE prestamo
    SET libros_prestados = libros
    WHERE nro_socio = 24;
END;
/

Con DELETE puede eliminar una fila que contenga una tabla anidada.

Ejemplo:

BEGIN
    DELETE FROM prestamo WHERE nro_socio = 24;
END;
/

Cuando se recupera una tabla anidada en una variable PL/SQL, se asignan claves comenzando por 1 hasta llegar al número de elementos que contiene la tabla. Este valor puede determinarse mediante el método COUNT, el cual devuelve un número entero correspondiente al número de elementos que tiene actualmente la colección.

Ejemplo:

DECLARE
    libros isbn_libros;
    i NUMBER;
BEGIN
    SELECT libros_prestados INTO libros FROM prestamo WHERE nro_socio=12;
    FOR i IN 1 .. libros.count LOOP
        DBMS_OUTPUT.PUT_LINE('Título: ' || libros(i).titulo|| ' del elemento: '|| i);
    END LOOP;
END;
/

jueves, 16 de diciembre de 2010

Tablas PL/SQL [Parte 1]

Para aquellos que programan en algún lenguaje (lo que estoy diciendo es una obviedad pero es solo por dar un ejemplo didáctico), apuesto a que trabajaron con vectores, también llamados arrays, matrices, n-uplas, etc.  Que no son más que sectores de almacenamiento contiguo para datos de un mismo tipo.
Seguramente se habrán dado cuenta, que no es más que un concepto adoptado del análisis vectorial. Para los que no tuvieron “el placer” de toparse con materias como Análisis Matemático, Álgebra y Geometría Analítica, Física, etc. les comento que el concepto de vector, es puramente Matemático.
Así como estos casos tenemos unos cuantos, y ya que estamos hablando de Bases de Datos, tenemos el claro ejemplo del álgebra de conjuntos. Les aclaro que yo era uno de los que, durante las clases de Matemática, hacia la típica pregunta “Y esto que aplicación tiene??”. Era obvio que no iba a obtener ninguna respuesta de un profesor que se dedicaba a enseñar Matemática en la carrera de Ingeniería. Así que con el tiempo me fui dando cuenta solo (Si bien nunca me pidieron que desarrolle un programa para calcular el flujo  a través de un campo eléctrico con el teorema de Gauss, y que no me pondría a hacer salvo que me presenten un maletín con 200 millones de dólares).
Llendo a la temática de este post, los vectores, así como los podrán utilizar en C, C++, Pascal, etc. También existen en el lenguaje de programación que utiliza Oracle, que es el PL/SQL.
Para comenzar nos vamos a remontar a las tablas PL/SQL. Estas tablas son básicamente un array, y tienen dos componentes: una clave primaria del tipo BINARY_INTEGER para indexarla y otra columna que permite guardar los escalares o registros. Cabe destacar que estas estructuras son dinámicas.
Para manejarlas, lo primero que tenemos que hacer es declarar el tipo de dato.

TYPE nombre_tipo_tabla IS TABLE OF
{tipo_columna | variable%TYPE | tabla.columna%TYPE}[NOT NULL]
INDEX BY BINARY_INTEGER ;

Lo que acabamos de declarar es un tipo tabla, que va a ser el tipo de nuestra variable. Por lo que luego, nuestra declaración no varía en nada a la declaración formal de cualquier variable en PL/SQL:

nombre_var nombre_tipo_tabla;

Si queremos referenciar a un elemento de la tabla, sería como si de un vector se tratase:

Pl/sql_nombre_tabla(valor_primary_key);

El rango de binary integer es –2147483647.. 2147483647, por lo tanto el índice puede ser negativo, lo cual indica que el índice del primer valor no tiene que ser necesariamente el uno.


También es posible declarar los famosos “Tipo Registro”, conocidos como struct en C, como record en Pascal. Y este tipo registro puede ser tranquilamente el tipo de dato de nuestra tabla PL/SQL. Y el concepto es prácticamente el mismo que en los lenguajes de programación mencionados, o sea, tendría mi tipo vector, cuyo tipo de dato seria de un tipo de registro que haya definido. Por lo que en cada posición del vector voy a poder guardar datos de ese tipo registro. Qué ventaja me da esto, que con las posibilidades que me ofrecen los tipos record, podría guardar varios datos, de distinto tipo dentro de las posiciones de un vector. Análogamente para PL/SQL.
Con la llegada de Oracle 8 PL/SQL añade dos tipos de colecciones, las tablas anidadas y los VARRAY. Cada uno con sus atributos y métodos (muy similar a lo que es un objeto en cualquier lenguaje de programación orientada a objetos).
En sí, las tablas anidadas son muy similares a las tablas PLSQL que acabamos de ver. Con la diferencia de que estas incluyen métodos de colección adicionales, que las tablas PL/SQL no tenían, ni tienen. Por otro lado también se abre la posibilidad de guardar una tabla anidad, dentro de una tabla en la base de datos. Digamos, puedo tener una tabla, que posea un campo cuyo dominio sea el mismo que mi tipo tabla, y dentro de ella tranquilamente podría persistir ese dato.
Su declaración es muy simple:
TYPE nombre_tabla IS TABLE OF tipo_tabla [NOT NULL];
Como podrán observar desaparece la clausula para la indexación, que tenían las anteriores, que es BINARY_INTEGER.
Una vez que creamos el tipo, la declaración de nuestra variable es análoga a cualquier otra declaración. Y por supuesto que en la declaración de nuestra variable, podemos inicializarla, como si se tratase de una variable “varchar”, por mencionar un ejemplo, con la diferencia de que para el caso de las nested tables, su inicialización se realiza a través del constructor de la misma.
Un simple ejemplo seria:
DECLARE
    TYPE tabla_numero IS TABLE OF NUMBER;
    var_tabla_1 tabla_numero := tabla_numero(0);
    var_tabla_2 tabla_numero := tabla_numero(1, 2, 3, 4);
    var_tabla_3 tabla_numero := tabla_numero();
    var_tabla_4 tabla_numero;
BEGIN
    var_tabla_1(1):= 123;
    DBMS_OUTPUT.PUT_LINE('Valor 1 de var_1: ' || var_tabla_1(1));
    DBMS_OUTPUT.PUT_LINE('Valor 1 de var_2: ' || var_tabla_2(1));
    IF var_tabla_3 IS NULL THEN
        DBMS_OUTPUT.PUT_LINE('var_tabla_3 SI es NULL');
    ELSE
        DBMS_OUTPUT.PUT_LINE('var_tabla_3 NO es NULL');
    END IF;
    IF var_tabla_4 IS NULL THEN
        DBMS_OUTPUT.PUT_LINE('var_tabla_4 SI es NULL');
    ELSE
        DBMS_OUTPUT.PUT_LINE('var_tabla_4 NO es NULL');
    END IF;
END;
/
Por supuesto que la inicialización no es obligatoria, y si la obviamos tendríamos una tabla sin elementos.
Cuando se inicializa una tabla utilizando el constructor, los elementos de la tabla se numeran secuencialmente desde 1 hasta el número de elementos especificado en la llamada al constructor. En caso de borrado en una tabla anidada de la base de datos, las claves se reenumeran para seguir siendo secuenciales.

Un ejemplo:

DECLARE
    TYPE tabla_numero IS TABLE OF NUMBER;
    var_tabla_2 tabla_numero := tabla_numero(10, 20, 30, 40);
BEGIN
    DBMS_OUTPUT.PUT_LINE('Nro elem de var_tabla_2: ' || var_tabla_2.count);
    DBMS_OUTPUT.PUT_LINE('Primer elem: ' || var_tabla_2.first);
    DBMS_OUTPUT.PUT_LINE('Último elem: ' || var_tabla_2.last);
END;
/

La salida será:
Nro elem de var_tabla_2: 4
Primer elem: 1
Último elem: 4
Aunque las tablas no tienen un tamaño fijo, no se puede asignar un valor a un elemento que todavía no existe. Para poder añadir elementos hay que utilizar el método EXTEND (que ya lo veremos en otro momento).

Ejemplo:

DECLARE
    TYPE tabla_numero IS TABLE OF NUMBER;
    var_tabla_2 tabla_numero := tabla_numero(10, 20, 30, 40);
BEGIN
    var_tabla_2 (1) := 50;
    DBMS_OUTPUT.PUT_LINE('Primer elemento de var_tabla_2: ' || var_tabla_2(1) );
END;
/



La salida es:
Primer elemento de var_tabla_2: 50
Procedimiento PL/SQL terminado con éxito.

Pero si pongo:

DECLARE
    TYPE tabla_numero IS TABLE OF NUMBER;
    var_tabla_2 tabla_numero := tabla_numero(10, 20, 30, 40);
BEGIN
    var_tabla_2 (1) := 50;
    DBMS_OUTPUT.PUT_LINE('Primer elemento de var_tabla_2: ' || var_tabla_2(1) );
    Var_tabla_2 (5) := 60;
    DBMS_OUTPUT.PUT_LINE('Quinto elemento de var_tabla_2: ' || var_tabla_2(5));
END;
/

Salida:
Primer elemento de var_tabla_2: 50
DECLARE
*
ERROR en línea 1:
ORA-06533: Subíndice mayor que el recuento
ORA-06512: en línea 7
Para la próxima parte, concluiremos con este tema hablando sobre algunos aspectos adicionales pero no menos importantes sobre las nested tables.

 

miércoles, 15 de diciembre de 2010

Archivos .ini con Java

Si bien la utilización de archivos .ini ha quedado en la historia, por sus desventajas en cuanto a la portabilidad, por las facilidades que nos ofrece el formato XML, etc. Hasta el día de hoy encuentro aplicaciones que los utilizan.
Haciendo un poco de memoria, los archivos ini, surgieron con la llegada de Windows 3.1. Aquel “Sistema Operativo”, de Microsoft, que corría sobre el Sistema Operativo, MS-DOS.
El sistema contaba con dos archivos de inicialización, en donde alojaba los valores para iniciar el sistema. De ahí el nombre para la extensión “INI”, ya que proviene de “Windows Initialization File”.
Por supuesto que estos archivos también pueden utilizarse para alocar una serie de parámetros que pueden ser utilizados por cualquier sistema. Java entre sus bastas posibilidades, nos permite utilizar estos archivos en nuestras aplicaciones.
El único riesgo que corremos, es a la hora de migrar nuestra aplicación hacia otro sistema operativo ya que este formato, es de uso exclusivo por Windows, lo que hace algo paradójico desarrollar una aplicación en Java, utilizando este formato, ya que se supone que las grandes ventajas que me ofrece el lenguaje es la portabilidad (siempre y cuando deseemos migrar). Si este es el caso, para evitar grandes cambios, deberíamos usar un archivo de properties de java. Es básicamente lo mismo que un archivo ini.
Vamos a ver cómo podemos manejar este formato, desde una simple aplicación:
Lo primero que vamos a establecer es la estructura de nuestro archivo:
Lo que se encuentra encerrado entre corchetes, representa a las Secciones, donde podemos agrupar una serie de parámetros. Las líneas que siguen a la sección, se la denominan Valores, allí es donde definimos nuestro Parámetro y su valor.
Ahora veamos como seria nuestro código en lenguaje Java. Para ello, voy a utilizar un ejemplo básico.
Primero voy a crear la clase “ArchivoIni”. Esta clase va a constar de dos Atributos, uno va a contener los parámetros que lea del ini, y el otro la ruta del archivo.
Como se puede observar mi primer atributo, es de la clase Properties, que nos provee el paquete java.util. Por lo que debemos importar este paquete: import java.util.Properties.
En el constructor que definí para la clase, invoco al método para setear la ruta del archivo.
A continuación, definimos un método para la lectura del archivo.
Como se puede observar, para "cargar" los parámetros que contiene mi archivo ini, invoco al metodo load(), de la clase Properties.
Por ultimo los métodos restantes
Ahora que tenemos nuestra clase, hagamos una prueba
Lo ejecutamos para ver el resultado

En nuestra clase IniPrueba instanciamos un objeto de la clase ArchivoIni, enviándole por parámetros, al constructor de la clase, la ruta en donde se encuentra el archivo. Por último invocamos al método leer archivo e imprimimos el valor de un parámetro, invocando al método getValorParametro(), al cual le pasaremos el nombre del parametro cuyo valor deseamos obtener.
Por supuesto que este es un ejemplo básico, del cual ustedes podrán sacar provecho, e investigar aún más.

martes, 14 de diciembre de 2010

Con chiche nuevo


Hace tiempo, que vengo  probando diferentes herramientas para administración de Bases de Datos, y particularmente ninguna llegaba a brindarme lo que necesito a la hora de trabajar.
Casualmente, luego de desistir en mi búsqueda de un sistema que realmente me permitiera trabajar cómodamente, y resignarme a sistemas como el de la compañía Embarcadero, DbArtisan, mortificarme con SQL Developer de Oracle y otros más que fui testeando, me topé con esta aplicación que llamo mucho mi atención.

DbVisualizer es una herramienta muy interesante a la hora de trabajar con bases de datos. Es una aplicación desarrollada en lenguaje Java, por lo que nos brinda la posibilidad de ejecutar el aplicativo en distintas plataformas, y viene en su versión gratuita y paga (Free y Personal, según lo menciona la pagina oficial). La versión Gratuita, nos provee una amplia variedad de posibilidades, sin embargo para una administración más intensiva, es recomendable la versión paga.
Algo que me gustó mucho, a la hora de trabajar con bases de datos Oracle, fue que no necesitaba tener el cliente instalado, esto se debe a que la aplicación trabaja con drivers jdbc para conectarse, por lo que lo único que necesitamos es importar el driver correspondiente e indicarle los datos de conexión. La única contra de este aspecto, es que hay que introducir el string o url de conexión a mano, para poder establecer conectividad con la base de datos, que para los que jamás establecieron una conexión desde java a una instancia de Oracle, Sql, MySql, etc, puede resultar algo confuso.

Otro dato, no menos importante, es que puede editarse directamente el contenido de las tablas. Por ejemplo, para personas que no están familiarizadas con el DML, y necesitan modificar datos persistidos en tablas, este nos brinda la posibilidad de hacer la edición de la misma forma que uno puede editar una celda en Excel. Ni hablar de los que, no tienen ni la menor idea de cómo se realiza una consulta en lenguaje SQL, o de los que se pelean con los dichosos “joins”, para estos casos provee una interfaz gráfica, con la que lo único que haremos es localizar las tablas del árbol en donde se encuentran, volcarlas en una ventana, al mejor estilo “drag & drop”, y hasta establecer las relaciones que creamos necesarias mediante simples clics. Como plus, un editor de stored procedures, magnífico.







Para concluir, DbVisualizer es un sistema bastante liviano, al contrario de otros , como, otra vez menciono el ejemplo de DBArtisan, que dependiendo lo que hagamos, si no poseemos amplios recursos de hardware puede derivar en errores de insuficiencia de memoria, que nos provoquen el cuelgue de la aplicación y por consiguiente la pérdida de lo que estabamos haciendo.

Pueden obtener más información en su página oficial: http://www.dbvis.com/