4 Presentation of the results
C- F Role Models
En este tema no se pretende enseñar a construir una base de datos en access, lo que se pretende es conectar la base de datos a su traductor o driver ODBC.
Primero deberan crear un folder en el disco C:\, en mi ejemplo le puse base (muy original), cargar access y crear una base de datos y guardarla en el folder antes mencionado,( yo le puse mibase.mdb), ya creada la base, crearle una tabla con los campos apropiados y grabarla (yo le puse tabla, con campos clave, nombre,edad).
Cargarle algunos registros o renglones de prueba para la tabla. Salirse de access y cargarle el driver odbc, procedimiento:
Nota: este procedimiento depende de la version de windows que se este usando, yo uso win2000, pero es muy similar(no igual) para todos los windows.
1.- Abrir control panel y se encuentran una opcion que dice algo de data sources y odbc.(en win2000 se encuentra dentro de administrative tools).
2.- Abrir data sources:
Observar que hay drivers para access 97 y access mas nuevos, yo uso access 97. En otros windows, esta pantalla sale despues que se usa user dsn (creo).
3.- Usarla opcion ADD (debe estar seleccionado el driver apropiado),y aparece la siguiente pantalla.
Observar que se vuelve a seleccionar el driver de access. 4.- Usar opcion finish y sale la siguiente pantalla:
En Data Source Name, solo escribir el nombre de la base de datos.
Luego usar el boton select, para que salga la pantalla de busqueda de archivos normal de windows, buscar el folder, seleccionar la base de datos y ok, ahora debe verse el path completo en esta pantalla(donde dice Database: C:\base\mibase.mbd).
La diferencia con la pantalla original, es que ya esta registrada la base, y ya tiene asignado su driver odbc.
Tarea Java armar su base de datos con una tabla y registrarle un driver odbc. JAVA TEMA 3: CONSULTA SQL SELECT
Empezamos por un programa-servlet que lee y despliega la tabla que esta en la base de datos construida en el JAVA TEMA anterior:
La instruccion basica de SQL a usar es: SELECT * FROM MITABLA;
Codigo.html <HTML>
<FORM ACTION=http://192.168.1.133/servlet/prog38 METHOD=POST> <INPUT TYPE=SUBMIT VALUE=OK>
</FORM></HTML>
No olvidar que tambien la base de datos ya debe estar enlazada a su odbc driver. Codigo java
import java.io.*; import java.util.*; import java.net.*; import java.sql.*; import javax.servlet.*; import javax.servlet.http.*;
public class prog38 extends HttpServlet { static Connection canal = null;
static ResultSet tabla= null; static Statement instruccion=null;
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
canal=DriverManager.getConnection("jdbc:odbc:mibase", " ", " ");
instruccion = canal.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
} catch(java.lang.ClassNotFoundException e){} catch(SQLException e) {}; response.setContentType("text/html");
try { tabla = instruccion.executeQuery("select * from tabla"); PrintWriter pagina =response.getWriter();
pagina.println("<HTML><HEAD><TITLE>MI SERVLET</TITLE></HEAD>"); pagina.println("<P ALIGN="+"CENTER"+">MI TABLA</P>");
pagina.println("<P ALIGN="+"CENTER"+">CLAVE NOMBRE EDAD</P>"); pagina.println("<DIV ALIGN="+"CENTER"+"><CENTER>"); pagina.println("<TABLE BORDER="+"1"+">"); while(tabla.next()) { pagina.println("<TR>"); pagina.println("<TD>"+tabla.getString(1)+"</TD>"); pagina.println("<TD>"+tabla.getString(2)+"</TD>"); pagina.println("<TD>"+tabla.getString(3)+"</TD>"); pagina.println("</TR>"); }; // fin while
pagina.println("</TABLE></CENTER></DIV></HTML>"); pagina.close();
tabla.close(); } //fin try no usar ; al final de dos o mas catchs catch(SQLException e) {};
destroy();
try {canal.close();} catch(SQLException e) {}; };//fin dopost
public void destroy() {super.destroy();}; } //fin clase
notas:
Observar todos los Imports
Se empiezan creando tres variables, una de tipo conección llamado canal que se usara para enlazar los dos drivers.
La segunda variable de tipo ResultSet, llamada tabla que se cargara con la tabla que esta en la base de datos, es de recordar que esta tabla(no confundirla con la que esta en disco) no solo contendra todos los renglones de la tabla en disco, sino tambien toda la información asociada a esa tabla(cantidad y numero de columnas, tipos de datos, fonts, etc).
Una instrucción de tipo Statement, que tiene como finalidad contener el codigo SQL que se usara para comunicarse entre el programa en java y la base de datos en access.
El metodo post() normal que primero usa un try (siguiente nota de abajo) y luego otro try que crea la instrucción de tipo statement y luego la carga con el SQL, el resultado(la tabla de access que regresa) la almacenamos en la tabla.
Observar el try que activa el jdbcodbcdriver que usa java, y despues hacer la conección o enlaze con el odbc de la base, observar lo parametros con comillas en blanco, son el login y el password de la base hecha en access.
Es de tomar muy en cuenta que variables de tipo ResultSet (tabla ) tienen muchos metodos que seran muy utiles para el trabajo con tablas, en otras palabras, deberan estudiar con mucho
cuidado la clase ResultSet y sus metodos.
Despues se crea una pagina con una tabla html, para irla cargando con nuestra tabla.
Observar que se usa un ciclo while(tabla.next()) para recorrer todos los renglones de nuestra tabla, es importante tambien recordar que en cuento llega de regreso la tabla en access y se carga en nuestra tabla en memoria, un apuntador de renglones queda en la posición anterior o arriba de todos los renglones, por eso el primer next()(metodo de resultset), nos lleva al primer renglon real de la tabla.
Observar que se usa el metodo getString(NUMERO O "NOMBRE COLUMNA"), tambien de ResultSet, para ir leyendo y desplegando el dato en la tabla html.
Es muy importante entender que cuando se abre una sesion o canal entre java y access debera cerrarse tambien y tambien es muy importante entender que por esa sesion o canal solo se podra
inyectar una y solo una instruccion de sql, aunque java provee de mecanismos que permiten inyectar un grupo de instrucciones de sql, pero estos mecanismos se veran para el siguiente curso de java que se de.
Corrida:
TAREAS PROGRAMACION JAVA SERVLET
Hacer java servlets de lectura y despliegue, para las tablas hechas. JAVA TEMA 4: INSERCCION SQL INSERT
Recordar que en base de datos, la operacion de agregar renglones o registros recibe el nombre de insercción.
La instrucción basica de SQL a usar es:
insert into tabla values (10, 'lauro','tijuana', 821055);
// y se usa executeUpdate se usa para insert, update y delete
Otro elemento importante a recordar es que se ocupan claves de preferencia numericas y consecutivas, por esta razon en el diseño de la base de datos en access se pidio que el campo clave fuese de tipo autonumber para que al ir agregando renglones access les fuese agregando la clave en forma consecutiva.
Como se resuelve este problema en java???
La solución que se propone en el programa ejemplo es primero abrir una sesion o canal en su propio procedimiento(se acuerdan de la penultima unidad del curso??), cargar la tabla en memoria con una instrucción select como se hizo en el ejemplo anterior, navegar al ultimo renglon tabla.last(), leer el valor de la primera columna en una variable entera llamada clave e incrementar esta variable en una unidad y listo ya tenemos la clave del siguiente renglon, no olvidar cerrar este canal o sesion( si se acuerdan que solo se puede inyectar una instruccion sql en una sesion- canal??).
Despues ya en una segunda sesion-canal, se hace el insert del SQL, como lo muestra el programa ejemplo.
Programa HTML <HTML>
<FORM ACTION=http://192.168.1.133/servlet/prog39 METHOD=POST> NOMBRE:<INPUT TYPE=TEXT NAME=NOMBRE><BR>
EDAD:<INPUT TYPE=TEXT NAME=EDAD><BR> <INPUT TYPE=SUBMIT VALUE=GRABAR> </FORM></HTML>
Observar que no se pide la clave al usuario. SERVLET
Codigo JAVA
import java.io.*; import java.util.*; import java.net.*; import java.sql.*; import javax.servlet.*; import javax.servlet.http.*;
public class prog39 extends HttpServlet { static Connection canal = null;
static ResultSet tabla= null; static Statement instruccion=null; static int clave=0;
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { //cargando clave en su propia sesion-canal cargarclave(); try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); canal=DriverManager.getConnection("jdbc:odbc:mibase", " ", " "); instruccion = canal.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); } catch(java.lang.ClassNotFoundException e){System.out.println("classnotfound");} catch(SQLException e) {System.out.println("error de enlace canal");}//fin try
response.setContentType("text/html"); //cargando los demas campos a grabar
String nombre = request.getParameter("NOMBRE"); //capturando y conviertiendo edad str-obj-var
Integer temp=Integer.valueOf(request.getParameter("EDAD")); int edad= temp.intValue();
// insert into tabla values(clave, 'nombre', edad);
String q="insert into tabla values(" +clave +",'"+ nombre+"',"+edad+") "; try { // agregando renglon (insert) y observar que es executeupdate() int n=instruccion.executeUpdate(q);
//avisando que se hizo la instruccion PrintWriter pagina =response.getWriter(); pagina.println("<HTML>");
pagina.println(n+"YA SE INSERTO, BACK PARA REGRESAR"); pagina.println("</HTML");
pagina.close(); } //termina try
catch(SQLException e) { System.out.println("error del sql probable mala instruccion sql"); }; //fin catch
destroy();
try {canal.close();} catch(SQLException e) {System.out.println("error el cerrar el canal");}; } ;//fin dopost
//construyendo procedimiento cargarclave() con su propia sesion-canal static void cargarclave(){
try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); } catch(java.lang.ClassNotFoundException e)
{System.out.println("no pude encontrar el driver"); }; //fin try
instruccion = canal.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
//select ocupa executequery()
tabla = instruccion.executeQuery("Select * from tabla"); // calculo de reng y/o clave
tabla.last(); int numreng=tabla.getRow(); tabla.beforeFirst(); clave=numreng+1;
instruccion.close(); canal.close();
} catch(SQLException ex){ System.out.println("error en sql"); };//fin try catch };//fin cargarclave()
//otro procedimiento
public void destroy() {super.destroy();}; }//fin clase prog39
Recordar que un programa bien documentado (como este que les estoy mostrando) es autoexplicativo
Corrida HTML
Corrida java (usando programa anterior prog38 para ver la insercción).
Cosntruir java servlets que inserten registros o renglones en sus tablas de su base de datos, seria bueno agregar la posibilidad de que cuando se avise de que ya se hizo la inserccion, se pudiese mandar llamar al programa que despliega lo tabla en disco (prog38).
JAVA TEMA 5: JAVA SQL SELECT BUSQUEDA
Uno de los procesos basicos con tablas es la llamada busqueda, en este proceso generalmente el usuario porporciona la clave del registro y entonces el programa o aplicación le despliega todos los datos del renglón.
Codigo html: <HTML>
<FORM ACTION=http://192.168.1.133/servlet/prog40 METHOD=POST> CLAVE:<INPUT TYPE=TEXT NAME=CLAVE><BR>
<INPUT TYPE=SUBMIT VALUE=BUSCAR> </FORM></HTML>
Codigo java:
import java.io.*; import java.util.*; import java.net.*; import java.sql.*; import javax.servlet.*; import javax.servlet.http.*;
public class prog40 extends HttpServlet { static Connection canal = null;
static ResultSet tabla= null; static Statement instruccion=null;
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
canal=DriverManager.getConnection("jdbc:odbc:mibase", " ", " ");
instruccion = canal.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
} catch(java.lang.ClassNotFoundException e){} catch(SQLException e) {}; response.setContentType("text/html");
//capturando clave a buscar
Integer temp=Integer.valueOf(request.getParameter("CLAVE")); int clave1= temp.intValue();
//buscando y recuperando try{
tabla= instruccion.executeQuery("Select * from tabla where clave ="+clave1+" "); PrintWriter pagina =response.getWriter();
pagina.println("<HTML><HEAD><TITLE>MI SERVLET</TITLE></HEAD>"); pagina.println("<P ALIGN="+"CENTER"+">MI TABLA</P>");
pagina.println("<P ALIGN="+"CENTER"+">CLAVE NOMBRE EDAD</P>"); pagina.println("<DIV ALIGN="+"CENTER"+"><CENTER>"); pagina.println("<TABLE BORDER="+"1"+">"); while(tabla.next()) { pagina.println("<TR>"); pagina.println("<TD>"+tabla.getString(1)+"</TD>"); pagina.println("<TD>"+tabla.getString(2)+"</TD>"); pagina.println("<TD>"+tabla.getString(3)+"</TD>"); pagina.println("</TR>"); }; // fin while
pagina.println("</TABLE></CENTER></DIV></HTML>"); pagina.close();
tabla.close(); } //fin try no usar ; al final de dos o mas catchs catch(SQLException e) {};
destroy();
try {canal.close();} catch(SQLException e) {}; };//fin dopost
public void destroy() {super.destroy();}; } //fin clase
Sencillo, se usa la instrucción SQL SELECT con una clausula where.
Se sigue usando el codigo de tabla completa de html, porque es indistinto que se despliegue un renglon o cien.
CORRIDA html:
corrida java:
tareas java seguir construyendo java servlets de busqueda para sus tablas y base de datos JAVA TEMA 6: FILTROS O CONDICIONES SQL SELECT
Como su nombre lo indica,en este proceso se pretende desplegar todo un conjunto de renglones que cumplan con la condición, por ejemplo se pide desplegar todos los alumnos de "sisJAVA TEMA s" o todos los empleados que sean de "sinaloa", etc.
En este caso el resultado es un conjunto de renglones de la tabla que cumplan la condición, simple o compuesta.
Codigo html: <HTML>
<FORM ACTION=http://192.168.1.133/servlet/prog41 METHOD=POST> EDAD >=<INPUT TYPE=TEXT NAME=EDAD><BR>
<INPUT TYPE=SUBMIT VALUE=BUSCAR> </FORM></HTML>
Codigo Java:
import java.io.*; import java.util.*; import java.net.*; import java.sql.*; import javax.servlet.*; import javax.servlet.http.*;
public class prog41 extends HttpServlet { static Connection canal = null;
static ResultSet tabla= null; static Statement instruccion=null;
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
canal=DriverManager.getConnection("jdbc:odbc:mibase", " ", " ");
instruccion = canal.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
} catch(java.lang.ClassNotFoundException e){} catch(SQLException e) {}; response.setContentType("text/html");
//capturando dato de filtro
Integer temp=Integer.valueOf(request.getParameter("EDAD")); int edad1= temp.intValue();
//filtrando, edad>=100 c/u puede ser un text en html try{
tabla= instruccion.executeQuery("Select * from tabla where edad >= "+edad1); PrintWriter pagina =response.getWriter();
pagina.println("<HTML><HEAD><TITLE>MI SERVLET</TITLE></HEAD>"); pagina.println("<P ALIGN="+"CENTER"+">MI TABLA</P>");
pagina.println("<P ALIGN="+"CENTER"+">CLAVE NOMBRE EDAD</P>"); pagina.println("<DIV ALIGN="+"CENTER"+"><CENTER>"); pagina.println("<TABLE BORDER="+"1"+">"); while(tabla.next()) { pagina.println("<TR>"); pagina.println("<TD>"+tabla.getString(1)+"</TD>"); pagina.println("<TD>"+tabla.getString(2)+"</TD>"); pagina.println("<TD>"+tabla.getString(3)+"</TD>"); pagina.println("</TR>"); }; // fin while
pagina.println("</TABLE></CENTER></DIV></HTML>"); pagina.close();
tabla.close(); } //fin try no usar ; al final de dos o mas catchs catch(SQLException e) {};
destroy();
try {canal.close();} catch(SQLException e) {}; };//fin dopost
public void destroy() {super.destroy();}; } //fin clase
Corrida html:
Corrida java:
tareas java sugeridas, construir dos o tres java servlets de filtro, en uno de ellos poner los tres inputs texts para que el usuario contruya completamente la condición.(suerte)
JAVA TEMA 7: BAJAS O ELIMINACION SQL DELETE
Baja o eliminación, es un proceso comun tambien con los registros o renglones de las tablas en las bases de datos.
Lo bueno es que existe la instruccion SQL DELETE solo observar bien el cambio que se hace en el execute.
Para todos los select vistos en los procesos se uso la instrucción executequery(instrucciónsql), pero para insert, delete y update se debera usar executeupdate(instrucciónsql).
Codigo Html: <HTML>
<FORM ACTION=http://192.168.1.133/servlet/prog42 METHOD=POST> CLAVE A ELIMINAR:<INPUT TYPE=TEXT NAME=CLAVE><BR> <INPUT TYPE=SUBMIT VALUE=DELETE>
</FORM></HTML> Codigo Java:
import javax.servlet.*; import javax.servlet.http.*; public class prog42 extends HttpServlet {
static Connection canal = null; static ResultSet tabla= null; static Statement instruccion=null;
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
canal=DriverManager.getConnection("jdbc:odbc:mibase", " ", " ");
instruccion = canal.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
} catch(java.lang.ClassNotFoundException e){} catch(SQLException e) {}; response.setContentType("text/html");
//capturando clave a eliminar
Integer temp=Integer.valueOf(request.getParameter("CLAVE")); int clave1= temp.intValue();
String borrar=" DELETE FROM tabla WHERE clave = "+clave1;
//executeUpdate se usa para insert, update y delete executequery para select //y en access cuando se construya la relación no olvidar poner en cierto //enforce relational integrity, cascade update y cascade delete
try{
//eliminando
instruccion.executeUpdate(borrar); PrintWriter pagina =response.getWriter(); pagina.println("<HTML>");
pagina.println("BORRADO BACK TO REGRESAR"); pagina.println("</HTML>");
pagina.close();
tabla.close(); } //fin try no usar ; al final de dos o mas catchs catch(SQLException e) {};
destroy();
try {canal.close();} catch(SQLException e) {}; };//fin dopost
public void destroy() {super.destroy();}; } //fin clase
Corrida html de eliminacion:
tareas java, servlets servlets y mas servlets de eliminación para todas sus tablas en la base de datos.
JAVA TEMA 8: EDICION O MODIFICACION SQL UPDATE
Tambien problema común en base de datos, modificar los datos de un renglón de la tabla es sencillo, porque se usa la instrucción UPDATE de SQL.
Lo dificil es la logica del programa:
Primero construir un programa html de busqueda por clave, que traiga el registro o renglon a modificar.
Segundo construir un primer servlet muy parecido al de busqueda con la unica diferencia que responde con una pagina html que despliega los datos de la tabla pero en un una forma dinamica <FORM> </FORM> esta forma dinamica le permitira al usuario editar o modificar los datos a su antojo, ya modificados los datos en esta forma se llamara a un segundo servlet.
Este segundo servlet captura los datos ya modificados o editados y utiliza la instrucción SQL UPDATE para hacer la actualización de la tabla en disco.
Codigo HTML: <HTML>
<FORM ACTION=http://192.168.1.133/servlet/prog43 METHOD=POST> CLAVE A MODIFICAR:<INPUT TYPE=TEXT NAME=CLAVE><BR> <INPUT TYPE=SUBMIT VALUE=BUSCAR>
</FORM></HTML>
Codigo servlet busqueda y pagina dinamica:
import java.io.*; import java.util.*; import java.net.*; import java.sql.*; import javax.servlet.*; import javax.servlet.http.*;
public class prog43 extends HttpServlet { static Connection canal = null;
static ResultSet tabla= null; static Statement instruccion=null;
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
canal=DriverManager.getConnection("jdbc:odbc:mibase", " ", " ");
instruccion = canal.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
} catch(java.lang.ClassNotFoundException e){} catch(SQLException e) {}; response.setContentType("text/html");
//capturando clave a modificar
Integer temp=Integer.valueOf(request.getParameter("CLAVE")); int clave1= temp.intValue();
//buscando y recuperando try{
tabla= instruccion.executeQuery("Select * from tabla where clave ="+clave1+" "); //recordar moverse al primer renglon
tabla.next();
PrintWriter pagina =response.getWriter(); pagina.println("<HTML>");
//construyendo forma dinamica, recordar que se insistio en no usar "" en html
pagina.println("CLAVE:<INPUT TYPE=TEXT NAME=CLAVE VALUE="+tabla.getString(1)+"><BR>");
pagina.println("NOMBRE:<INPUT TYPE=TEXT NAME=NOMBRE VALUE="+tabla.getString(2)+"><BR>");
pagina.println("EDAD:<INPUT TYPE=TEXT NAME=EDAD VALUE="+tabla.getString(3)+"><BR>"); pagina.println("<INPUT TYPE=SUBMIT VALUE=MODIFICAR>");
pagina.println("</FORM></HTML>"); pagina.close();
tabla.close(); } //fin try no usar ; al final de dos o mas catchs catch(SQLException e) {};
destroy();
try {canal.close();} catch(SQLException e) {}; };//fin dopost
public void destroy() {super.destroy();}; } //fin clase
Segundo servlet que actualiza tabla disco:
import java.io.*; import java.util.*; import java.net.*; import java.sql.*; import javax.servlet.*; import javax.servlet.http.*;
public class prog44 extends HttpServlet { static Connection canal = null;
static ResultSet tabla= null; static Statement instruccion=null; static int clave=0;
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
canal=DriverManager.getConnection("jdbc:odbc:mibase", " ", " ");
instruccion = canal.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
} catch(java.lang.ClassNotFoundException e){System.out.println("classnotfound");} catch(SQLException e) {System.out.println("error de enlace canal");}
response.setContentType("text/html"); //cargando los campos a modificar
Integer temp=Integer.valueOf(request.getParameter("CLAVE")); int clave1= temp.intValue();
String nombre = request.getParameter("NOMBRE"); //capturando y conviertiendo edad
temp=Integer.valueOf(request.getParameter("EDAD")); int edad= temp.intValue();
// y el formato de update es:
// update tabla set campo1=dato, campo2=dato where clave = 300; // se supone que la clave no se ocupa modificar solo el resto de campos String q = "UPDATE tabla SET " +
"NOMBRE='" + nombre + "', EDAD='" + edad +
try {
// modificando renglon (update) int n=instruccion.executeUpdate(q); //avisando que se hizo la instruccion PrintWriter pagina =response.getWriter(); pagina.println("<HTML>");
pagina.println(n+"YA SE MODIFICO, BACK PARA REGRESAR"); pagina.println("</HTML");
pagina.close(); } //termina try
catch(SQLException e) { System.out.println("error del sql probable mala instruccion sql"); }; destroy();
try {canal.close();} catch(SQLException e) {System.out.println("error el cerrar el canal");}; } ;//fin dopost
public void destroy() {super.destroy();}; }//fin clase prog44
tan tan el curso se acabo y a empezar a construir su proyecto un java servelet que tenga dos tablas basicas y una tabla de relacion 1-kte, suerte.