Diseño y Modelado de bases de datos Practica 11: Conexión de Java con Bases de datos Access En esta práctica vamos a crear una base de datos Microsoft Access y luego vamos a conectarnos desde una aplicación java haciendo uso del puente JDBC-ODBC que se establece con las fuentes de datos y los drivers que ya vienen el el JDK de Windows y de Java respectivamente. Creación de la base de datos en Access 1. 2. 3. 4. Abra Microsoft Access De clic sobre Archivo nuevo y seleccione Base de datos en blanco En la ventana que aparece seleccione crear una tabla en la vista de diseño En la ventana emergente ingrese los nombres de los cambos id_ciudad, nom_ciudad y poblacion como lo muestra la figura 1 Figura 1. Gabriel Vásquez – Departamento de Electrónica, Instrumentación y Control Diseño y Modelado de bases de datos 5. Cierre la ventana y escoja guardar los cambios, en el nombre de la tabla digite Ciudad. 6. Seleccione la opción Tablas y luego seleccione la tabla ciudad dando doble clic. 7. Ingrese los datos que muestra la figura 2. Hasta aquí ya se ha creado la base de datos y se han ingresado los datos en la tabla ciudad, ahora vamos a crear una aplicación en java que se conecte y nos permita recuperar algunos datos. JDBC y ODBC La capacidad para acceder a bases de datos desde Java la ofrece la API JDBC (Java DataBase Conectivity). JDBC es un estándar para manejar bases de datos en Java. ODBC es un estándar de Windows para manejar bases de datos, de forma que cualquier programa en Windows que desee acceder a bases de datos genéricas debe usar este estándar. La necesidad de crear un estándar propio para acceder a bases de datos desde Java se explica porque el estándar ODBC está programado en C y un programa que use este estándar, por lo tanto, depende de la plataforma. Controladores JDBC-ODBC Necesitamos acceder a un origren de datos ODBC pero contamos con una API que usa el estándar JDBC. Para solventar este problema las empresas realizan drivers que traducen el ODBC a JDBC. Hay varios tipos de Driver, pero para nuestro ejemplo usaremos los llamados puentes JDBC-ODBC. El JDK de Windows incorpora el driver necesario para conectar bases de datos Access. Crear un nuevo DSN (Data Source Name) Para realizar la conexión a una base de datos ODBC necesitaremos crear un perfil DSN desde el panel de control y posteriormente accederemos a la base de datos a partir del nombre del perfil. En el perfil DSN lo que se hace es indicar el driver a utilizar, así como el archivo o archivos del origen de datos. Estos son los pasos a llevar a cabo para configurar un perfil DSN. 1. Vaya al Panel de Control. 2. De doble clic en el icono de Herramientas Administrativas Gabriel Vásquez – Departamento de Electrónica, Instrumentación y Control Diseño y Modelado de bases de datos 3. De doble clic sobre el icono Origenes de Datos (ODBC) 4. En nuestra pantalla aparecerá ahora la pestaña DSN usuario seleccionada. Para crear un nuevo perfil de clic en Agregar... 5. A continuación se nos pide que ingresemos el controlador que vamos a usar en el nuevo perfil. En nuestro caso será Microsoft Access Driver (*.mdb). 6. Una vez aquí sólo nos queda dar un nombre al origen de datos y especificar el archivo .mdb de origen. Tras aceptar la ventana ya tenemos creado un perfil con lo que ya podemos comenzar a crear la aplicación en Java. Clases, objetos y métodos básicos Lo que necesitamos para hacer nuestro programa es la API JDBC incluida en el JDK. El paquete a utilizar y el cual debemos importar es el paquete java.sql. 1. Cree un nuevo proyecto en Eclipse y cree una clase llamada ControlBD dentro de un paquete llamado control. 2. Importe el paquete java.sql con la línea de código import java.sql.*; Las primeras líneas de código suelen ser rutinarias ya que siempre serán muy similares. Cargar el Driver Lo primero es hacer una llamada al Driver JDBC-ODBC para cargarlo. 1. Cree un método llamado conectar (public void conectar(){ })y en el cuerpo del método digite el siguiente código Srtring url= "jdbc:ODBC:nombre_perfil_DSN"; String login= ""; String password= ""; try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); }catch(ClassNotFoundException e){ System.out.println("No se encontro la clase del Driver"); } Con esto ya tenemos cargado el Driver. Ahora básicamente trabajaremos con tres objetos. Estos objetos son: Connection, Statement y ResultSet. El objeto Connection se obtiene al realizar la conexión a la base de datos. El objeto Statement se crea a partir del anterior y nos permite ejecutar SQL para hacer consultas o modificaciones en la base de datos. En caso de hacer una consulta (SELECT ... FROM ...) se nos devolverá un objeto que representa los datos que deseamos consultar; este objeto es un objeto ResultSet (Hoja de resultados). Gabriel Vásquez – Departamento de Electrónica, Instrumentación y Control Diseño y Modelado de bases de datos 2. Adicione los siguientes atributos a la Clase ControlBD; Connection conn; Statement stat; ResultSet rst; El objeto Connection Debemos realizar la conexión a nuestro origen de datos. 3. Digite las siguiente línea debajo de la línea donde se carga el Driver. conn=DriverManager.getConnection(url,login,password); Los dos últimos parámetros pueden ser cadenas vacías a no ser que la base de datos requiera otros valores. Con esto ya hemos realizado una conexión a nuestra base de datos. Pero esto todavía no es suficiente. Ahora vamos a crear un objeto Statement con el que podremos ejecutar y hacer consultas SQL. Si hasta ahora todo ha sido rutinario a partir de ahora vamos a poder crear código más adaptado a las necesidades de nuestra aplicación. 4. Adicione un catch para capturar la excepción SQLException El objeto Statement Como se ha dicho, un objeto Statement se crea a partir del objeto Connection antes obtenido. También como se ha dicho un objeto Statement nos permite hacer consultas SQL que nos devuelven una hoja de resultados. Pues bien, según como deseamos que sea esa hoja de resultados (modificable, o no, sensible a las modificaciones o no,...) deberemos crear de una forma u otra el objeto Statement 5. Debajo de la línea donde se crea el objeto conn adicione la siguientes líneas de código stat = conn.createStatement(); System.out.println("Conexion establecida"); De esta forma muy simple hemos creado un objeto Statement. Ahora podemos usar este objeto Statement para hacer modificaciones en la base de datos a través del lenguaje SQL. Para realizar modificaciones, es decir, instrucciones INSERT, UPDATE o DELETE, se usa el método executeUpdate pasando como parámetro una cadena de texto String que contenga la instrucción SQL. Gabriel Vásquez – Departamento de Electrónica, Instrumentación y Control Diseño y Modelado de bases de datos Para hacer una consulta, es decir, una instrucción SELECT debemos usar otro método: el método executeQuery que como el anterior se le ha de pasar un String que contenga la instrucción. Este método nos devuelve un objeto ResultSet que contiene los datos obtenidos. El objeto ResultSet: Hoja de resultados Moverse por la hoja de resultados Al hablar de posición del cursor nos referimos a la posición dentro de los datos del objeto ResultSet. Lo primero que hay que saber es que el cursor tiene tantas posiciones como filas tenga la consulta y dos más que se sitúan antes de la primera fila y después de la última. Cuando se crea un objeto Resultset, la posición del cursor es la anterior a la primera fila. Para mover el cursor a la posición siguiente usaremos el método next() que nos devuelve una variable booleana: true, si se ha podido mover; false, si no ha sido posible el desplazamiento. Nos devolverá false si estamos en el útimo registro (el posterior al último). Para movernos hacia atrás tenemos un método muy similar: el método previous() que al igual que el anterior nos devuelve un valor booleano que será false si estamos en el registro anterior al primero. Estos métodos nos permiten movernos de forma relativa por la hoja de resultados Obtener datos de la hoja de resultados Para acceder a los datos de la hoja de resultados usamos los métodos get...(int numeroColumna) o get...(String nombreColumna). Estos métodos nos devuelven el valor que indica el nombre del método (por ejemplo tenemos: getString, getInt, getDate, ...) indicando el número o el nombre de la columna. Hay que tener en cuenta que el número de columna es el número de columna en la hoja de resultados y por tanto se establece con el orden en el que se han incluido las columnas en la instrucción SELECT. Por ejemplo si hemos hecho la consulta de la siguiente forma: SELECT Nombre, Apellidos ... la columna Nombre será la primera y la columna Apellidos será la segunda independientemente de cómo estén situadas en la base de datos. Si hacemos un SELECT * FROM ..., en ese caso las columnas estarán en el orden en el que están en la base de datos. 6. Cree un método llamado getCiudades de la siguiente forma: public String[][] getCiudades(){ int numFilas; String[][] datos; String sql="select count(*) as numFilas from ciudad"; try { rst=stat.executeQuery(sql); rst.next(); numFilas=rst.getInt("numFilas"); datos=new String[numFilas][3]; String sql2="Select * from ciudad"; Gabriel Vásquez – Departamento de Electrónica, Instrumentación y Control Diseño y Modelado de bases de datos rst=stat.executeQuery(sql2); int i=0; while(rst.next()){ datos[i][0]=Integer.toString(rst.getInt(1)); datos[i][1]=rst.getString("nom_ciudad"); datos[i][2]=Integer.toString(rst.getInt(3)); i++; } return datos; } catch (SQLException e) { e.printStackTrace(); return null; } } Creación de la interfaz de usuario 1. 2. Cree una nueva clase visual de tipo JFrame dentro de un paquete llamado vista Agregue un botón en la parte inferior del Frame como lo muestra la figura 3. 3. En el centro del panel Adicione una JTable on ScrollPane, la GUI debe ir quedando como lo muestra la figura 4. 4. Adicione el evento actionPerformed al botón. Gabriel Vásquez – Departamento de Electrónica, Instrumentación y Control Diseño y Modelado de bases de datos 5. Vaya al código de la clase y cambie la línea System.out.println("actionPerformed()"); por la línea getCiudades(); los errores que se generan es porque no se ha implementado este método. 6. Antes de implementar el método importemos la clase Control.ControlBD mediante la linea de código: import control.ControlBD; antes de la declaración de la clase GUI_Ciudad 7. Ahora adicione el atributo de clase de tipo ControlBD con la siguiente línea en la sección de atributos: ControlBD cBD=new ControlBD(); 8. Implemente el método getCiudades de la siguiente forma: private void getCiudades() { cBD.conectar(); String[][] ciudades=cBD.getCiudades(); String[] columns=new String[]{"ID","NOMBRE","POLACION"}; jTable=null; jTable= new JTable(ciudades, columns); jScrollPane.getViewport().add(jTable); cBD.desconectar(); } El error que se genera es porque falta implementar el método desconetar en la clase ControlBD. 9. Impelerte el método desconectar en la clase ControlBD de la siguiente forma: public void desconectar(){ try { conn.close(); System.out.println("Conexion cerrada"); }catch (SQLException e) { e.printStackTrace(); } } 10. En la clase GUI_Ciudad busque el método initialize y adicione la línea de código this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 11. Cree el método main en la clase GUI_Ciudad (si no está creado) y digite las siguientes lineas de código, de modo que quede de la siguiente forma: public static void main(String[] args) { GUI_Ciudad gCiudad=new GUI_Ciudad(); gCiudad.setVisible(true); } Gabriel Vásquez – Departamento de Electrónica, Instrumentación y Control Diseño y Modelado de bases de datos 12. Ejecute la clase GUI_Ciudad y de clic sobre el botón Consultar, si las cosas salieron bien, la interfaz debería verse como la figura. Fin de la Práctica Gabriel Vásquez – Departamento de Electrónica, Instrumentación y Control