You are on page 1of 79

Acceso a base de datos con Java desde aplicaciones web con la tecnologa JDBC

Bases de Datos en aplicaciones


Aplicacin que procese informacin base de datos. Normalmente se utilizan bases de datos relacionales. SQL: Lenguaje estndar para acceder a una base datos.

Acceder a una base de datos desde una aplicacin


Cmo puede enviar una aplicacin sentencias SQL a una BD. Interfaz procedural para ejecutar sentencias SQL. X/Open CLI (ISO 9075-3 Call level interface). ODBC es variante de Microsoft del X/Open CLI (implementada en lenguaje C). La filosofa de estas APIs es que permitan acceder de la misma forma a distintas BD.
3

JDBC
Es un interfaz orientado a objetos de Java para SQL. Se utiliza para enviar sentencias SQL a un sistema gestor de BD (DBMS). Con JDBC tenemos que continuar escribiendo las sentencias SQL. No aade ni quita potencia al SQL.
4

Arquitectura JDBC
La filosofa de JDBC es proporcionar transparencia al desarrollador frente al gestor de BD. JDBC utiliza un Gestor de Controladores que hace de interfaz con el controlador especfico de la BD. Aplicacin Java Driver Manager de JDBC Controlador Oracle Controlador JDBC-ODBC Controlador DB2

SGBD Oracle BD

Access BD

BD

SGBD DB2

Clases e interfaces JDBC


La especificacin JDBC incluye 8 interfaces y 10 clases, en el paquete estndar java.sql. Podemos dividirlos en los siguientes grupos:
Nucleo de JDBC, interfaces y clases que todos los controladores deben implementar. Extensiones al paquete java.lang, extensiones para SQL. Extensiones al paquete java.util, son extensiones a java.util.Date. Metadatos para SQL, permiten examinar dinmicamente las propiedades de BD y controladores.
6

Ncleo de JDBC
Estos interfaces se utilizarn el 90% de las veces que trabajemos con una BD.

<<Interface>>

<<Interface>>

<<Interface>>

<<Interface>>

Driver

Connection

Statement

ResultSet

DriverManager

<<Interface>> PreparedStatement

<<Interface>> ResultSetMetaData

DriverPropertyInfo

<<Interface>> CallableStatement
7

Invocar una consulta SQL


Vamos a estudiar un escenario en el que realizaremos una consulta sobre una BD con JDBC. Mediante el seguimiento de un diagrama de secuencia veremos las clases en funcionamiento. Cliente, representa a la aplicacin Java donde implementamos la consulta. Un buen ejercicio sera ir escribiendo el programa a la vez que vamos viendo cada una de las fases.
8

Configuracin de la conexin con base de datos


Antes de conectar con la base de datos y trabajar con ella debemos tener en cuenta dos cuestiones:
Registrar un controlador. Convenciones de nombres para la base de datos.

Carga de un controlador (I)


Determinados controladores requerirn la instalacin y configuracin de software especfico en el cliente. Ejemplo: el origen ODBC o la fuente de datos nativa. Otros controladores son simplemente una clase Java y bastar que la mquina virtual de Java las pueda localizar mediante el classpath.
10

Carga de un controlador (y II)


Dos alternativas:
Utilizar una propiedad del sistema (jdbc.drivers). Cargar la clase de forma explcita con la llamada Class.forName().
La propia clase llamar al mtodo registerDriver() de la clase DriverManager, que dejar registrado el controlador para utilizarlo posteriormente. Consultar que los controladores registrados con DriverManager.getDrivers().
11

Cdigo fuente de carga del controlador de la BD


try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); } catch (ClassNotFoundException e) { System.out.println("Error en la carga del driver JDBC"); return; }

12

Cliente

: DriverManager

: Connection

gn( ee) tnn C oo c t i

Conexin a la BD

13

Obtener conexin BD

Abrir una conexin


Previamente habremos registrado el controlador. DriverManager.getConnection(url). El parmetro imprescindible es la url de la base de datos; para especificar la base de datos que queremos utilizar. Tambin se puede especificar el usuario y la clave con los que nos queremos conectar a la base de datos.
14

