You are on page 1of 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
http://java.sun.com/products/jdbc
JDBC tutorial
http://java.sun.com/docs/book/tutorial/jdbc
Lista de drivers
http://industry.java.sun.com/products/jdbc/d
rivers
java.sql API
http://java.sun.com/j2se/1.4/docs/api/java/s
ql/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:p
ostgresql: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
nmero de columnas de la relacin
getColumnDisplaySize
mximo ancho de la columna especificada
getColumnName
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

You might also like