Sunday, March 23, 2008

Programando en java ...

Hola a todos, en esta ocasión les voy a hablar acerca de una pequeña experiencia que tuve al hacer un programita el cual desarrolle en java, el programa se trataba básicamente de un pequeño administrador de bases de datos, lo único que tenia que hacer era visualizar todas las bases que se encontraban en el manejador de BD en cuestión (postgresql, mysql, oracle, informix, etc.), una vez visualizadas todas las BD, podían elegir entre las diferentes bases de datos y elegir una, a continuación tenia que mostrar las tablas que contenía esta base de datos, ya visualizadas estas podíamos elegir entre alguna de ellas, y se mostraría los atributos que esta tabla contenía, entre los cuales destaca, llave primaria, llave(s) foráneas, tipos de datos de los campos, etc.

Pues bien lo primero que se hizo fue definir sobre que manejador trabajaríamos como base para realizar el programa y la elección fue trabajar con postgresql, para realizar el código me tuve que valer de información en Internet y sobre todo de la documentación de java (que dicho sea de paso recomiendo siempre tenerla al lado cada vez que programamos en java), lo primero que hice fue resolver el primer problema el cual era poder mostrar todas las bases de datos (omitiré la instalación de postgresql y otros detallitos), así que me hize del conector de java para postgres (puede ser algún otro y de esta forma poder disponer entre varios manejadores de base de datos) logre conectarme a una base de datos ya existente, esto se tiene que hacer antes para poder usar las clases que veremos mas adelante, este paso lo tuve que hacer usando alguna base de datos ya existente, así que utilice una que es usada por defecto “template1” (por rapidez tuve que utilizar esta artimaña pero si encuentran una mejor forma de hacer esto pues ahí me avisan, ;) ) después lo que hice fue buscar entre las múltiples clases que ofrece java la que pudiera suplir este detallito, y en resumidas cuentas quedo mas o menos así:

ResultSet R;DatabaseMetaData dbm;

Obj.j=new JComboBox();

dbm=C.db.getMetaData();

R=dbm.getCatalogs();

while(R.next())

{

Obj.j.addItem(R.getString(1));

System.out.println("here");

}

R.close();st.close();C.db.close();

Lo primero que se tiene que hacer es conectarse de alguna forma a una base de datos, posteriormente. En la parte de arriba declaro un ResultSet el cual contendrá los resultados de un Query, y posteriormente un objeto DatabaseMetaData que es el que contendrá metadatos acerca de la base de datos a la cual hace referencia la conexión, instancia un ComboBox y después instancia el dbm al hacer esto dbm contiene metadatos sobre la base de datos, pero lo que nos interesa es el nombre de todas las bases así que aplicándole el método getCatalogs obtengo el nombre de las bases de datos, después cierro las conexiones.

Ahora necesito saber las tablas que puede tener una base de datos en específico, la función que realiza eso es la siguiente:

void cargar_tablas(String base)

{

try{

/*Se realiza una nueva conexión a la base elegida*/

new C(base);

if(Obj.Fallo==false)

{

ResultSet R;Statement st;DatabaseMetaData dbm;

Obj.j2=new JComboBox();

st=C.db.createStatement();

dbm=C.db.getMetaData();

String tipos[] = {"TABLE"};

R=dbm.getTables(null,null,null,tipos);

while(R.next())

{

String a=R.getString("TABLE_NAME");

Obj.j2.addItem(a);

System.out.println(a);

}

R.close(); st.close(); C.db.close();

}

}catch(Exception ex){System.err.println("Exception caught.\n"+ex);ex.printStackTrace();}

}

En esta función se recibe como parámetro la base de datos elegida y se pega en un JComboBox las tablas que se encuentran en dicha base, es algo similar a la función anterior pero aquí hacemos un paso diferente ya que en lugar de utilizar el método getCatalogs, usamos el método getTables el cual recibe parámetros los cuales son (catalogo, patrón esquema, patrón del nombre de la tabla, tipos), todos a excepción del ultimo que recibe como parámetro un arreglo de Strings reciben un String, a este método se le envían como parámetros null en los primeros tres parámetros (mayor información consultar documentación de java) y al final un arreglo donde se especifica el tipo de dato que requerimos el cual es una tabla.

