Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Índice
1. Introducción 1
1.1. JDBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2. Arquitecturas tı́picas con JDBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1. Introducción
Un sistema gestor de base de datos que permita la conexión mediante JDBC (MySQL)
Un editor para Java (Eclipse 2.1.3 que es más que un editor para Java...)
J2SE: java.sun.com
Eclipse: www.eclipse.org
MySQL: www.mysql.org
En la dirección:
http://dev.mysql.com/downloads/connector/j/3.0.html
Se obtiene el archivo
mysql-connector-java-3.0.14-production.zip
Página: 1
JDBC MySQL y Java
Julio 2004. Universitat de València
mysql-connector-java-3.0.12-production.jar
Este fichero debe estar en un sitio visible para Java tanto al compilar la aplicación como al ejecu-
tarla.
1.1. JDBC
JDBC: Java DataBase Connectivity (Conexión con Bases de Datos mediante Java).
¿Qué es JDBC? es una biblioteca de clases que permite la conexión con Bases de Datos que soporten
SQL utilizando Java.
Permite realizar operaciones (consultas, actualizaciones, ...) sobre bases de datos relacionales uti-
lizando SQL (Structured Query Language).
¿Que ventajas ofrece acceder a la base de datos utilizando JDBC y Java? Que la aplicación será in-
dependiente de la plataforma y que se puede mover la aplicación de un sistema gestor de bases de
datos a otro (por ejemplo de Oracle a MySQL o a Microsoft SQL Server o a...).
Controlador tipo 3: es una biblioteca cliente escrita completamente en Java que utiliza
un protocolo independiente de la BD para comunicar las peticiones a un servidor que
las traduce a un protocolo especı́fico de la Base de Datos.
Controlador tipo 4: es una biblioteca escrita completamente en Java que traduce las
peticiones a un protocolo especı́fico de la Base de Datos.
Resumiendo:
Página: 2
JDBC MySQL y Java
Julio 2004. Universitat de València
Mediante JDBC se pueden escribir aplicaciones Java en las que se puede acceder a
Bases de Datos utilizando sentencias SQL estándar.
Las clases proporcionadas en los paquetes java.sql y javax.sql definen el API JDBC.
Servidor
Cliente JDBC de la BD
Protocolo de la BD
La desventaja que tiene esta arquitectura es que la Base de Datos es directamente accesible y es
complicado el control sobre el tipo de consultas que se pueden realizar.
Página: 3
JDBC MySQL y Java
Julio 2004. Universitat de València
La ventaja es que la Base de Datos queda oculta tras la capa intermedia. Es mucho más fácil
controlar el tipo de consultas (ya que estas se realizan desde la capa intermedia sobre la que se
tiene pleno control).
Los pasos a realizar para utilizar JDBC en una aplicación Java son los siguientes:
5. Cerrar la conexión
Página: 4
JDBC MySQL y Java
Julio 2004. Universitat de València
Lo primero que hemos de hacer es ver cual es la clase que implementa a esta interfaz en el contro-
lador JDBC que vamos a utilizar:
Una vez identificado el controlador debe ser registrado para poder ser utilizado en la aplicación.
Por supuesto, al inicio de nuestra aplicación debe aparecer (al menos) la siguiente biblioteca de
clases:
import java . s q l . ∗ ;
El formato es el siguiente:
j d b c : nombre : o t r o s e l e m e n t o s
Ejemplos:
j d b c : mysql : / / l o c a l h o s t : 3 3 0 6 / L i b r o s ? u s e r=u s u a r i o&password=c l a v e
Se especifica que la base de datos está en la máquina local, que el puerto donde escucha mysql es
el 3306, que la base de datos a utilizar es Libros, que el usuario es usuario y que el password es clave
Página: 5
JDBC MySQL y Java
Julio 2004. Universitat de València
j d b c : mysql : / / e p i . uv . e s : 3 3 0 6 / V i a j e s ? u s e r=admin&password=admin48
Se especifica que la base de datos está en la máquina cuyo nombre es epi.uv.es, que el puerto donde
escucha mysql en esa máquina es el 3306, que la base de datos a utilizar es Viajes, que el usuario es
admin y que el password es admin48
Una vez que se ha registrado la clase del controlador se puede una instancia de Connection.
p u b l i c s t a t i c C o n n e c t i o n g e t C o n n e c t i o n ( S t r i n g u r l ) t h r o w s SQLException
Cuando se llama a este método, el DriverManager intentará localizar un controlador apropiado entre
los que se hayan registrado.
...
try {
C o n n e c t i o n conn = DriverManager . g e t C o n n e c t i o n ( u r l ) ;
// R e a l i z a r a l g o con l a c o n e x i o n
...
} c a t c h ( SQLException ex ) {
// h a n d l e any e r r o r s
System . out . p r i n t l n ( ” SQLException : ” + ex . g e t M e s s a g e ( ) ) ;
System . out . p r i n t l n ( ” SQLState : ” + ex . getSQLState ( ) ) ;
System . out . p r i n t l n ( ” VendorError : ” + ex . g e t E r r o r C o d e ( ) ) ;
}
...
Mediante la interfaz DatabaseMetaData es posible obtener información del sistema gestor de bases
de datos o de una determinada base de datos.
1
La interfaz DataSource, nueva en JDBC 2.0, proporciona otra forma de conectarse con una fuente de datos. El uso
de un objeto DataSource es el método recomendado para conectarse a una fuente de datos desde una aplicación web.
Página: 6
JDBC MySQL y Java
Julio 2004. Universitat de València
Utilizando esta clase se podrı́an obtener las capacidades de un determinado sistema gestor de bases
de datos.
Esta clase dispone de entre otros (consúltese el API para un listado completo) los siguientes
métodos:
p u b l i c S t r i n g getDatabaseProductName ( )
Nombre d e l SGBD
p u b l i c String getDatabaseProductVersion ( )
V e r s i ó n d e l SGBD
p u b l i c S t r i n g getDriverName ( )
Nombre d e l c o n t r o l a d o r
p u b l i c R e s u l t S e t g e t C a t a l o g s ( ) t h r o w s SQLException
L i s t a d o de l a s b a s e s de d a t o s e x i s t e n t e s
p u b l i c R e s u l t S e t g e t T a b l e s ( S t r i n g c a t a l o g , S t r i n g schemaPattern , S t r i n g tableNamePattern ,
String [ ] types )
L i s t a d o de l a s t a b l a s en una b a s e de d a t o s
Ejemplo : r e f e r e n c i a . g e t T a b l e s ( ” e s t a n c i a s ” , ” %” , ” %” , n u l l ) ; }
p u b l i c R e s u l t S e t ge tT a bl eT yp e s ( ) t h r o w s SQLException
L i s t a d o con l o s t i p o s de t a b l a s s o p o r t a d a s por e l SGBD
import java . s q l . ∗ ;
p u b l i c c l a s s Metadatos {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
try {
S t r i n g URL = ” j d b c : mysql : / / l o c a l h o s t : 3 3 0 6 / e s t a n c i a s ? u s e r=u s u a r i o&password=c l a v e ” ;
C o n n e c t i o n conn = DriverManager . g e t C o n n e c t i o n ( u r l ) ;
conn . c l o s e ( ) ;
} c a t c h ( SQLException ex ) {
System . out . p r i n t l n ( ” SQLException : ” + ex . g e t M e s s a g e ( ) ) ;
System . out . p r i n t l n ( ” SQLState : ” + ex . getSQLState ( ) ) ;
System . out . p r i n t l n ( ” VendorError : ” + ex . g e t E r r o r C o d e ( ) ) ;
}
}
}
Página: 7
JDBC MySQL y Java
Julio 2004. Universitat de València
j a v a c − c l a s s p a t h m y s q l j d b c . j a r ; . Metadatos . j a v a
Ejercicio 1
Realizar una conexión con la base de datos de otra máquina y mostrar la siguiente información:
La versión
La ejecución de sentencias en la base de datos a través de JDBC se realiza mediante las interfaces
Statement o PreparedStatement.
Los objetos de estos tipos se obtienen a partir del objeto de tipo Connection
Mediante objetos de este tipo se pueden ejecutar sentencias SQL sencillas y obtener los resultados
mediante la clase ResulSet.
Para obtener un objeto del tipo Statement se llama al método createStatement() del objeto Connection.
Una vez que se dispone del objeto se pueden ejecutar sentencias SELECT (que no modifican las
tablas) utilizando el método
R e s u l S e t e x e c u t e Q u e r y ( S t r i n g SQL)
El resultado de la consulta se devuelve en un objeto del tipo ResultSet, es decir, para acceder a la
información habrá que utilizar los métodos de esta clase.
Para ejecutar sentencias que contengan UPDATE, INSERT o DELETE hay que utilizar el método
i n t e x e c u t e U p d a t e ( S t r i n g SQL)
Página: 8
JDBC MySQL y Java
Julio 2004. Universitat de València
Este método devuelve true si la sentencia contenı́a un SELECT y false en caso contrario.
Si la sentencia contenı́a un SELECT se pueden obtener los resultados llamando al método getRe-
sultSet() que devuelve un objeto del tipo ResulSet.
En caso contrario se puede obtener el número de filas afectadas llamando al método getUpdate-
Count().
Ejemplos:
...
Statement s = DriverManager . g e t C o n n e c t i o n ( u r l ) . c r e a t e S t a t e m e n t ( ) ;
ResulSet rs ;
S t r i n g s e n t e n c i a S Q L = ”SELECT ∗ FROM c a s a s ” ;
r s = s . executeQuery ( sentenciaSQL ) ;
...
...
Statement s = DriverManager . g e t C o n n e c t i o n ( u r l ) . c r e a t e S t a t e m e n t ( ) ;
i n t filasMod ;
S t r i n g s e n t e n c i a S Q L = ” update c a s a s s e t DispHasta = ’2004 −11 −30 ’ where IdCasa=7” ;
filasMod = s . executeUpdate ( sentenciaSQL ) ;
...
...
Statement s = DriverManager . g e t C o n n e c t i o n ( u r l ) . c r e a t e S t a t e m e n t ( ) ;
boolean tipoSentencia ;
B u f f e r e d R e a d e r br = new B u f f e r e d R e a d e r ( new InputStreamReader ( System . i n ) ) ;
s e n t e n c i a S Q L = br . r e a d L i n e ( ) ;
t i p o S e n t e n c i a = s . execute ( sentenciaSQL ) ;
i f ( tipoSentencia ){
ResulSet rs = s . getResultSet () ;
...
} else
i n t f i l a s M o d = s . getUpdateCount ( ) ;
...
}
...
La interfaz PreparedStatement extiende a la interfaz Statement y utiliza una plantilla para crear la
sentencia SQL.
Se utiliza en aquellas situaciones en las que se necesita ejecutar varias veces una consulta en la
que pueden cambiar únicamente los parámetros. De esta forma (si el SGBD lo permite) se optimiza
la consulta una sola vez.
Página: 9
JDBC MySQL y Java
Julio 2004. Universitat de València
Par obtener un objeto del tipo PreparedStatement se llamará al método prepareStatement(.) del objeto
del tipo Connection.
A este método hay que pasarle la plantilla donde se especifican los lugares donde irán los paráme-
tros.
Los parámetros son después especificados utilizando los métodos setXXX(.) indicando el número de
parámetro y el dato a insertar en la sentencia.
PreparedStatement de consulta
Por ejemplo supongamos que hay un campo de texto en el que el usuario puede introducir su
dirección de correo electrónico y con este dato se desea buscar al usuario:
...
C o n n e c t i o n con = DriverManager . g e t C o n n e c t i o n ( u r l ) ;
S t r i n g c o n s u l t a = ”SELECT u s u a r i o FROM r e g i s t r o WHERE e m a i l l i k e ? ” ) ;
P r e p a r e d S t a t e m e n t pstmt = con . p r e p a r e S t a t e m e n t ( c o n s u l t a ) ;
pstmt . s e t S t r i n g ( 1 , campoTexto . g e t T e x t ( ) ) ;
R e s u l t S e t r e s u l t a d o = ps . e x e c u t e Q u e r y ( ) ;
...
PreparedStatement de modificación
...
C o n n e c t i o n con = DriverManager . g e t C o n n e c t i o n ( u r l ) ;
S t r i n g i n s e r c i o n = ”INSERT INTO r e g i s t r o ( u s u a r i o , e m a i l , f e c h a N a c ) v a l u e s ( ? , ? , ? ) ” ) ;
P r e p a r e d S t a t e m e n t pstmt = con . p r e p a r e S t a t e m e n t ( c o n s u l t a ) ;
String user = . . . ;
String email = . . . ;
Date edad = . . . ;
pstmt . s e t S t r i n g ( 1 , u s e r ) ;
pstmt . s e t S t r i n g ( 2 , e m a i l ) ;
pstmt . s e t D a t e ( 3 , edad ) ;
ps . e x e c u t e U p d a t e ( ) ;
...
Como hemos visto en los ejemplos anteriores el resultado de una consulta es devuelto en un objeto
del tipo ResultSet.
Página: 10
JDBC MySQL y Java
Julio 2004. Universitat de València
Podemos imaginar que el resultado se devuelve en forma de tabla donde las filas corresponden a
los registros y las columnas a los datos.
Primero hay que colocarse en una determinada fila y a continuación acceder a la columna deseada.
Para ello, la clase ResultSet dispone de métodos para moverse en filas y de métodos para seleccionar
una determinada columna.
void beforeFirst ()
void f i r s t ()
void afterLast ()
void l a s t ()
boolean next ( )
boolean previous ()
3
Por defecto los objetos del tipo ResultSet no son actualizables y tienen un cursor que sólo puede ir hacia adelante.
Por tanto, se puede iterar a lo largo de él una sola vez y desde el inicio hasta el final. Es posible crear ResultSet que se
puedan actualizar y/o que permitan libertad de movimientos. Se verá más adelante
Página: 11
JDBC MySQL y Java
Julio 2004. Universitat de València
Para seleccionar columnas una vez que nos hemos colocado en un determinado registro se dispone
de dos conjuntos de métodos.
Por un lado métodos que reciben un entero (que indica el número de la columna) y por otro
métodos que reciben el nombre de la columna.
Por ejemplo si se desea obtener el valor de una columna que es de tipo float se dispone de los dos
métodos:
f l o a t g e t F l o a t ( i n t numeroColumna )
f l o a t g e t F l o a t ( S t r i n g nombreColumna )
i n t g e t I n t ( i n t numeroColumna )
i n t g e t I n t ( S t r i n g nombreColumna )
Se pueden obtener metadatos relacionados con el ResultSet utilizando el método getMetaData() que
devuelve un objeto del tipo ResultSetMetaData
i n t getColumnCount ( )
S t r i n g getColumnName ( i n t column )
S t r i n g getColumnTypeName ( i n t column )
Ejemplo:
import java . s q l . ∗ ;
p u b l i c c l a s s EjemploResultSet {
Página: 12
JDBC MySQL y Java
Julio 2004. Universitat de València
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
try {
S t r i n g u r l = ” j d b c : mysql : / / l o c a l h o s t : 3 3 0 6 / e s t a n c i a s ? u s e r=u s u a r i o&password=c l a v e ” ;
C o n n e c t i o n con = DriverManager . g e t C o n n e c t i o n ( u r l ) ;
Statement s = con . c r e a t e S t a t e m e n t ( ) ;
ResultSet resultado ;
S t r i n g s e n t e n c i a S Q L = ”SELECT Ciudad , DispDesde , DispHasta FROM c a s a s ” ;
r e s u l t a d o = s . executeQuery ( sentenciaSQL ) ;
resultado . beforeFirst () ;
w h i l e ( r e s u l t a d o . next ( ) ) {
S t r i n g c i u = r e s u l t a d o . g e t S t r i n g ( ” Ciudad ” ) ;
j a v a . s q l . Date f e c h 1 = r e s u l t a d o . g e t D a t e ( ” DispDesde ” ) ;
j a v a . s q l . Date f e c h 2 = r e s u l t a d o . g e t D a t e ( ” DispHasta ” ) ;
System . out . p r i n t ( ” Casa en : ” + c i u ) ;
System . out . p r i n t ( ” Desde : ” + f e c h 1 ) ;
System . out . p r i n t ( ” Hasta : ” + f e c h 2 ) ;
System . out . p r i n t l n ( ) ;
}
con . c l o s e ( ) ;
} c a t c h ( SQLException ex ) {
System . out . p r i n t l n ( ” SQLException : ” + ex . g e t M e s s a g e ( ) ) ;
System . out . p r i n t l n ( ” SQLState : ” + ex . getSQLState ( ) ) ;
System . out . p r i n t l n ( ” VendorError : ” + ex . g e t E r r o r C o d e ( ) ) ;
} c a t c h ( ClassNotFoundException e ) {
System . out . p r i n t l n ( ”No s e e n c u e n t r a e l c o n t r o l a d o r ” ) ;
}
}
}
Ojo, puede que alguno de los tipos de la izquierda no estén soportados por todas las Bases de
Página: 13
JDBC MySQL y Java
Julio 2004. Universitat de València
Ejercicio 2
Realizar una consulta en la que se muestren las familias del Reino Unido donde el precio de
estancia por dı́a sea menor o igual a 18 euros y que muestre por pantalla el nombre de la familia,
la ciudad y el tipo de casa.
Ejercicio 3
Debido a la devaluación de la libra esterlina respecto al euro se desea incrementar en un 5 por
ciento el precio por dı́a de todas las casas del Reino Unido. Realizar la actualización de los
precios.
Las versiones anteriores a JDBC 2.0 devolvı́an los resultados con cursores que sólo podı́an ir hacia
adelante. Cada elemento se obtenı́a llamando al método next().
A partir de JDBC 2.0 se puede recorrer el resultado en las dos direcciones y se puede actualizar el
resultado si esta operación está soportada por la base de datos.
Una ventaja es que se pueden actualizar una serie de columnas sin necesidad de enviar ninguna
llamada executeUpdate(). La actualización se realiza de forma automática.
// Para c r e a r un S t a t e m e n t
Statement stmt = conn . c r e a t e S t a t e m e n t ( i n t t i p o R e s u l t a d o , i n t t i p o A c t u a l i z a c i o n ) ;
// Para c r e a r un P r e p a r e d S t a t e m e n t
P r e p a r e d S t a t e m e n t pstmt = conn . p r e p a r e S t a t e m e n t ( S t r i n g s q l , i n t t i p o R e s u l t a d o , i n t
tipoActualizacion ) ;
Página: 14
JDBC MySQL y Java
Julio 2004. Universitat de València
Es posible verificar si la Base de Datos soporta estos tipos utilizando el siguiente método
En cuanto a la actualización del resultado se pueden utilizar los métodos updateTIPO(.) (donde
TIPO es el tipo de dato a actualizar) que ofrece la interfaz ResultSet.
A continuación se envı́a el mensaje updateRow() al objeto del tipo ResultSet para que actualice la
fila en la base de datos.
Por ejemplo, el siguiente código se puede utilizar para modificar el valor de la fecha en el resultado
y actualizar la base de datos:
r s . a b s o l u t e ( 5 ) ; // mueve e l c u r s o r a l a fila 5
// a c t u a l i z a l a f e c h a en e l R e s u l t S e t
r s . updateDate ( ” Fecha ” , ”2004−04−01” ) ;
// A c t u a l i z a l a f e c h a en l a b a s e de d a t o s para e l
// r e g i s t r o s e l e c c i o n a d o
r s . updateRow ( ) ;
Ejercicio 4
Realizar la actualización de los precios del ejercicio 3 del siguiente modo:
Crear un Statement en el que se permita el movimiento en cualquier dirección y en el que las
actualizaciones se reflejan en cuanto se producen y además que el resultado sea actualizable.
Ejecutar una sentencia de consulta en la que se seleccione el pais y el precio de todas las casas.
Recorrer el ResultSet obtenido mostrando el pais y el precio y si además el pais es el Reino Unido
actualizar el precio por dı́a subiéndolo un 5 por ciento.
Página: 15