Sie sind auf Seite 1von 90

Acceso a base de datos con

Java desde aplicaciones web


con la tecnologa JDBC

Samuel Marrero Lorenzo smarlor@iespana.es

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 o
DriverManager que hace de interfaz con el
controlador especfico de la BD.
Aplicacin Java
Driver Manager de JDBC
Controlador
Oracle
SGBD
Oracle BD

Controlador
JDBC-ODBC

Access BD

Controlador
MySQL

BD

SGBD
MySQL

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

Result Set

DriverManager

<<Interface>>
PreparedStatement

DriverPropertyInfo

<<Interface>>
CallableStatement

<<Int erface>>
Res ult SetMet aData

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.

Registrar un controlador (1)




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

Registrar un controlador (2)




Para que la JVM pueda localizar una clase de


driver JDBC de Oracle, por ejemplo,



Situar la ruta a la clase en el CLASSPATH, o


Aadir un JAR externo en el proyecto de Eclipse
donde est nuestra aplicacin


En el men contextual del proyecto Eclipse 


Propiedades  Java Build Path  Add External JARs
En el caso de Oracle aadir el fichero classes12.jar

Ms adelante se explicar cmo configurar esto


para crear una asociacin o pool de conexiones
11

Registrar el controlador (3)




Averiguar el nombre de la clase provista por


el paquete a ser usado.
Localizar la clase en el directorio apropiado
para que pueda ser cargado.
Alternativamente se puede cargar la clase en
el programa usando el comando:



Class.forName(sun.jdbcJdbcOdbcDriver);
DriverManager.registerDriver(new
oracle.jdbc.driver.OracleDriver() ).
12

Cdigo fuente de carga/registro


del controlador de la BD
try
{
//Ejemplo para Oracle
DriverManager.registerDriver(new
oracle.jdbc.driver.Oracledriver());

//Ejemplo para MySQL


Class.forName("com.mysql.jdbc.Driver").newInstance();

}
catch (ClassNotFoundException e)
{
System.out.println("Error en la carga del driver
JDBC");
return;
}

13

Cliente

:
DriverManager

:
Connection

getConnection( )

Conexin a la BD

14
Obtener conexin BD

Abrir una conexin




La clase DriverManager es la responsable de:


 seleccionar el driver
 crear una nueva conexin a la base de datos
Previamente habremos registrado el controlador en el
DriverManager.
Crear una conexin:
 Connection con =
DriverManager.getConnection(url,user,pass)
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.
El DriverManager buscar un driver, entre los registrados, que
pueda usar el protocolo especificado en la url
15

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.
16

Cdigo fuente de conexin


try
{
url de la BD
//Oracle
Connection con=
DriverManager.getConnection("jdbc:oracle:thin:curso_java@10
.1.1.36:1521:DESA",
"","");
//MySQL
Connection con=
DriverManager.getConnection("jdbc:odbc:agenda",
"","");
}
catch (SQLException e)
Usuario, password
{
System.out.println(e);
}

17

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.
18

Cliente

:
DriverManager

:
Connection

: Statement

getConnection( )
createStatement( )

Obtener el objeto
Statement

Crear sentencia de
19
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.
20

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

21

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);
}
22

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.
23

Cliente

:
DriverManager

:
Connection

: Statement

: ResultSet

getConnection( )
createStatement( )

executeQuery( )

Ejecutar la consulta

Ejecutar
consulta

24

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.
25

Cdigo fuente de ejecucin de


una sentencia
try
{
[...]
// Ejecutamos una sentencia SQL
ResultSet rs=
stmt.executeQuery("SELECT id, nombre," +
" , email, telefono" +
" FROM Contactos" +
" WHERE nombre LIKE '%pepe%'");
}
catch (SQLException e)
...
26

Cliente

:
DriverManager

:
Connection

: Statement

: ResultSet

getConnection( )
createStatement( )

executeQuery( )

Posicionar el cursor
en la siguiente fila

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

Recuperar valores
de las columnas.

Repetir mientras
haya filas que
Recuperacin valores
procesar.
resultado

27

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
28
tipos.

Cdigo fuente de recuperacin


