You are on page 1of 15

26/04/2007

Bases de Datos en Java:


JDBC y Patrn DAO

26/04/2007

DAI

Contenido
z
z
z
z
z
z
z
z

Definicin.
Arquitectura.
Driver.
Conexin.
Consultas.
Transacciones
Transacciones.
Pool de conexiones.
Patrn DAO.

Curso 2006/2007

26/04/2007

JDBC
z
z
z
z

Java DataBase Connectivity


API Java para ejecutar consultas SQL en Bases de
Datos Relacionales.
Independiente del Sistema Gestor Relacional.
Similar en concepto a ODBC de Windows.
Distribuida en dos paquetes:
java.sql, dentro de J2SE
javax.sql extensin dentro de J2EE
Para acceder a una base de datos es necesario un
driver.
Implementacin de todas las interfaces del API.

Curso 2006/2007

JDBC
z

El API ofrece las clases e interfaces para:


Establecer una conexin a una base de datos.
Ejecutar una consulta.
Procesar los resultados.
// Establece la conexin
Connection con = DriverManager.getConnection (
"jdbc:odbc:miBD", miLogin", miPassword");
// Ejecuta la consulta
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT nombre, edad FROM Empleados");
// Procesa los resultados
while (rs.next()) {
String nombre = rs.getString(nombre");
int edad = rs.getInt(edad");

Curso 2006/2007

26/04/2007

Arquitectura
ResultSet

Statement Statement

Statement

Connection

Connection

Aplicacin

DriverManager
Driver

Driver

JVM

Access

Curso 2006/2007

Oracle

Driver
z
z

Conjunto de clases encargadas de implementar las interfaces del API y


acceder a la base de datos.
Tipos:
Driver Tipo 1:
z Utilizan un API nativa estndar
z Ejemplo: puente JDBC:ODBC
Driver Tipo 2:
z Utilizan un API nativa de la base de datos
z Ejemplo: Oracle OCI
Driver
Di
Ti
Tipo 3:
3
z Servidor remoto con un API genrica.
z til para aplicaciones en internet.
Driver Tipo 4:
z Totalmente desarrollado en Java
z Ejemplo: Oracle Thin.

Curso 2006/2007

26/04/2007

Driver
z
z

Los drivers Tipo 1 y 2 utilizan cdigo nativo va JNI.


Son ms eficientes.
Diseo Driver Tipo 3:

En aplicaciones enterprise favorecen la gestin de las bases de datos,


que se realiza en el servidor.
Carga de un driver: Class.forName(acme.db.Driver);
Repositorio de drivers:
http://industry.java.sun.com/products/jdbc/drivers

z
z

Curso 2006/2007

Conexin
z
z

Representa una conexin con una base de datos.


Se obtienen a partir de la clase DriverManager:
DriverManager.getConnection(URL, login, password)
Mantiene un registro de todos los drivers cargados en la
JVM.
URL identifica el driver y su tipo, la localizacin de la base de
d t y su nombre:
datos
b
jdbc:oracle:oci:dis.um.es/MiBD
Alternativa a DriverManager: DataSource

Curso 2006/2007

26/04/2007

DataSource
z

z
z

Acta como factora de conexiones.


Mtodo getConnection()
Abstrae los detalles de acceso:
Cargar los drivers, URL, login, etc.
Aplicaciones ms portables.
Suelen mantener un pool de conexiones.
Proporcionado por el contenedor utilizando el API JNDI (Java
Naming and Directory Interface).
Los detalles de acceso se indican en ficheros de configuracin.
Acceso a los servicios de nombres y directorios.
Ejemplo: acceso a recursos, LDAP.

Curso 2006/2007

Consultas SQL
z
z
z

10

El API JDBC no restringe las sentencias que se envan a la BD.


En principio, todos los drivers deben ser compatibles con ANSI SQL-2
Entry Level.
Tipos de sentencias:
Statement: para sentencias sencillas en SQL.
PreparedStatement: para consultas preparadas,
z Ejemplo: las que tienen parmetros.
CallableStatement: para ejecutar procedimientos almacenados en
la BD.
El API distingue dos tipos de consultas:
Consultas: SELECT
Actualizaciones: INSERT, UPDATE, DELETE, sentencias DDL.

Curso 2006/2007

26/04/2007

Statement
z

Son creadas a partir de la conexin:


Statement stmt = conexion.createStatement();
Ejecucin de una consulta:
stmt.executeQuery(SELECT * FROM Pedidos);
Devuelve un objeto ResultSet.
Ejecucin de una actualizacin:
stmt.executeUpdate(DELETE FROM Pedidos WHERE
codigo = 15)
Devuelven un entero indicando los registros actualizados
0 si es una consulta DDL.

11

Curso 2006/2007

ResultSet
z

12

Es un proxy sobre los registros del resultado de la bsqueda.


Controla la recuperacin de los registros.
Representa un cursor (iterador) sobre los resultados.
Movimiento: mtodos next() y previous()
Inicialmente el cursor est posicionado antes del primer
registro.
Depende del objeto consulta:
Cada vez que se realice una consulta se pierden los
resultados.

Curso 2006/2007

26/04/2007

ResultSet
z

13

Tenemos dos alternativas para acceder a las columnas del


resultado:
rs.getString(nombre); Nombre de la columna
rs.getString(1); Posicin en la consulta
El acceso por posicin es til cuando:
Acceso a una columna derivada, ej. calcular la media
Cuando hay columnas con los mismos nombres (join)
Recuperacin de los valores de las columnas:
Mtodos de acceso (getXXX).
Es conveniente leer los datos de izquierda a derecha.
Para averiguar si se ha ledo un nulo: wasNull()
Curso 2006/2007

ResultSet Mtodos de Acceso


Tipo de dato SQL
CHAR
VARCHAR
LONGVARCHAR

NUMERIC
DECIMAL
BIT
TINYINT
SMALLINT
INTEGER
BIGINT
REAL
FLOAT
DOUBLE
BINARY
VARBINARY
DATE
TIME
TIMESTAMP

14

Mtodo de Acceso
String getString()
String getString()
InputStream
getAsciiStream()
getUnicodeString()
java.math.BigDecimal
getBigDecimal()
java.math.BigDecimal
getBigDecimal()
boolean getBoolean()
byte getByte()
short getShort()
int getInt()
l
long
getLong()
tL
()
float getFloat()
double getDouble()
double getDouble()
byte[] getBytes()
InputStream
getBinayStream()
java.sql.Date getDate()
java.sql.Time getTime()
java.sql.TimeStamp
getTimeStamp()

Curso 2006/2007

26/04/2007

PreparedStatement
z

15

Problema con Statement:


Cuando la consulta se realiza dentro de un bucle y vara
slo en unos valores:
z stmt.executeQuery(SELECT * FROM Cliente WHERE
codigo = + i);
z La base de datos planifica cada consulta.
Conviene disponer de una consulta con parmetros.
PreparedStatement:
Especializacin de Statement que permite definir consultas
parametrizadas.
La BD slo planifica la consulta cuando se crea.
Evitan tener que formatear los datos al construir la cadena
de consulta: para cadenas, fechas y horas.
Curso 2006/2007

PreparedStatement
z

16

Tambin se crean a partir de la conexin:


PreparedStatement pstmt =
conexion.prepareStatement(SELECT * FROM Cliente WHERE
codigo = ?)
Los parmetros de entrada se especifican por posicin utilizando
mtodos setXXX:
psmt.setInt(1, 20);
Misma equivalencia que los getXXX de ResultSet.
Los valores se conservan entre ejecuciones.
z Borrar parmetros: clearParameters()
Ejecucin:
Consulta: executeQuery().
Actualizacin: executeUpdate().
Curso 2006/2007

26/04/2007

Transacciones
z
z

17

Ejecucin de bloques de consultas SQL manteniendo las


propiedades ACID (Atomicy-Consistency-Isolation-Durability)
Una conexin funciona por defecto en modo autocommit:
Cada consulta representa una sola transaccin.
Mtodo: conexion.setAutocommit(false);
Definimos bloques de consultas:
Deshabilitando el modo autocommit.
Finalizamos la transaccin ejecutando commit() o
rollback() sobre la conexin.

Curso 2006/2007

Nivel de Aislamiento
Transaccional
z

18

Niveles de aislamiento:
TRANSACTION_NONE:
z Sin soporte transaccional.
TRANSACTION_READ_UNCOMMITED:
z Permite lecturas sobre datos no comprometidos.
TRANSACTION_READ_COMMITED:
z Permite lecturas slo sobre datos comprometidos.
z Nivel por defecto.
TRANSACTION_REPEATABLE_READ.
z Bloquea los datos ledos.
TRANSACTION_SERIALIZABLE.
z Slo una transaccin al mismo tiempo.
Suelen estar disponibles read commited y serializable.
Curso 2006/2007

26/04/2007

Concurrencia
z

19

Establecer el modo de aislamiento:


conexion.setTransactionIsolation(
Connection.TRANSACTION_SERIALIZABLE);
Consejos de uso:
Bloque con slo actualizaciones:
z TRANSACTION_READ_COMMITED
Bloque donde leamos varias veces el mismo registro:
z TRANSACTION_REPEATABLE_READ
TRANSACTION REPEATABLE READ
Bloque en el que leamos un valor para actualizarlo:
z TRANSACTION_SERIALIZABLE
Bloque donde realicemos varias veces la misma consulta (varios
registros):
z TRANSACTION_SERIALIZABLE
Curso 2006/2007

Bases de Datos en Entornos Web


z

20

Motivacin:
Mltiples conexiones simultneas a la base de datos.
El establecimiento de una conexin es costoso.
Consecuencia:
Definir cuidadosamente las transacciones.
Establecer algn mecanismo para optimizar el uso de
conexiones Pool de Conexiones
Pool de Conexiones:
Habitualmente implementado por los DataSource.

Curso 2006/2007

10

26/04/2007

Pool de Conexiones
z
z

21

Cuando no dispongamos de un DataSource que lo


implemente.
Recomendaciones de diseo:
Definir la clase ConnectionPool como Singleton.
Implementar la interface DataSource Objeto que
devuelve el getInstance.
Definir una clase ConnectionWrapper que implemente
Connection:
z Todos los mtodos a excepcin de close delegan en un
objeto Connection.
z close libera la conexin del pool.
Crear un lista de conexiones inicial que expandir si no
hay ninguna libre.
Curso 2006/2007

ConnectionPool - Estructura
< < In t e rf ac e > >
C o n n e c tio n
+ c o n e xio n
1

< < In t e rfa c e > >


D a t a S o u rc e

c re a te S ta te m e n t() : S ta te m e n t
p re p a re S ta te m e n t(c o n s u lta : S trin g ) : P re p a re d S ta te m e n t
c lo s e ()
...()

g e tC o n n e c tio n () : C o n n e c ti o n

C o n n e c t io n W ra p p e r
c re a te S ta te m e n t() : S ta te m e n t
p re p a re S ta te m e n t(( c o n s u lta : S trin g ) : P re p a re d S ta te m e n t
c lo s e ()
...()

C o n n e c t io n P o o l
+ pool
*

g e tC o n n e c tio n ( ) : C o n n e c tio n
r etu
t rn C o n n e ctio
ti n (c
( : C o n n e c ti
tio n P o o l)
< < s ta ti c> > ge t In s ta n c e () : D a ta S o u rc e

<<us es >>

" c lo s e " d e vu e lve e l o b je t o


C o n n e c t io n W ra p p e r a l P o o l
D r ive rM a n a g e r
c re a te C o n n e c tio n () : C o n n e c tio n

22

Curso 2006/2007

11

26/04/2007

Patrn DAO
z

Motivacin:
Almacenar y recuperar informacin persistente de diferentes
fuentes: bases de datos relacionales, LDAP, XML, etc.
Las APIs para el acceso a datos son muy diferentes.
La portabilidad y mantenimiento de los componentes (servlets,
EJB, ...) se ve limitada.
Solucin:
Usar un objeto DAO (Data Access Object) que abstraiga y
encapsule el acceso a la fuente de datos.
El DAO gestiona la conexin con la fuente de datos para obtener y
almacenar la informacin.

23

Curso 2006/2007

Colaboracin
ServletEdicion

Participantes:

dao : DAOCliente

getClienteByUsuario(usuario)

c : Cliente

Fuente de
datos

Obtiene los datos


new( )

return c

Objeto de negocio

DAO

ValueObject

Fuente de datos

Curso 2006/2007

getNombre()
Accede a los
datos
setCorreo( correo)
updateCliente(c)
d t Cli t ( )

getNombre()
Recupera la
informacin
Actualiza los datos

24

12

26/04/2007

Estrategia de Implementacin
Basada en los patrones Abstract Factory y Factory Method.
Pasos:

Definir la interface DAO de nuestros objetos de datos

z
z

public interface ClienteDAO


{
public Cliente create (String nombre, String nif, String
correo,
String usuario, String clave) throws
DAOException
DAOException;
public Cliente findClienteByUsuario (String usuario) throws
DAOException;
public java.util.Collection findAll () throws DAOException;
public void update (Cliente c) throws DAOException;
}

25

Curso 2006/2007

Factora Abstracta
z

Definir la factora abstracta de objetos DAO:

public abstract class DAOFactoria


{
public abstract ClienteDAO getClienteDAO() throws DAOException;
public abstract ProductoDAO getProductoDAO() throws DAOException;
public final static int ACCESS = 1;
...
public static DAOFactoria getDAOFactoria (int tipo) {
switch (tipo) {
case ACCESS:
return new AccessDAOFactoria();
case XML:
...
}

26

Curso 2006/2007

13

26/04/2007

Factora Concreta
z

Implementar la factora concreta:

public class AccessDAOFactoria extends DAOFactoria{


...
public ClienteDAO getClienteDAO() {
return (ClienteDAO) new
AccessClienteDAO(ds);
}
}

Simplemente instancia objetos DAO concretos.

27

Curso 2006/2007

Clase DAO
z

Implementar las clases DAO concretas:


import java.sql.*;
public class AccessClienteDAO implements ClienteDAO
{
...
public Cliente create (String nombre, String nif, String
correo,
String usuario, String clave) throws
DAOException
{
Connection con = null;
try {
con = ds.getConnection();
Statement stmt = con.createStatement();
stmt.executeUpdate(...);
stmt.close();
con.close();
Cliente c = new Cliente();
c.setNombre(nombre);
...

28

Curso 2006/2007
return c;
}

14

26/04/2007

Estructura
DAOFactoria
getClienteDAO() : ClienteDAO
getProductoDAO() : ProductoDAO
<<static>> getDAOFactoria() : DAOFactoria

AccessDAOFactoria

XMLDAOFactoria

getClienteDAO() : ClienteDAO
getProductoDAO() : ProductoDAO

getClienteDAO() : ClienteDAO
getProductoDAO() : ProductoDAO

<<create>>

<<create>>

AccessClienteDAO

AccessProductoDAO

<<Interface>>
ClienteDAO

<<Interface>>
ProductoDAO

create() : Cliente
findAll() : Collection
findByUsuario() : Cliente
update()

29

Curso 2006/2007

Consecuencias

30

Beneficios:
Favorece la transparencia.
Facilita la migracin de los componentes.
Reduce la complejidad del cdigo.
Centraliza todo el acceso a datos en una capa.

Inconvenientes:
Diseo de una jerarqua de clases.
Introduce una nueva capa.

Curso 2006/2007

15

You might also like