Nombres para las BD en JDBC


En JDBC las bases de datos se designan mediante una URL. La forma de la url es la siguiente:
jdbc:<subprotocolo>:<dominio>

Subprotocolo: identifica el mecanismo de conexin o el controlador JDBC concreto. Dominio: Depende del subprotocolo, puede ser simplemente un nombre simple para la base de datos o una serie de parmetros que permiten encontrar la BD.
15

Cdigo fuente de conexin


try url de la BD { Connection con= DriverManager.getConnection("jdbc:odbc:Biblio", "",""); "",""); } Usuario, clase de la BD catch (SQLException e) { System.out.println(e); }

16

El objeto Connection
Si no se producen excepciones el mtodo getConnection nos devuelve un objeto que implementa la interfaz Connection. Podemos crear varias conexiones con distintas bases de datos o incluso con la misma. Cada conexin representa una sesin con la BD. El objeto Connection nos permitir acceder a la base de datos para realizar operaciones sobre ella y obtener resultados.
17

Cliente

: DriverManager

: Connection

: Statement

gn( ee) tnn C oo c t i


createStatement( )

Obtener el objeto Statement

18

Crear sentencia de BD

Acceso a los datos


Utilizamos la conexin con la base de datos creada anteriormente para enviar comandos y sentencias SQL. El objeto conexin funciona como un enlace directo con el controlador de la BD. Creamos un objeto de la clase Statement que servir de envoltorio para las sentencias SQL. Cuando pasamos la SQL a la conexin este lo enva al controlador que a su vez lo redirecciona a la BD, que nos devolver los resultados.
19

Objetos involucrados en el acceso a datos (diagrama de colaboracin)


Objeto ResultSet Programa Java Objeto Driver JDBC BD Resultados

Base de datos

Objeto Statement

Objeto Connection

SQL

20

Cdigo fuente de creacin de una sentencia de consulta


try { // Creamos el objeto sentencia Statement stmt= con.createStatement();
[...] } catch (Exception e) { System.out.prinln(e); }
21

Creacin del objeto Statement


La clase Connection tiene varios mtodos que permiten crear un objeto Statement o una de sus variantes. createStatement, para crear sentencias simples. prepareStatement, para sentencias que pueden contener parmetros, optimiza la utilizacin repetida de estas sentencias. prepareCall.
22

Cliente

: DriverManager

: Connection

: Statement

: ResultSet

gn( ee) tnn C oo c t i


createStatement( )

executeQuery( )

Ejecutar la consulta

23

Ejecutar consulta

Ejecucin de la sentencia
executeQuery(), ejecucin de consultas, sentencia SELECT. executeUpdate(), actualizaciones de valores en al base de datos. INSERT, UPDATE, DELETE. Slo devuelve la cuenta de las columnas afectadas. execute(), se usa para ejecutar sentencias que no se conocen a priori o que devuelven resultados no homogneos.
24

Cdigo fuente de ejecucin de una sentencia


