1. Objetivos:
Este laboratorio es una continuación del anterior y consiste en crear una nueva clase que implemente el nivel de lógica del negocio y que acceda a una BD que contenga los nombres de usuarios y passwords con permiso de acceso al sistema, para ello llevaremos a cabo los siguentes pasos:
2.1. Definir una fuente de datos ODBC llamada BDPasswLabLog3N y asociadla a la BD anterior. Para ello:
a) En Windows 2000: hay que acceder al Panel de control => Herramientas administrativas => Orígenes de datos ODBC
b) En Windows XP: hay que acceder al Panel de control => Rendimiento y Mantenimiento => Herramientas administrativas => Orígenes de datos ODBC
2.2. Dentro del Administrador de ODBC hay que definir el nombre de la fuente de datos BDPasswLabLog3N y seleccionar la BD cuentas.mdb.
Dentro de la pestaña DNS del usuario (User DNS) pinchar en Agregar (Add) y seleccionar "Microsoft Access Driver". Esto hará que surja un ventana en la cual pondremos como nombre del origen de datos BDPasswLabLog3N y mediante el botón Seleccionar buscaremos la BD cuentas.
3.- Añadir una nueva lógica de negocio llamada EntradaSistemaDB que implemente la interface InterfaceLogicaNegocio,la cual se encargara de gestionar la BD. Compilad la nueva clase y llevad a cabo los siguientes pasos compilando en cada paso:
Nota: Si en el paso anterior tenéis problema de compilación recordad implementar el método hacerLogin.
3.1. Inicilizar los driver. La clase que se encarga de inicializar o cargar los drivers es DriverManager perteneciente al paquete Java.sql.*. La carga (Class.forName) dependera del controlador.
Puente JDBC/ODBC --> Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);
JDBC de MySQL --> Class.forName(“com.mysql.jdbc.Driver”);
JDBC de ORACLE --> Class.forName(“oracle.jdbc.driver.OracleDriver");
Nota: Al compilar vereis que es necesario atrapara una excepción. Si no lo podeis solucionar presetad atención a la primera línea de la excepción.
3.2. Crear una conexión. Luego de inicializar
los drivers, es necesario crear una conexion para ello se utiliza el
DriverManager para obtener un objeto del tipo conexión,
Connection.
Puente JDBC/ODBC --> Connection c = DriverManager.getConnection("jdbc:odbc:NombreBD");
JDBC
--> Connection c = DriverManager.getConnection(String d,
String u, String c);
// d = identifica la BD, jdbc:subprotocolo//servidor:puerto/BDs
// u = identifica el usuario
// c = identifica la clave
// "jdbc:oracle:thin:@g010128.si.ehu.es:1521:ISO", "ISO", "ISO"
// "jdbc:mysql://jipla0.gi.ehu.es/ISO","ISO","ISO"
3.3. Crear una sentencia. Una vez que se tiene un objeto del tipo Connection, se pueden crear sentencias (statements).
// c es un objeto Connection
Statement s = c.createStatement();// Ejecuta una sentencia SQL INSERT, UPDATE o DELETE
int i = s.executeUpdate(String sql);// Ejecuta una sentencia SQL SELECT y devuelve el resultado en un objeto ResultSet
ResultSet r = s.executeQuery(String sql);
Cread una sentencia que recupere la primera tupla de la tabla y compilad.
Nota: Recordad que los String se concatenan con el signo +, es decir, "usuario=" + "invitado"
Moverse por el ResultSet. Cada una de estas sentencias puede
devolver cero o más resultados, los mismos son devueltos como objetos del tipo ResultSet. Mediante
ResultSet.next() nos podemos mover al «siguiente» elemento del resultado, o bien
sobre el primero si todavía no se ha utilizado. La función next() devuelve true
o false si el elemento existe, de forma que se puede iterar mediante la
sentencia while (
resultado.next()) de este modo se puede tener acceso a todos los elementos.
Para tener acceso a la diferentes columnas se utilizan los métodos getXXX(). El
acceso se puede hacer por el nombre de la columna o bien mediante su ubicación relativa. Además
de getString() están disponibles getBoolean(), getByte(), getDouble(), getFloat(),
getInt(), getLong(), getNumeric(), getObject(), getShort(), getDate(), getTime()
y getUnicodeStream(), cada uno de los cuales devuelve la columna en el formato
correspondiente, si es posible.
3.5. Probar a recuperar la primera tupa y luego la segunda. ¿Que sucede?. Hay que reescribir el código, es posible parametrizar las sentencias SQL. Un ejemplo de ello se observa a continuación.
PreparedStatement s = c.prepareStatement(“Select nombre From Persona
Where ciudad =? and edad=?”);
s.setString(1, ”San Luis”); // pone
San Luis en
el primer parámetro
s.setInt(2, 25); // pone 25 en el
segundo parámetro
ResultSet r = s.executeQuery();
Implemetad el método hacerLogin para que consulte en la base de datos si existe o no el usuario y password pasado por referencia. Compilad y atrapad las excepciones.
3.6. Cerrar la conexión. Después de haber trabajado con una sentencia o una conexión es recomendable cerrarla mediante sentencia.close() o conexión.close().
Cread un método que cierre la conexión, compilad y atrapad las excepciones.
4. Ejecutar la lógica del negocio creada
4.1. Comprobar que dentro de vuestro código se utiliza una fuente de datos ODBC llamada BDPasswLabLog3N.
4.2 Ejecutar la aplicación asignando la nueva lógica del negocio. Intentadlo pero si teneis algun problema, aqui teneis la Solución del laboratorio hasta este paso.
5.- Manejo de ODBC Remoto. En esta sección dividiremos nuestra aplicación en dos niveles: 1) colocando en un ordenador remoto la base de datos (Servidor Flaco) y 2) colocando nuestra aplicación en un ordenador local (Cliente Gordo). Por lo tanto, el cliente tendrá el nivel de presentación (la clase Presentacion) y la lógica del negocio (la clase EntradaSistemaBD) y el servidor tendrá la tabla CUENTA (usuario, password, numIntentosFallidos).
El manejo ODBC Remoto es totalmente
trasparente al usuario y de hecho no hace falta CAMBIAR NI RECOMPILAR EL CÓDIGO DE LA PRESENTACIÓN, NI EL
DE LA LÓGICA DEL NEGOCIO.
- el mismo contiene un recurso compartido llamado DOCENCIA (Este es el recurso compartido que hay que “Conectar a unidad de red”)
- y dentro del directorio ISO se encuentra la base de datos
a) Hay que buscar el ordenador JIPL00 en la red (Menú Inicio S.O. => Buscar => Archivos o Carpetas … => Buscar Equipo => Nombre equipo: JIPL00
Nota: si no lo encuentra o hay problemas para entrar, intentad buscarlo añadiendo el dominio: jipl00.gi.ehu.es
Probad la aplicación distibuida.
6.- Hasta el momento no hemos hecho uso del atributo “numIntentosFallidos” de la tabla “cuenta”. Modificar la clase del negocio para incrementar en uno el número de intentos fallidos al introducir incorrectamente el password de un usuario e inicializa a cero el mismo cuando se entra correctamente en el sistema. Si teneis algún problemar recurir al punto 3.3 de este laboratorio.
7. Manejo de JDBC Remoto y librerías disponibles. Hasta el momento hemos trabajado con ODBC ahora lo haremos con JDBC, para ello probaremos conectarnos a otro sistema de gestión de BD como es ORACLE, para ello debemos cargar el controlador adecuado recuerda el punto 3.1 y 3.2 de este laboratorio. La maquina a la cual nos conectaremos sera:
- Máquina: g010128.si.ehu.es
- Puerto: 1521
- BD: ISO
- Usuario/Password: ISO
Probad a ejecutar la aplicación que sucede? Nos da una excepción porque no es posible cargar o encontrar la clase JDBC. Este error no nos aparecia en el caso de ODBC porque sun proporciona las clases necesarias para realizar el puente. Pero para el caso de JDBC es necesario cargarlo uno mismo. Para ello hay que realizar los siguientes pasos:
1. Debemo pinchar con el botón derecho sobre el proyecto, esto hara que aparezca una lista desplegable.
2. Seleccionar la última opción de la lista "Project Setting"
3. Bucar "Oracle JDCB" dentro de Configurations --> Development --> Libraries
4. Seleccionarla y pinchar en la flecha de la derecha de forma tal que aparezca en el cuadro adyacente.
5. Ejecutad la aplicación y comprobad su funcionamiento.
6. Si teneis algun problema con el nombre de la tabla anteponed al nombre de la tabla "jimena." es decir "jimena.cuenta"
9. Manejo de JDBC Remoto y librerías no disponibles. Para conectarnos al servidor Oracle fue necesario agregar la libreria "ORACLE JDBC" disponible en JDeveloper ya que ambas herramientas (BD Oracle y JDeveloper) pertenecen a la misma compañia, pero que sucede si deseamos usar librerias externas como puede ser una BD de libre distribución del tipo Mysql, será necesario bajarnos los driver o librería necesarias para gestionar las mismas desde Java.
Probaremos concectarnos al servidor Mysql que se encuentra en:
- Máquina: jipla.si.ehu.es
- BD: ISO
- Usuario/Password: ISO
Probad a ejecutar la aplicación que sucede? Nos da una excepción porque no es posible cargar o encontrar la clase JDBC. Para ello repetiremos los pasos 1, 2 y 3 del punto anterior
1. Debemo pinchar con el botón derecho sobre el proyecto, esto hara que aparezca una lista desplegable.
2. Seleccionar la última opción de la lista "Project Setting"
3. Bucar "Oracle JDCB" dentro de Configurations --> Development --> Libraries
4. Pinchar en new y colocar como nombre de la libreria: Mysql y buscar las librerias en JIPL00/Docencia/ISO/mysql-connector-java-3.0.17-ga-bin.jar
Nota: Si teneis el siguiente problema (table or view that not exist) al ejecutar la aplicación anteponed al nombre de la tabla (cuenta) lo siguiente: "jimena." de forma tal que la tabla se llame "jimena.cuenta"
8. Parametrizacion del manejo de conexiones. Utilizar un archivo de configuración para no tener que recompilar la aplicación cada vez que cambiamos de BD. Para ello crea una clase llamada PropiedadesDelSistema.
8.1. Leer los atributos del sistema.
Por lo general, un programa contiene un conjunto
de atributos del sistema como es la dirección del
servidor, el puerto de conexión, el sistema operativo. A veces, también
tiene sus propios atributos configurables llamados atributos del programa
que permiten al usuario configurar aspectos de una aplicación. Estos valores se
suelen llamar preferencias de usuario.
import java.util.Properties;
Properties props = System.getProperties();
System.out.println(props);
8.2. Crea una función principal y ejecuta el programa. Como resultado veremos una lista de todas las claves/valores (key/values). La clave es la “palabra” y el valor es la “definición” de dicha palabra. Cada Property key es un atributo de configuración del programa, y su correspondiente Property value es el valor de dicha propiedad.
java.runtime.name=Java(TM) 2 Runtime Environment Standard Edition,
sun.boot.library.path=D:\JDeveloper903i\jdk\jre\bin,
java.vm.version=9.0.3.738 cdov, ....
8.3. Cargar atributos del programa. Los atributos del programa se gestionan con la clase java.util.Properties. La cual nos permite: 1) Cargar pares key/values desde un fichero; 2) Obtener un valor a partir de una clave; 3) Listar todas las claves y sus valores; 4) Hacer un recorrido por las claves; 5) Salvar las claves a un fichero.
Lo primero que debemos hacer para cargar los atributos del programa es hacer un archivo de configuración, llamad al archivo "ArchivoDeConfiguracion.txt", el cual tendra el siguiente aspecto
# esto es un comentario y no sera leido
sistema_operativo = Windows
bd_utilizada = Oracle
Las claves están separadas de sus valores por el símbolo “=”. A la hora de ser cargado por el sistema no se tienen en cuenta ni los espacios ni líneas en blanco. Las líneas que empiezan por “#” se utilizan para hacer comentarios.
8.4. Cambiad la clase EntradaSistemaDB para que tome en consideración el archivos de configuración. Implementad el método getSO y getDB para obtener los datos cargados en tiempo de ejecucion.
FileInputStream f = new FileInputStream("c:\\lab2\\ArchivoDeConfiguracion.txt");
props.load(f);
System.setProperties(props);
s_sist_op =
props.getProperty("sistema_operativo");
s_db =
props.getProperty("bd_utilizada");
Nota: Al compilar nos encontraremso con que JDevoloper no encuentra la clase FileInputStream. Navega en la siguiente pagina (http://java.sun.com/j2se/1.3/docs/api/) y busca el paquete a incorporar y atrapa las excepciones.
8.4. Ejecutar la aplicación cambiando en el archivo de configuración la BD utilizada como se observa no es necesario recompilar la aplicacion, ni realizar cambios, solo basta con parametrizar el sistema.
En este
enlace se encuentra la solución del laboratorio: SOLUCION LABORATORIO
En este enlace se allá una descripcion más detallada de cada uno de los pasos llevados a cabo en este laboratorio: Laboratorio_Detallado