de datos
...
while (rs.next())
{
// Se recupera cada columna por separado
String id= rs.getString(id");
String nombre= rs.getDate(nombre");
String email= rs.getInt(email");
String telefono= rs.getDouble(telefono");
// Operacin que realizamos con cada fila
System.out.println(Nombre: " + nombre + ", telefono:
" + telefono);
}

29

Cliente

:
DriverManager

:
Connection

: Statement

: ResultSet

getConnection( )
createStatement( )

executeQuery( )

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

Liberar el objeto
Connection

Liberar el objeto
Statement Librerar
objetos

30

Cdigo fuente de liberacin de


recursos de BD
try
{
[...]
// Liberamos objeto sentencia
stmt.close();
// Liberamos objeto conexin BD
con.close();
}
catch (SQLException e)
...
31

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.

32

Primer ejemplo de manejo de


conexin JDBC





El siguiente cdigo muestra el acceso a una


base de datos y ejecucin de consultas de
seleccin y accin a una base de datos
utilizando un driver JDBC
Cdigo: c:\java\JDBC1\Bd.java
La recuperacin de datos se realiza a la tabla
contactos de la base de datos agenda
conociendo previamente la estructura de la
tabla


Tabla contactos: id, nombre, ciud_id, email,


telefono
33

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.
34

Manejo de las excepciones de


SQL


SQLException
 Es la principal forma que tiene JDBC de informar de errores,
normalmente relacionadas con el acceso y recuperacin de
datos.
 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().
35

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.

36

Extensiones JDBC al paquete


java.lang



Amplan envoltorio Number para permitir albergar grandes nmeros.


Crean clases Exception especializadas.
Number

Exception

BigDecimal

SQLException

SQLWarning

Dat aTruncation
37

Utilizacin de diferentes BD


JDBC permite utilizar distintas bases de datos


sin cambiar el cdigo o haciendo retoques
mnimos (normalmente parmetros de
conexin y, a veces, en las sentencias SQL)
Cambios que implica la utilizacin de una BD
diferente:



controlador,
url de la BD.

Otros posibles cambios.


38

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
39

Controlador Tipo 1


Puente JDBC-ODBC

Servidor

CServ.
B
D
O
o
l
ODBC
o
c
o
t
ro
P
Cliente
JDBCODBC
BD Java
Serv.
Protoc
olo OD
BCODBC

Cliente

BD

BD

Requieren que la mquina en la que corre la


aplicacin tenga instalada la librera de la API
nativa (.dll)
40

Controlador Tipo 2


Controlador utilizando APIs nativas


Servidor
o Serv.
v
BD
i
t
Cliente
a
n
o
l
o
nativo
c
o
t
o
Cliente
APIPr
JDBC
BD Java
nativa

Requieren que la mquina en la que corre la


aplicacin tenga instalada la librera de la API nativa
(.dll)
41

Controlador Tipo 3


Controlador JDBC-NET Java puro

Servidor
Serv. Serv.
BD
Cliente
r
a
d
n

t
es
o
JDBC nativo
l
o
c
o
t
o
r
P
Cliente
JDBC
BD Java
Protoc
Serv. Serv.
BD
olo es
tndar JDBC nativo


Permite que la aplicacin se conecte a varias


bases de datos
42

Controlador Tipo 4


Controlador Java puro y protocolo


nativo

Servidor
Serv.
BD
o
Cliente
v
i
t
na
nativo
o
l
o
c
o
rot
Cliente
P
JDBC
BD Java

En general el tipo ms eficiente es el de


tipo 2
43

Ejecucin de distintas
sentencias SQL


Tipos de sentencias SQL:




Sentencias de definicin de datos (DDL): CREATE


TABLE, CREATE INDEX.
Sentencias de manipulacin de datos (DML):
INSERT, UPDATE, DELETE.
Sentencias de consulta: SELECT.

Cada tipo devuelve resultados distintos y


empleamos distintos mtodos stmt.execute().

44

Sentencias preparadas


Optimiza rendimiento en las sentencias que se


ejecutan repetidamente, por ejemplo la insercin de
varios contactos de clientes en la agenda en un bucle
Caractersticas:





Sentencias en las que no se ponen explcitamente


determinados valores.
Las sentencias escritas en el cdigo por el programador son
ms propensas a errores, stas mejoran ese aspecto ya que
En stas el formateo de los datos lo hace el driver
La base de datos slo tiene que interpretar la sentencia la
primera vez.
Optimizan la ejecucin.
45

Cdigo fuente de sentencias


preparadas
PreparedStatement pstmt= con.prepareStatement(
"INSERT INTO Contactos VALUES (CUJA.nextval,?,?,?)");
// Establece valores para cada uno de los parametros
pstmt.setString(1,Pedro Rodrguez");
// Nombre
pstmt.setString(2,pedro.rodriguez@laspalmasgc.es");//email
pstmt.setString(3,928543424);
// Telefono
int insCount= pstmt.executeUpdate();
// Establece valores para cada uno de los parametros
pstmt.setString(1,Nicols Prez");
// Nombre
pstmt.setString(2,nico@hotmail.com");
// Email
pstmt.setString(3,928246538");
// Telfono
int insCount= pstmt.executeUpdate();

46

Ejemplo de cdigo usando


sentencias preparadas


El siguiente ejemplo es el cdigo fuente


de una clase Java que utiliza JDBC con
sentencias preparadas para acceder a la
tabla contactos de la base de datos
agenda


Cdigo: c:\java\BDCliente.java

47

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.

48

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

49

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().

50

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).

51

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.

52

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().

53

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().
54

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.

55

Metadatos para SQL





Types simplemente contiene constantes con los tipos de datos.


DatabaseMetadata, proporciona informacin sobre la BD.

Object

<<Interface>>
Dat abaseMetaData

Types

56

Informacin sobre el resultado


de una consulta


Muchas veces no conocemos lo que va a


devolver una consulta: SELECT * FROM
Contactos.
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.
57

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");
}
...
58

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");
}
}
...
59

Ejemplo de uso de metadatos







El siguiente cdigo muestra el acceso a una


base de datos y ejecucin de consultas de
seleccin y accin a una base de datos
utilizando un driver JDBC
Cdigo: c:\java\JDBC2\Bd.java
La recuperacin de datos se realiza
cualquiera de las tablas de la base de datos
agenda no conociendo previamente la
estructura de la tabla
60

Manejo de transacciones


Hay veces que no queremos que una sentencia tenga


efecto a menos que otra tambin suceda.
Por ejemplo en una operacin en la que hay que
actualizar campos de varias tablas, en diferentes
acciones SQL, no se querr actualizar una sin
actualizar la otra; de otro modo, los datos seran
inconsistentes.
La forma para asegurarnos que ocurren las dos
acciones o que no ocurre ninguna es utilizar una
transacin. Una transacin es un conjunto de una o
ms sentencias que se ejecutan como una unidad,
por eso o se ejecutan todas o no se ejecuta ninguna.
61

Manejo de transacciones (2)




Cuando se crea una conexin, est en modo autoentrega.


Esto significa que cada sentencia SQL individual es
tratada como una transacin y ser automticamente
entregada justo despus de ser ejecutada.
La forma de permitir que dos o ms sentencia sean
agrupadas en una transacin es desactivar el modo
auto-entrega. Esto se demuestra en el siguiente
cdigo, donde con es una conexin activa.
con.setAutoCommit(false);

62

Manejo de transacciones (3)




Es el tratamiento conjunto de sentencias SQL.


Operaciones bsicas:



COMMIT: realizar la accin


ROLLBACK: volver al paso anterior, revocar la
accin

Mtodos para el tratamiento de


transacciones, sobre el objeto coneccin:


commit(), roollback() y setAutoCommit().

63

Cdigo de ejemplo de manejo


de una transaccin
con.setAutoCommit(false);  Iniciamos la transaccin
PreparedStatement psProd = con.prepareStatement( "UPDATE Productos
SET precio = ? WHERE nombreProducto LIKE ?");
psProd.setInt(1, 500);
psProd.setString(2, Caja 10 cds");
psProd.executeUpdate();  Todavia no se ejecuta
PreparedStatement psInv = con.prepareStatement( "UPDATE Inventario
SET valorTotal = cantidad * ? WHERE Producto LIKE ?");
psInv.setInt(1, 500);
psInv.setString(2, "Caja 10 cds");
psInv.executeUpdate();
con.commit();  Se ejecutan las dos acciones
con.setAutoCommit(true);  Volvemos al modo auto-entrega

64

Acceso a base de datos desde


Servlets y JSP

65

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.
66

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.

67

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, en la tabla
contactos.
Con los datos del formulario construimos una
consulta que realizamos sobre la BD.
Los resultados se los devolvemos al usuario
en otra pgina HTML.
68

Conexin a la base de datos




Respecto al rendimiento, el mayor


cuello de botella se produce al crear 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().
El cdigo de cierre de la conexin se realiza en el mtodo
destroy() del servlet
69

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.

70

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.
71

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.

72

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.

73

Resumen de acceso y manejo de una


conexin a 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.
74

Ejemplo de manejo de
conexin de BD en un servlet


El siguiente ejemplo implementa una


bsqueda de datos en la tabla
contactos de la base de datos agenda
por cualquier criterio.
Cdigo: c:\java\Servlet3.java

75

Ejemplo de pequea
aplicacin web


En el siguiente ejemplo se implementa una pequea aplicacin web


que permite: insertar, mostrar y eliminar registros de la tabla
contactos
Cdigo:


InsertarCliente: servlet que inserta el contacto y enva el resultado de la


accin


EliminarCliente: servlet que elimina el contacto del cliente y enva el


resultado de la accin


c:\java\Servlet4-JDBC-Clientes\Clientes\WEB-INF\src\EliminarCliente.java

VerCliente: servlet que muestra los datos del contacto del cliente


c:\java\Servlet4-JDBC-Clientes\Clientes\WEB-INF\src\InsertarCliente.java

c:\java\Servlet4-JDBC-Clientes\Clientes\WEB-INF\src\VerCliente.java

MostrarClientes: servlet que muestra todos los contactos de clientes de la


tabla contactos


c:\java\Servlet4-JDBC-Clientes\Clientes\WEB-INF\src\MostrarClientes.java

76

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.
77

Asociaciones de conexiones


La creacin y destruccin de conexiones es un proceso costoso,


en consultas pequeas, nos podemos tardar ms en abrir una
conexin, que en ejecutar la propia consulta.
En el caso de los servlets, como hemos visto, la conexin a la
base de datos se mantiene abierta de acuerdo al tiempo y ciclo
de vida del servlet, y esto puede afectar la eficiencia y la
escalabilidad, debido al gran nmero de conexiones abiertas
durante mucho tiempo, muchas de las cuales no se estarn
usando en determinados momentos.
Adems, las variables de instancia Connection y Statement no
son seguras en modo multi-thread, y el servlet debe
implementar el SingleThreadModel, lo cual degrada la eficiencia
y la escalabilidad del servlet.
Para corregir este tipo de problemas, debemos usar lo que se
conoce como asociacin de conexiones o pool de
conexiones(connection pooling).
78

Asociaciones de conexiones
(2)


La asociacin de conexiones es una tcnica que se


utiliza para que una aplicacin pueda reusar las
conexiones que ya han sido establecidas en lugar de
crear nuevas conexiones cada vez.
Esta tcnica est basada en el hecho de que la
mayora de las aplicaciones solo necesita tener
acceso a una conexin JDBC cuando se est
procesando una consulta, lo cual toma slo algunos
milisegundos en completarse.
En las aplicaciones que se conectan continuamente a
una misma base de datos tiene mucho sentido volver
a reciclar las conexiones que ya estn abiertas y que
no se estn utilizando
Mejora la eficiencia
79

Creacin de asociaciones de
conexiones


Para ello usamos una fuente JDBC


representado en la interfaz DataSource
Utilizar la interface DataSource en vez de
DriverManager es mejor por dos razones
importantes, se hace el cdigo ms portable y
ms fcil de mantener.
La informacin relativa a la seguridad,
nombres y contraseas, son almacenados en
ficheros de configuracin y no en el cdigo.
80

Creacin de asociaciones de
conexiones (2)


DataSource es referenciado usando la


interfaz JNDI
JNDI es un servicio de nombres y
directorios
JNDI proporciona una manera uniforme
para que una aplicacin pueda acceder
a servicios remotos sobre una red,
como una base de datos.
81

Pasos para la creacin de


asociaciones de conexiones (3)


Definir una referencia a un recurso dentro de


nuestro archivo descriptor de despliegue de la
aplicacin web (web.xml).
Establecer la relacin entre la referencia al
recurso y una referencia real para el contexto
de nuestra aplicacin.
A continuacin se comentan todos los pasos

82

Definir una referencia a un


recurso: web.xml


web.xml: aadir este fragmento al


final, antes de la etiqueta </webapp>. Esto indica que se va a usar un
recurso referenciado como dsAgenda
<resource-ref>
<res-ref-name> jdbc/dsAgenda </res-ref-name>
<res-type> javax.sql.DataSource </res-type>
<res-auth> Container </res-auth>
</resource-ref>

83

Definicin del recurso en el


servidor de aplicaciones (Tomcat)


server.xml: aadir algo parecido a esto entre las


etiquetas <host> del server.xml
<Context path="/Servlet5-JDBC-CliPool" docBase="/Servlet5JDBC-CliPool/CliPool" debug="0">
<Resource name="jdbc/dsAgenda"
auth="Container"
type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/dsAgenda">

84

Definicin del recurso en el servidor


de aplicaciones (Tomcat) (2)
<! Nmero mximo de conexiones BD en la asociacin. -->
<parameter>
<name>maxActive</name>
<value>100</value>
</parameter>
<! Nmero mximo de conexiones ociosas en la asociacin.
Poner a -1 para ningn lmite. -->
<parameter>
<name>maxIdle</name>
<value>30</value>
</parameter>

85

Definicin del recurso en el servidor


de aplicaciones (Tomcat) (3)
<! Tiempo de espera mximo para que una conexion est disponible. En este caso
10 segundos. Poner a -1 para esperar indefinidamente-->
<parameter>
<name>maxWait</name>
<value>10000</value>
</parameter>
<! Nombres de usuario y password para la conexin a la BD -->
<parameter>
<name>username</name>
<value>curso_java</value>
</parameter>
<parameter>
<name>password</name>
<value>curso_java</value>
</parameter>

86

Definicin del recurso en el servidor


de aplicaciones (Tomcat) (4)
<! Nombre de la clase del driver -->
<parameter>
<name>driverClassName</name>
<!-- <value>com.mysql.jdbc.Driver</value> -- >
<value>oracle.jdbc.driver.OracleDriver</value>
</parameter>

 Para MySQL
 Para Oracle

<! La url para conectar con la BD. El autoReconnect=true asegura que se reconectar
automticamente si la BD cierra la conexion -->
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost:3306/agenda</value>
 Para MySQL
value>jdbc:oracle:thin:@10.1.1.36:1521:DESA</value>
 Para Oracle
</parameter>
</ResourceParams>
</Context>

Si se define este recurso en la etiqueta <DefaultContext> el recurso estar
disponible para todas las aplicaciones que corran en el servidor

87

Crear un pool de conexiones




Copiar el driver JDBC de la base de


datos en el directorio
TOMCAT_HOME\common\lib
Esto hace que el driver est disponible
para Tomcat
Reiniciar Tomcat

88

Acceder a la base de datos a travs


de una asociacin de conexiones


El siguiente cdigo muestra como recuperar el objeto


DataSource asociado con el nombre jdbc/dsAgenda para
entonces establecer una conexin a la base de datos.
Las tres primeras lneas usan el API JNDI para obtener el objeto
DataSource, la ltima lnea usa el API JDBC para establecer la
conexin.
Context init = new InitialContext();
Context context = (Context) init.lookup("java:comp/env");
DataSource ds = (DataSource) context.lookup("jdbc/dsAgenda");
Connection con = ds.getConnection();

El objeto con de conexin es idntico a los anteriores y ya


podemos utilizar la conexin con la BD

89

Ejemplo de uso de una asociacin


de conexiones con servlets


En el siguiente ejemplo se implementa una pequea aplicacin web


que permite: insertar, mostrar y eliminar registros de la tabla
contactos
Cdigo:


FormInsertarCliente: servlet de entrada que enva un formulario al cliente


para insertar un nuevo contacto


InsertarCliente: servlet que inserta el contacto y enva el resultado de la


accin


c:\java\Servlet5-JDBC-CliPool\CliPool\WEB-INF\src\EliminarCliente.java

VerCliente: servlet que muestra los datos del contacto del cliente


c:\java\Servlet5-JDBC-CliPool\CliPool\WEB-INF\src\InsertarCliente.java

EliminarCliente: servlet que elimina el contacto del cliente y enva el


resultado de la accin


c:\java\Servlet5-JDBC-CliPool\CliPool\WEB-INF\src\FormInsertarCliente.java

c:\java\Servlet5-JDBC-CliPool\CliPool\WEB-INF\src\VerCliente.java

MostrarClientes: servlet que muestra todos los contactos de clientes de la


tabla contactos


c:\java\Servlet5-JDBC-CliPool\CliPool\WEB-INF\src\MostrarClientes.java
90