try { [...]
// Ejecutamos una sentencia SQL ResultSet rs= stmt.executeQuery("SELECT Titulo, ISBN," + " Fecha_edicion, Paginas, Precio" + " FROM LIBROS" + " WHERE Titulo LIKE '%jdbc%'"); } catch (SQLException e) ...
25

Cliente

: DriverManager

: Connection

: Statement

: ResultSet

gn( ee) tnn C oo c t i


createStatement( )

executeQuery( )

Posicionar el cursor en la siguiente fila

next( ) getInt( ) getString( ) getBigDecimal( )

Repetir mientras haya filas que 26 procesar. Recuperacin valores resultado

Recuperar valores de las columnas.

Recuperacin de datos
Cuando ejecutamos una consulta debemos emplear el mtodo executeQuery(), que devuelve un objeto ResultSet, que nos permitir acceder a los resultados. El ResultSet utiliza el concepto de cursor de base de datos para ir movindose por las filas de datos recuperadas. Las columnas pueden accederse en cualquier orden, utilizando su posicin o su nombre. El objeto ResultSet incluye mtodos getXXX que permiten recuperar valores de distintos tipos. 27

Cdigo fuente de recuperacin de datos


... while (rs.next()) { // Se recupera cada columna por separado String titulo= rs.getString("Titulo"); Date fechaEdicion= rs.getDate("Fecha_edicion"); int pags= rs.getInt("Paginas"); double precio= rs.getDouble("Precio");
// Operacin que realizamos con cada fila System.out.println("Titulo: " + titulo + ", edicin: " + fechaEdicion); }
28

Cliente

: DriverManager

: Connection

: Statement

: ResultSet

gn( ee) tnn C oo c t i


createStatement( )

executeQuery( )

next( ) getInt( ) getString( ) getBigDecimal( ) close( ) close( )

Liberar el objeto Connection

Liberar el objeto Statement 29 Librerar objetos

Cdigo fuente de liberacin de recursos de BD


try { [...]
// Liberamos objeto sentencia stmt.close(); // Liberamos objeto conexin BD con.close();

} catch (SQLException e) ...


30

Resumen proceso consulta simple


Registrar controlador Class.forName. Abrir conexin DriverManager.getConnection. Crea sentencia con.createStatement. Ejecuta la sentencia stmt.executeQuery. Procesar resultados while(rs.next()) ... Cerrar sentencia y conexin close.
Ver Acceso a BD desde servlets
31

Profundizando en la utilizacin de JDBC


Manejo de las excepciones de SQL Utilizacin de diferentes BD. Ejecucin de distintas sentencias SQL. Sentencias preparadas. Conjuntos de resultados.
Desplazamiento y actualizacin por programa. Metadatos.
32

Manejo de las excepciones de SQL


SQLException
Es la principal forma que tiene JDBC de informar de errores. Hereda de la clase Exception de java.lang. Proporciona la siguiente informacin sobre el error:
Una cadena describiendo el error a la que se puede acceder con el mtodo getMessage(). La cadena de error SQLstate de acuerdo con el estndar X/Open a la que se puede acceder con el mtodo getSQLState(). Un cdigo de error entero especfico de la BD que se puede acceder con getErrorCode(). Permite acceder a ms errores con getNextException().

33

Manejo de los avisos de SQL


SQLWarning
Permite informar de errores leves en distintos objetos de la BD: ResultSet, Statement, Connection. Al contrario que SQLException no es obligatorio capturar los SQLWarning. Para obtener un SQLWarning se llama al mtodo getWarning() sobre el objeto. Para obtener SQLWarning adicionales se llama a getNextWarning().

DataTruncation
Informa de avisos de truncado de datos en las lecturas y al escribir datos. 34

Extensiones JDBC al paquete java.lang


Amplan envoltorio Number para permitir albergar grandes nmeros. Crean clases Exception especializadas.
Number Exception

BigDecimal

SQLException

SQLWarning

DataTruncation
35

Utilizacin de diferentes BD
JDBC permite utilizar distintas bases de datos sin cambiar el cdigo o haciendo retoques mnimos. Cambios que implica la utilizacin de una BD diferente:
controlador, url de la BD.

Otros posibles cambios.


36

Tipos de controladores
JDBC es una especificacin que establece dos tipos de interfaces:
Interfaz de aplicacin, que permite acceder a una base de datos independientemente de su fabricante. Interfaz del controlador, al cual se deben adaptar los desarrolladores de controladores.

Actualmente en el mercado existen gran cantidad de controladores que varan en su arquitectura. Sun ha clasificado estos controladores en cuatro tipos.
http://industry.java.sun.com/products/jdbc/drivers
37

Controlador Tipo 1
Puente JDBC-ODBC
Servidor Cliente Cliente JDBC ODBC BD Java Serv. ODBC

BD

Serv. ODBC

BD
38

Controlador Tipo 2
Controlador utilizando APIs nativas
Servidor Cliente Cliente API JDBC BD Java nativa Serv. nativo

BD

39

Controlador Tipo 3
Controlador JDBC-NET Java puro
Servidor Cliente Cliente JDBC BD Java Serv. Serv. JDBC nativo

BD

Serv. Serv. JDBC nativo

BD
40

Controlador Tipo 4
Controlador Java puro y protocolo nativo
Servidor Cliente Cliente JDBC BD Java Serv. nativo

BD

41

Ejecucin de distintas sentencias SQL


Tipos de sentencias SQL:
Sentencias de definicin de datos: CREATE TABLE, CREATE INDEX. Sentencias de manipulacin de datos: INSERT, UPDATE, DELETE. Sentencias de consulta: SELECT.

Cada tipo devuelve resultados distintos y empleamos distintos mtodos stmt.execute().

42

Sentencias preparadas
Optimiza rendimiento en las sentencias que se ejecutan repetidamente. Caractersticas:
Sentencias en las que no se ponen explcitamente determinados valores. La base de datos slo tiene que interpretar la sentencia la primera vez. Optimizan la ejecucin.
43

Cdigo fuente de sentencias preparadas


PreparedStatement pstmt= con.prepareStatement( "INSERT INTO Autores VALUES (?,?,?,?)");
// Establece valores para cada uno de los parametros pstmt.setString(1,"Mario"); // Nombre pstmt.setString(2,"Vargas Llosa"); // Apellidos pstmt.setString(3,"Peru"); // Lugar nacimiento pstmt.setInt(4,1953); // Anio nacimiento int insCount= pstmt.executeUpdate(); // Establece valores para cada uno de los parametros pstmt.setString(1,"Nicholas"); // Nombre pstmt.setString(2,"Negroponte"); // Apellidos pstmt.setString(3,"New York"); // Lugar nacimiento pstmt.setInt(4,1953); // Anio nacimiento int insCount= pstmt.executeUpdate();
44

Conjunto de resultados desplazable


Recorrido bsico del ResultSet: cursor hacia delante, de fila en fila y desde la primera fila next(). Podemos acceder a las filas del ResultSet de ms formas (JDBC 2.0), como un ndice de un array.

45

Creacin de la sentencia para Resultset desplazable


Cambio en la creacin del objeto sentencia:
createStatement(int tipoResultSet, int concurrenciaResultSet) tipoResultSet es el que permite flexibilidad en el desplazamiento. Valores:
TYPE_FORWARD_ONLY, slo hacia delante TYPE_SCROLL_INSENSITIVE, TYPE_SCROLL_SENSITIVE, mtodos de posicionamiento habilitados
46

Mtodos de desplazamiento del cursor


Mtodos
Movimiento hacia atrs: afterLast(), previous(). Posicionamiento absoluto: first(), last(), absolute(numFila). Posicionamiento relativo: relative(num). Recupera fila actual: getRow().

47

Conjunto de resultados actualizable


Para actualizar datos en la BD tenamos que recurrir a sentencias SQL: INSERT, UPDATE, DELETE. Podemos realizar actualizaciones por programa (JDBC 2.0).

48

Creacin de la sentencia para Resultset actualizable


Cambio en la creacin del objeto sentencia:
createStatement(int tipoResultSet, int concurrenciaResultSet) concurrenciaResultSet es el que permite actualizar ResultSet por programa. Valores:
CONCUR_READ_ONLY, no se puede actualizar. CONCUR_UPDATABLE, permite la utilizacin de mtodos para modificar filas.

49

Mtodos para actualizar filas


Posicionarse en la fila para actualizar. Llamar a los mtodos de actualizacin de campos:
updateXXX(<campo>,<valor>)

Para confirmar las actualizaciones sobre la tabla llamamos a: updateRow().

50

Insertando y borrando por programa


Mtodos para insertar filas sin utilizar SQL:
moveToInsertRow(), mueve a fila vaca. updateXXX(<campo>,<valor>) sobre cada campo de la nueva fila. insertRow(), confirma insercin.

Mtodo para borrar filas sin utilizar SQL:


Posicionarnos sobre la fila a borrar. deleteRow().
51

Informacin acerca de la base de datos (Metadatos)


Cuando a priori no tenemos informacin sobre la estructura de la base de datos podemos acceder a ella mediante los metadatos. Esto permite adaptar el acceso que est realizando nuestra aplicacin a una BD concreta en tiempo de ejecucin. Objeto Connection al que aplicamos el mtodo getMetaData(), que devuelve un objeto que implementa la interfaz DatabaseMetaData.
52

Metadatos para SQL


Types simplemente contiene constantes con los tipos de datos. DatabaseMetadata, proporciona informacin sobre la BD.

Object

<<Interface>> DatabaseMetaData

Types

53

Informacin sobre el resultado de una consulta


Muchas veces no conocemos lo que va a devolver una consulta: SELECT * FROM Usuarios. JDBC permite obtener un objeto que implementa ResultSetMetaData al aplicar el mtodo getMetada() a un objeto ResultSet. De esta forma podemos obtener datos como nmero de columnas devueltas y el nombre de una determinada columna. Esto permite la ejecucin y recuperacin de resultados de forma dinmica.
54

Cdigo fuente de recuperacin de metadatos


ResultSet rs = stmt.executeQuery(sqlStr);
ResultSetMetaData rsmd= rs.getMetaData(); int columnCount= rsmd.getColumnCount(); // Vamos imprimiendo los nombres de cada columna for(int x =1;x<=columnCount;x++) { String columnName= rsmd.getColumnName(x); System.out.print(columnName +"\t"); } ...
55

Cdigo fuente de recuperacin de metadatos (cont.)


// Recorremos filas e imprimimos los valores de cada columna while(rs.next()) { for(int x =1;x<=columnCount;x++) { if (rsmd.getColumnTypeName(x).compareTo("CURRENCY") == 0) System.out.print("$"); String resultStr = rs.getString(x); System.out.print(resultStr +"\t"); } } ...
56

Utilizacin de transacciones
Tratamiento conjunto de sentencias SQL. COMMIT y ROLLBACK Mtodos para el tratamiento de transacciones:
commit(), roollback() y setAutoCommit().

57

Ampliaciones al tratamiento bsico de BD


Versiones JDBC
JDBC 1.0 JDBC 2.0
JDBC Optional Package (inicialmente se le llam standard extension API): paquete javax.sql. Es necesario si queremos utilizar objetos DataSource o Rowset. Est incluido en la J2EE. Si tenemos la J2SE podemos bajarlo por separado.

JDBC 3.0: paquetes java.sql y javax.sql est integrado en la plataforma J2SE 1.4.
58

Caractersticas incluye JDBC 2.0 (I)


El recorrido del ResultSet no se limita al avance. Actualizacin de los datos de la base de datos mediante mtodos. Envo de mltiples sentencias SQL de actualizacin a la BD para que las trate como una unidad (Batch updates). Utilizacin de tipos de datos SQL3. Creacin y utilizacin de nuevos tipos SQL definidos por el usuario (UDTs).
59

Caractersticas incluye JDBC 2.0 (y II)


Fuentes de datos como alternativa a getConnection. Creacin de conexiones como pools de conexiones. RowSets.

60

Acceso a base de datos desde Servlets y JSP

Acceso a base de datos desde Servlets


La mayora de las aplicaciones comerciales basadas en servlets utilizan bases de datos. El acceso a base de datos desde un servlet es igual al que se puede realizar desde cualquier aplicacin java. Se utiliza la tecnologa JDBC de Java.

62

JDBC en un Servlet
Para emplear JDBC en un Servlet simplemente hay que incluir los paquetes de java adecuados. Debemos tener en cuenta los distintos tipos de controladores JDBC y cual nos interesa emplear, como en otros entornos. Se utilizan exactamente las mismas interfaces y las mismas clases para conectarnos y extraer informacin de la base de datos que en cualquier otra aplicacin Java.
63

Escenario comn servlets y BD


Vamos a representar un escenario comn en cualquier aplicacin que utiliza servlets y BD. Tenemos un formulario HTML en el que el usuario introduce datos. Con los datos del formulario construimos una consulta que realizamos sobre la BD. Los resultados se los devolvemos al usuario en otra pgina HTML. Ejercicio: ir escribiendo el programa a la vez que vamos viendo cada una de las fases.
64

Conexin a la base de datos


Respecto al rendimiento, el mayor cuello de botella se produce al crea un objeto Connection para conectarnos a la BD. Debemos evitar tener que hacerlo repetidamente. Cdigo de creacin de la conexin con la BD en la inicializacin del servlet que se produce slo una vez mtodo init().
65

Recuperar datos del formulario de consulta


Una vez conectados, el resto del cdigo de acceso a BD estar en los mtodos doGet() o doPost(). Recuperamos los valores de los campos que ha introducido en el formulario que lanza la consulta.

66

Construccin de la consulta
Construiremos la cadena que constituye la sentencia SQL que posteriormente ejecutaremos contra la base de datos. Normalmente habr una parte fija que no vara y unos parmetros que crearemos a partir de la informacin del formulario.

67

Ejecucin de la consulta y devolucin de resultados


Una vez construida la consulta, la enviamos a la BD para su ejecucin. Si existe algn problema debemos devolver un error al usuario. Si la ejecucin fue correcta debemos devolver los resultados de la ejecucin.

68

Cierre de la conexin
Debemos asegurarnos que en el mtodo destroy() del servlet se cierren todas las conexiones. El recolector de basura podr liberar todos los recursos.

69

BD desde un servlet
Conexin con la BD. Recuperar parmetros del formulario de consulta. Construir la sentencia. Ejecucin de la consulta y devolucin de resultados. Cierre de la conexin.
Ver acceso a BD desde JSP
70

Sentencias preparadas en la construccin de sentencias


Principal uso de las sentencias preparadas: mejorar rendimiento. Tambin permiten evitar errores sintcticos en la construccin de la sentencia SQL en el servlet. El usuario podra meter caracteres reservados (ej.: ) en el parmetro. El uso de setString() evita la confusin del analizador de sentencias de la BD.
71

Acceso a base de datos desde JSP


JSP utiliza JDBC para acceder a base de datos. No necesita etiquetas especiales para acceder a base de datos.

72

JSP con el cdigo de acceso a BD incrustado


Uso de scritplets que utilizan JDBC para acceder a la BD. No es necesaria la captura de excepciones JSP hace el trabajo automticamente. Cuando recuperamos resultados de una consulta aparecer cdigo HTML dentro del bucle para ir mostrando cada fila. Realizar ejemplo de acceso a BD con scritplets.
73

Acceso a travs de Beans


Una forma habitual de utilizar BD con JSP es utilizar componentes JavaBean de apoyo. De esta forma mantenemos independiente la presentacin y el acceso a datos, esto es fundamental para facilitar el mantenimiento de la aplicacin.

74

Proceso para recuperar datos a travs de un JavaBean


El Bean se encarga de conectar con la BD y ejecutar la sentencia deseada. El bean proporciona mtodos para posicionarse en cada fila de la consulta. A travs de las propiedades del JavaBean podemos acceder a los valores de cada uno de los campos. Las propiedades de un JavaBean se representan muy fcil en una pgina JSP.
75

Estructura del JavaBean para acceso a BD


Constructor del JavaBean:
conexin con la base de datos. realizacin de la consulta. Guardar resultados en una estructura local al Bean. establecer los valores de las propiedades. cerrar la conexin.

Mtodo para recorrer los resultados.


Recargando las propiedades cada vez que cambie.

Propiedades se corresponden con los campos de la tabla.


76

Ejemplo JavaBean BD
Ejemplo sencillo de un JavaBean que permite recuperar resultados de una BD. Mtodos bsicos:
obtenerFilas(), hace la consulta sobre la BD y guarda resultados en un vector interno. seleccionarFila(int f), se posiciona en el elemento f del vector y carga en cada uno de los atributos los valores de los campos.
77

JSP muestra resultados (I)


Realizamos una pgina JSP que utilizando el Bean anterior muestre todas las filas de la consulta en una tabla. Pide al JavaBean que realice la consulta.
<% BeanBd.obtenerFilas(); %>

78

JSP muestra resultados (y II)


Recupera cada una de las filas.
<% for (int i= 0; i<BeanBd.numEle(); i++)
{ BeanBd.seleccionarFila(i); %>

<tr> <td><jsp:getProperty name=BeanBd property=campo1/></td> <td><jsp:getProperty name=BeanBd property=campo2/></td> <td><jsp:getProperty name=BeanBd property=campo3/></td> </tr> <% } %>
79

You might also like