Como paso final necesitamos saber los datos de la tabla señalada previamente esta función queda así:

void cargar_info_tablas(String tabla,String base)

{

try{

/*Se realiza una nueva conexion a la base elegida*/

T.setText("");

int c=0;

Statement st;ResultSet R;DatabaseMetaData dbm,dbm2;

st=C.db.createStatement();

dbm=C.db.getMetaData();

dbm2=C.db.getMetaData();

System.out.println("Testeando la tabla :"+tabla);

T.append("\n****** LLave Primaria ******\n");

ResultSet rx=dbm2.getPrimaryKeys(base,null,tabla);

while(rx.next())

{

T.append("Nombre de la Tabla ="+rx.getString(3)+"\n");

T.append("Nombre de la Columna ="+rx.getString(4)+"\n");

}

T.append("\n****** LLaves Foraneas ******\n");

ResultSet rf=dbm2.getImportedKeys(base,null,tabla);

while(rf.next())

{

T.append("Tipo ="+rf.getString(2)+"\n");

T.append("Tabla a la que importa ="+rf.getString(3)+"\n");

T.append("Nombre de la columna ="+rf.getString(8)+"\n");

}

R=dbm.getColumns(base, null, tabla, null);

while(R.next())

{

c++;

T.append("\n****** Caracteristicas de las columnas "+c+" ******\n");

T.append("Categoria de tabla :"+R.getString(1)+"\n");

T.append("Esquema de la tabla :"+R.getString(2)+"\n");

T.append("Nombre de la tabla :"+R.getString(3)+"\n");

T.append("Nombre de la columna :"+R.getString(4)+"\n");

T.append("Tipo de dato :"+R.getString(5)+"\n");

T.append("Tipo de nombre :"+R.getString(6)+"\n");

T.append("Tamaño de la columna :"+R.getString(7)+"\n");

T.append("Digitos decimales :"+R.getString(9)+"\n");

T.append("Es Nulo (1=si/0=no) :"+R.getString(11)+"\n");

T.append("Longitud del Octeto de valor char :"+R.getString(16)+"\n");

}

}catch(Exception ex){System.err.println("Exception caught.\n"+ex);ex.printStackTrace();}

}

Las partes que mas destacan de la función anterior son las siguientes:

En la siguiente línea de código el objeto DatabaseMetaData que en este caso es dbm2 utiliza el método “getPrimaryKeys” para obtener la llave primaria de la tabla, los parámetros que le mandamos son: la base de datos, después un valor nulo, posteriormente la tabla a que nos referimos, el resultado lo concentramos a un objeto ResultSet para su uso.

ResultSet rx=dbm2.getPrimaryKeys(base,null,tabla);

La siguiente línea a destacar es esta, en la cual se realiza lo mismo que con la anterior pero esta se refiere a las llaves foráneas.

ResultSet rf=dbm2.getImportedKeys(base,null,tabla);

Esta es la ultima línea de código que a mi juicio merece ser mencionada, en ella se obtiene toda la información detallada de la tabla, datos que la verdad ni siquiera sabia que podía existir en una tabla, merece examinarse a fondo (echen una checada en la documentación, ya que aquí no hay espacio). El método “getColumns” del objeto dbm (el cual es un objeto de la clase DatabaseMetaData) arroja información detallada de la tabla, se le pasa como parámetro la base de datos, un valor nulo la tabla en cuestión y otro valor nulo (nuevamente persisto en que le den un vistazo a la documentación).

R=dbm.getColumns(base, null, tabla, null);

Bueno eso es todo, se que hubo muchas cosillas que no pude explicar, asi que confio en que la mayoria tiene un cierto grado de programacion y muchas ganas de aprender, asi que espero que les ayude en algo.


Saludos .......


No comments: