Está en la página 1de 46

JDBC

Programando interfaces para bases de


datos con java

Java

Java: Definiendo las clases

En Java, cualquier pedazo de cdigo que


se desee ejecutar debe formar parte de
una clase.
Cada clase se describe en un fichero que
debe nombrarse con el nombre de la
clase y la extensin java
As, si existe una clase que se llama
MiClaseDeJava debe definirse en un
fichero llamado MiClaseDeJava.java

Java: Importando Clases

Las primeras lneas de cdigo tienen que importar las


clases (o paquetes) que se usarn en la nueva clase.
Entre otras nos harn falta las clases definidas en el
paquete java.sql (el API de JDBC).

Para ello necesitas incluir la lnea:


import java.sql.*;.

La estrella indica que se desea importar todas las


clases contenidas en el paquete java.sql.
(Alternativamente se pueden especificar las clases
necesarias).

Java: Mtodo main

Si la clase ha de ser ejecutable, debe contener


un mtodo pblico llamado main
El mtodo debe ir tras la declaracin de la clase

import java.sql.*;
public class TestDriver {
public static void main(String[] Args) {
. . .
}//fin de main
. . .
}//fin de clase TestDriver

Java: Excepciones-I

Como veris todas las aplicaciones


incluyen "bloques" try y catch. Esta
es la forma que tiene Java de
manejar los errores/excepciones.
Java requiere que cuando alguna
rutina lanza una excepcin esta sea
recogida.

Java: Excepciones-II

Los arboles no dejan ver el bosque

try {
// Code that could generate an exception goes
here.
// If an exception is generated, the catch block
below
// will print out information about it.
} catch(SQLException ex) {
System.err.println("SQLException: " +
ex.getMessage());
ex.printStackTrace();
System.exit(1);
}

JDBC

Introduccin

JDBC provee una librera para acceder


a distintas bases relacionales y
normaliza la mayor parte de las
operaciones (las hace independientes
de la base de datos utilizada y por
tanto portables). Es parte de las
distribuciones standard de Java
JDBC no comprueba que las sentencias
SQL son correctas, sencillamente las
pasa a la base de datos

JDBC drivers

JDBC consta de un

API genrico (escrito en java)


Drivers especficos de cada base de
datos que se encargan de las
interacciones con la base de datos
especificas de cada sistema que
"habla" a la base con la base de datos.

Tanto el API como los drivers se


ejecutan en el cliente.

Ms informacion en:

Sun JDBC web

JDBC tutorial

http://java.sun.com/docs/book/tutorial/j
dbc

Lista de drivers

http://java.sun.com/products/jdbc

http://industry.java.sun.com/products/jd
bc/drivers

java.sql API

http://java.sun.com/j2se/1.4/docs/api/ja
va/sql/package-summary.html

Siete pasos bsicos para


programar en JDBC

Cargar el driver de la base de datos


a acceder
Definir el URL usado para
Establecer la conexin
Crear una orden SQL
Ejecutarla
Procesar los resultados
Cerrar la conexin

Cargar el driver
// cargar las clases relacionadas con sql
. . .
// carga el driver usando el metodo Class.forName()
try {
Class.forName("org.postgresql.Driver");
} catch (ClassNotFoundException cnfe) {
System.out.println("Couldn't find the driver!");
System.out.println("Let's print a stack trace, and
exit.");
cnfe.printStackTrace();
System.exit(1);
}
// Si el driver no esta disponible, el mtodo
forName() //emitira una excepcion del tipo
//ClassNotFoundException.

Cargar el driver II

Como veis cargar el driver requiere una nica lnea


de cdigo.
La forma de cargar el driver mostrada en la
transparencia anterior es la ms comn pero hace
que el codigo no sea portable, si cambiamos de
base de datos y la nueva eleccin no es
postgreSQL.
Otra posibilidad es especificar el driver necesario
cuando se ejecuta el programa pasandolo mediante
-Dargumento. Por ejemplo:

java -Djdbc.drivers=org.mysql.Driver
myaplicacion

Definir el URL usado para


Establecer la conexin
Una vez cargado el driver hay que solicitar
una conexin a la base de datos, para ello
se usa la clase DriverManager y un URL
como el siguiente.
jdbc:postgresql:peliculas

jdbc:nombre_driver_base://host:puerto
/nombre_de_la_base

Establecer la conexin
Connection connection = null;
connection =
DriverManager.getConnection("jdbc:pos
tgresql:peliculas",
"username","password");
_____________________________
Ver Ejemplo1
-> programa trivial
Ver Ejemplo 1_5 (NO) -> usando java -Djdbc...

Opcionalmente conseguir
informacin sobre la base
import java.sql.DatabaseMetaData
//cargar driver
//conectarse a la base
. . .
DatabaseMetaData dbMetaData = connection.getMetaData();
String productName =
dbMetaData.getDatabaseProductName();
System.out.println("Database: " + productName);
String productVersion =
dbMetaData.getDatabaseProductVersion();
System.out.println("Version: " + productVersion);
// check if "actor" table is there
ResultSet tables = dbMetaData.getTables(null, null, "actor",
null);
if (tables.next()) {
System.out.println("Table exists");
}
-----Ejemplo1_6

http://java.sun.com/j2se/1.3/docs/api/java/sql/DatabaseMetaData.html

Crear una Sentencia SQL y


ejecutarla
El siguiente paso requiere la creacin de un objeto de la clase
Statement. El se encargar de enviar la consulta en SQL a la base.
Statement statement = connection.createStatement();
//statement necesita una conexin abierta

Es necesaria una instancia activa de una conexin para crear el


objeto Statement

JDBC devuelve los resultados en un objeto de la clase ResultSet


Finalmente, ejecutamos la consulta
String query = "SELECT * FROM cia";
ResultSet resultSet = statement.executeQuery(query);
//el resultado de la consulta se almacena
//en resulset
// NO SE PONE ; AL FINAL DE LA CONSULTA
Example2_0

Si se desea modificar la
Base

Entonces se ejecuta:

executeUpdate(string); en lugar de
executeQuery(string) (donde string
contiene UPDATE, INSERT o DELETE);
SetQueryTimeout se puede usar para
especificar cuanto se espera antes de
abortar la transaccin

Statement se puede
reutilizar

No hace falta crear un objeto estatement para cada consulta

statement.executeUpdate("INSERT INTO cia " +


"VALUES('Algeria','Africa'," +
"2381740.0,28539321.0,97100000000.0)");
statement.executeUpdate("INSERT INTO cia " +
"VALUES(American Samoa'," +
"'Oceania',199.0,57366.0,128000000.0)");
Prestar atencin a la forma de romper las lineas:

espacio tras cia


dobles comillas para cada lnea
+ uniendo la orden SQL

Procesando los resultados

El objeto resultSet, contiene 265 tuplas describiendo los


distintos pases. Para acceder a los distintos valores se
leern las tuplas una a una y accederemos a los atributos
usando distintos mtodos segn el tipo de variable.
El mtodo next mueve el cursor a la siguiente tupla (la
cual sobre la que se opera)
Cada invocacin al mtodo next mueve el cursor una fila
hacia delante

Procesar los resultados


//Los metodos usados no son los correctos para cia
while(resultSet.next()) {
System.out.println(resultSet.getString(1) + " " +
resultSet.getDouble(2) + " " +
resultSet.getInt(3) + " " +
resultSet.getTimeStamp(4));

La primera columna tiene ndice 1 (no 0)

ResultSet define varios mtodos getXxxx que dado


el nmero de columna devuelve el valor all
almacenado

A partir de JDBC 2.0, es posible mover el cursor hacia atrs


yo incrementarlo en ms de una unidad
srs.absolute(4);
srs.relative(-3);

Procesar los Datos

Tambin se puede indexar usando


atributos.

while(resultSet.next()) {
System.out.println(resultSet.getString(1) + " " +
resultSet.getString(2) + " " +
resultSet.getInt(3)
+ " " +
resultSet.getInt(4));
while(resultSet.next()) {
System.out.println(resultSet.getString("nombre") + " " +
resultSet.getString("region") + " " +
resultSet.getInt
("area")
+ " " +
resultSet.getInt("poblacion"));

Cerrar la conexin

connection.close();
Abrir una conexin es caro as que
debe posponerse el cierre de la
conexin si se van a ejecutar ms
consultas a la misma base de datos

Ejemplo Completo-I
import java.sql.*;
public class TestDriver {
public static void main(String[] Args) {
try {
//Constructor
Class.forName("org.postgresql.Driver");}
Connection connection =
DriverManager.getConnection
("jdbc:postgresql:cia","roberto","pepino");
Statement statement =
connection.createStatement();
String consultaSQL = "SELECT 1+1";

Ejemplo Completo-II
ResulSet results = statement.executeQuery(consultaSQL);
//Mostrar datos
int outp;
while (results.next())
{
outp = results.getInt();
System.out.println("1+1 es: " + outp + "\n");
}
connection.close();
} catching excepcion
cath(java.lang.Exception ex){
System.out.println("Error: " + ex);
}}}

ResultSetMetaData:

ResulSetMetaData

Ya lo vimos al principio de la charla


Permite responder a preguntas como:

Cuntas columnas hay en un ResultSet?


Cul es el nombre de una columna en
particular?
Qu tipo de datos contiene una columna
en particular?
Cul es el tamao mximo de una
columna?

ResulSetMetaData:
Mtodos
getColumnCount

getColumnDisplaySize

mximo ancho de la columna


especificada

getColumnName

nmero de columnas de la relacin

nombre de la columna

getColumnType

tipo de datos (SQL ) de la columna

ResulSetMetaData:
Mtodos

isNullable

Esta columna puede contener NULLs?


Las posibles respuestas son
columnNoNulls, columnNullable,
columnNullableUnknown

Ejemplo usando "Meta


Data"
//Este cdigo no compila, driver ya cargado
Connection connection=
DriverManager.getConnection(url,username,password);
//Info sobre la base de datos
DatabaseMetaData dbMetaData =
connection.getMetaData();
String productName =
dbMetaData.getDatabaseProductName();
System.out.println("Database: " + ProductName);
String productVersion =
dbMetaData.getDatabaseProductVersion();
. . .

Ejemplo usando "Meta Data"


II
Statement statement = connection.createStatement();
String query = "SELECT * FROM cia";
ResultSet resultset = statement.executeQuery(query);
//Info sobre la tabla
ResultSetMetaData resultsMetaData =
resultSet.getMetaData();
int columnCount = resultsMetaData.getColumnCount();
// El ndice de las columnas empieza en 1
for (int i=1; i< columnCount ;i++)
System.out.print( resultsMetaDAta.getColumnName(i)
+ " ");
//etc, etc, etc

Statement

Statement

A travs de la clase Statement, se


envan las consultas en SQL a la base
Existen varios tipos de objetos
"statement". Nos concentraremos en
dos:

Statement: ejecccin de consultas sencillas.


PreparedStatement: ejecucin de consultas
precompiladas (parametrizadas).

PreparedStatement

Si se van a ejecutar varias consultas


similares el uso de consultas
"parametrizadas" puede ser ms eficiente
Se crea la consulta, este se enva a la base
de datos donde se optimiza antes de ser
usada.
Cuando se desee usar basta con remplazar
los parmetros usando los mtodos
setXxxx
Ejemplo6

Transacciones

Transacciones

Por defecto JDBC abre las conexiones en


modo autocommit, esto es, cada
comando se trata como una transaccin
Para controlar las transacciones se debe:

anular el modo autocommit


connection.setAutoCommit(false);

llamar commit para registrar


permanentemente los cambios

llamar a rollback en caso de error

Transacciones: ejemplo
Connection connection =
DriverManager.getConnection(url,username,passwd);
connectio.setAutoCommit(false);
//setTransactionIsolation
//NO commit explicito
try{
statement.executeUpdate();
statement.executeUpdate();
} catch (SQLExcepcione e){
try{
connection.rollback();
} catch(SQLExcepcion sqle) {
//report problem
}
}

Transacciones: ejemplo II
try {
connection.commit();
connection.close();
} catch (SQLException sqle) {}
}

Utilidades
DatabaseUtilities y DBResults

Idea:

La tarea ms "repetitiva" en JDBC es la


realizacin de consultas y el formateo
de las respuestas. DatabaseUtilities
y DBResults facilitan estas tareas.

Mtodos:

getQueryResults

conecta la base
realiza la consulta
trae las tuplas resultado (como strings)
las coloca en un objeto DBResults

createTable. Dado:

El nombre de una tabla


una cadena describiendo el tipo de los
atributos
un array de strings con una instancia de la
tabla
Este metodo crea la tabla (CREATE TABLE)
y la puebla (INSERT)

printTable

Dado el nombre de una tabla este


mtodo se conecta a la base e imprime
el contenido de la tabla por pantalla

printTableData

Dado un objeto DBResults obtenido


con anterioridad. printTableData
imprime el resultado por pantalla

Ejemplo
DBResults results =
DatabaseUtilities.getQueryResults(driver,
url, username, password,query,true);
out.println(results.toHTMLTable("CYAN"));

DBUtilities/jesus/cwp/CiaTest.java
compile all/run from above
Example3 (command line)/Example4 (input)

Curiosidad: Qu es lo que se
manda de verdad?
El comado SQL puede ser transformado
de acuerdo a las peculiaridades de la base
String Nat =
connection.nativeSQL("SELECT * FROM
cia WHERE name='rrr'");
System.out.println("native: " +nat +
"\n");
Aunque normalmente no lo es para estos
casos tan sencillos

Example2_1.java

También podría gustarte