Você está na página 1de 47

Introduccin a JDBC

JTP: Ing. Felipe Steffolani


fsteffolani@sistemas.frc.utn.edu.ar
Objetivos y Temas
Objetivos
Conocer las motivaciones y causas de JDBC
Comprender el esquema de funcionamiento
de los Conectores J
Conocer el conjunto de interfaces y clases
que permiten enviar sentencias al DBMS y
las diferencias entre cada una de ellas.
Temas
JDBC Introduccin e Historia
Esquema de conectores
Conexiones
Clases intervinientes
Conexin, envi, proceso, liberacin.
Introduccin a JDBC
Java DataBase Connectivity
Es la API (librera) estndar de acceso a base
de datos desde Java
Est incluida en Java SE (Standard Edition)
En Java SE 6 se incluye JDBC 4.0, pero
actualmente la mayora de bases de datos
soportan JDBC 3.0 y JDBC 4.0
Ms informacin
http://java.sun.com/javase/technologies/database
http://java.sun.com/docs/books/tutorial/jdbc/
Introduccin a JDBC

Para conectarse a una base de datos concreta,


es necesario su driver JDBC
El driver es un fichero JAR que se aade a la
aplicacin como cualquier otra librera (no
necesita instalacin adicional)
La mayora de las bases de datos incorporan
un driver JDBC
ODBC (Open DataBase Connectivity) es un
estndar de acceso a base de datos
desarrollado por Microsoft. Sun ha
desarrollado un driver que hace de puente
entre JDBC y ODBC aunque no suele usarse.
Introduccin a JDBC
Los pasos para que una aplicacin se
comunique con una base de datos
son:
1. Cargar el driver necesario para
comprender el protocolo que usa la base
de datos concreta
2. Establecer una conexin con la base de
datos, normalmente a travs de red
3. Enviar consultas SQL y procesar el
resultado
4. Liberar los recursos al terminar
5. Manejar los errores que se puedan
producir
Esquema ODBC
La primera estandarizacin de cdigo
de acceso a los DBMS fue ODBC
Problema del Conector J
nativo de JDBC
Esquema de Conectores J
Luego en JDBC
JDBC propone 4 tipos de conectores:
Tipo 1: Bridge
Permite la conexin a travs de otro driver, por lo
general un driver ODBC
Tipo 2: Native
Permite la conexin a travs de llamadas propias
de la API del DBMS
Tipo 3: Network
Utiliza las libreras de cliente propias del motor de
base de datos.
Tipo 4: Thin
Convierte o traduce las llamadas al API JDBC en
llamadas al protocolo de red usado por el motor
de bases de datos, lo que en realidad es una
invocacin directa al motor de bases de datos.
Tipo de Conectores J
HolaMundo en Base de Datos
import java.sql.*;
public class HolaMundoBaseDatos {
public static void main(String[] args)
throws ClassNotFoundException, SQLException {

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

Connection conn = DriverManager.getConnection(


"jdbc:mysql://localhost:3306/sample","root","pass");

Statement stmt = conn.createStatement();


ResultSet rs = stmt.executeQuery(
"SELECT titulo, precio FROM Libros WHERE precio > 2");

while (rs.next()) {
String name = rs.getString("titulo");
float price = rs.getFloat("precio");
System.out.println(name + "\t" + price);
}
rs.close();
stmt.close(); Bambi 3.0
conn.close();
} Batman 4.0
}
import java.sql.*;
public class HolaMundoBaseDatos {
public static void main(String[] args)
throws ClassNotFoundException, SQLException {

Class.forName("com.mysql.jdbc.Driver");
Carga del
driver
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/sample","root","pass");

Statement stmt = conn.createStatement();


ResultSet rs = stmt.executeQuery(
"SELECT titulo, precio FROM Libros WHERE precio > 2");

while (rs.next()) {
String name = rs.getString("titulo");
float price = rs.getFloat("precio");
System.out.println(name + "\t" + price);
}
rs.close()
stmt.close();
conn.close();
}
}
Introduccin a JDBC
Carga del driver
Antes de poder conectarse a la base de datos
es necesario cargar el driver JDBC
Slo hay que hacerlo una nica vez al
comienzo de la aplicacin

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

El nombre del driver debe venir especificado


en la documentacin de la base de datos
Se puede elevar la excepcin
ClassNotFoundException si hay un error en
el nombre del driver o si el fichero .jar no est
correctamente en el CLASSPATH o en el
proyecto
import java.sql.*;
public class HolaMundoBaseDatos {
public static void main(String[] args)
throws ClassNotFoundException, SQLException {
Establecer
Class.forName("com.mysql.jdbc.Driver"); una conexin
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/sample","root","pass");

Statement stmt = conn.createStatement();


ResultSet rs = stmt.executeQuery(
"SELECT titulo, precio FROM Libros WHERE precio > 2");

while (rs.next()) {
String name = rs.getString("titulo");
float price = rs.getFloat("precio");
System.out.println(name + "\t" + price);
}
rs.close()
stmt.close();
conn.close();
}
}
Introduccin a JDBC
Establecer una conexin
Las bases de datos actan como servidores y
las aplicaciones como clientes que se
comunican a travs de la red
Un objeto Connection representa una
conexin fsica entre el cliente y el servidor
Para crear una conexin se usa la clase
DriverManager
Se especifica la URL, el nombre y la
contrasea
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/sample","root","pass");
Introduccin a JDBC
Establecer una conexin
El formato de la URL debe especificarse en el
manual de la base de datos
Ejemplo de MySQL

jdbc:mysql://<host>:<puerto>/<esquema>

jdbc:mysql://localhost:3306/sample

El nombre de usuario y la contrasea


dependen tambin de la base de datos
import java.sql.*;
public class HolaMundoBaseDatos {
public static void main(String[] args)
throws ClassNotFoundException, SQLException {

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

Connection conn = DriverManager.getConnection(


"jdbc:mysql://localhost:3306/sample","root","pass");

Statement stmt = conn.createStatement();


ResultSet rs = stmt.executeQuery(
"SELECT titulo, precio FROM Libros WHERE precio > 2");

while (rs.next()) { Ejecutar una


String name = rs.getString("titulo"); sentencia
float price = rs.getFloat("precio");
System.out.println(name + "\t" + price); SQL
}
rs.close()
stmt.close();
conn.close();
}
}
Introduccin a JDBC
Ejecutar una sentencia SQL
Una vez que tienes una conexin
puedes ejecutar sentencias SQL
Primero se crea el objeto Statement
desde la conexin
Posteriormente se ejecuta la consulta
y su resultado se devuelve como un
ResultSet
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(
"SELECT titulo, precio FROM Libros WHERE precio > 2");
import java.sql.*;
public class HolaMundoBaseDatos {
public static void main(String[] args)
throws ClassNotFoundException, SQLException {

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

Connection conn = DriverManager.getConnection(


"jdbc:mysql://localhost:3306/sample","root","pass");

Statement stmt = conn.createStatement();


ResultSet rs = stmt.executeQuery(
"SELECT titulo, precio FROM Libros WHERE precio > 2");

while (rs.next()) {
String name = rs.getString("titulo");
float price = rs.getFloat("precio");
System.out.println(name + "\t" + price);
}
rs.close()
stmt.close(); Acceso al conjunto
conn.close(); de resultados
}
}
Introduccin a JDBC
Acceso al conjunto de resultados

El ResultSet es el objeto que representa el


resultado
No carga toda la informacin en memoria
Internamente tiene un cursor que apunta a un
fila concreta del resultado en la base de datos
Hay que posicionar el cursor en cada fila y
obtener la informacin de la misma
while (rs.next()) {
String name = rs.getString("titulo");
float price = rs.getFloat("precio");
System.out.println(name + "\t" + price);
}
Acceso al conjunto de resultados
Posicionamiento del cursor

El cursor puede estar en una fila concreta


Tambin puede estar en dos filas especiales
Antes de la primera fila (Before the First Row, BFR)
Despus de la ltima fila (After the Last Row, ALR)
Inicialmente el ResultSet est en BFR
next() mueve el cursor hacia delante
Devuelve true si se encuentra en una fila concreta
y false si alcanza el ALR
while (rs.next()) {
String name = rs.getString("titulo");
float price = rs.getFloat("precio");
System.out.println(name + "\t" + price);
}
Acceso al conjunto de resultados
Posicionamiento del cursor
Acceso al conjunto de resultados
Obtencin de los datos de la fila

Cuando el ResultSet se encuentra en una fila


concreta se pueden usar los mtodos de
acceso a las columnas
String getString(String columnLabel)
String getString(int columnIndex) Los ndices
int getInt(String columnLabel) empiezan en
int getInt(int columnIndex) 1 (no en 0)

(existen dos mtodos por cada tipo)

while (rs.next()) {
String name = rs.getString("titulo");
float price = rs.getFloat("precio");
System.out.println(name + "\t" + price);
}
import java.sql.*;
public class HolaMundoBaseDatos {
public static void main(String[] args)
throws ClassNotFoundException, SQLException {

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

Connection conn = DriverManager.getConnection(


"jdbc:mysql://localhost:3306/sample","root","pass");

Statement stmt = conn.createStatement();


ResultSet rs = stmt.executeQuery(
"SELECT titulo, precio FROM Libros WHERE precio > 2");

while (rs.next()) {
String name = rs.getString("titulo");
float price = rs.getFloat("precio");
System.out.println(name + "\t" + price);
}
rs.close()
stmt.close();
conn.close();
Librerar Recursos
}
}
Introduccin a JDBC
Liberar recursos
Cuando se termina de usar una Connection,
un Statement o un ResultSet es necesario
liberar los recursos que necesitan
Puesto que la informacin de un ResultSet
no se carga en memoria, existen conexiones
de red abiertas
Mtodos close():
ResultSet.close() Libera los recursos del
ResultSet. Se cierran automticamente al cerrar el
Statement que lo cre o al reejecutar el Statement.
Statement.close() Libera los recursos del
Statement.
Connection.close() Finaliza la conexin con la
base de datos
import java.sql.*;
public class HolaMundoBaseDatos { Manejar los errores
public static void main(String[] args)
throws ClassNotFoundException, SQLException {

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

Connection conn = DriverManager.getConnection(


"jdbc:mysql://localhost:3306/sample","root","pass");

Statement stmt = conn.createStatement();


ResultSet rs = stmt.executeQuery(
"SELECT titulo, precio FROM Libros WHERE precio > 2");

while (rs.next()) {
String name = rs.getString("titulo");
float price = rs.getFloat("precio");
System.out.println(name + "\t" + price);
}
rs.close()
stmt.close();
conn.close();
}
}
Introduccin a JDBC
Manejar los errores
Hay que gestionar los errores apropiadamente
Se pueden producir excepciones
ClassNotFoundException si no se encuentra
el driver
Se pueden producir excepciones
SQLException al interactuar con la base de
datos
SQL mal formado
Conexin de red rota
Problemas de integridad al insertar datos (claves
duplicadas)
import java.sql.*;
public class HolaMundoGestionErrores {
Gestin de
public static void main(String[] args) {
errores en la
try { localizacin
Class.forName("com.mysql.jdbc.Driver"); del driver
} catch (ClassNotFoundException e) {
System.err.println("El driver no se encuentra");
System.exit(-1);
}

Connection conn = null;


try {
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/sample", "root", "pass");

Statement stmt = conn.createStatement();


ResultSet rs = stmt.executeQuery(
SELECT titulo, precio FROM Libros WHERE precio > 2");
while (rs.next()) {
String name = rs.getString("titulo");
float price = rs.getFloat("precio"); Gestin de
System.out.println(name + "\t" + price); errores en el
}
rs.close();
envo de
stmt.close(); consultas
} catch (SQLException e) {
System.err.println("Error en la base de datos: "+
e.getMessage());
e.printStackTrace();
} finally {
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
System.err.println("Error al cerrar la conexin: "+
e.getMessage());
} Gestin de
} errores al
}
}
cerrar la
} conexin
Conexiones a la base de datos
Cada objeto Connection representa una
conexin fsica con la base de datos
Se pueden especificar ms propiedades
adems del usuario y la password al
crear una conexin
Estas propiedades se pueden
especificar:
Codificadas en la URL (ver detalles de la
base de datos)
Usando mtodos getConnection()
sobrecargados de la clase DriverManager
Conexiones a la base de
datos
String url = "jdbc:mysql://localhost:3306/sample";
String name = "root";
String password = "pass" ;
Connection c = DriverManager.getConnection(url, user, password);

String url =
"jdbc:mysql://localhost:3306/sample?user=root&password=pass";
Connection c = DriverManager.getConnection(url);

String url = "jdbc:mysql://localhost:3306/sample";


Properties prop = new Properties();
prop.setProperty("user", "root");
prop.setProperty("password", "pass");
Connection c = DriverManager.getConnection(url, prop);
Sentencias SQL

Con JDBC se pueden usar diferentes tipos de


Statement
SQL esttico en tiempo de ejecucin,
no acepta parmetros
Statement stmt = conn.createStatement();

Para ejecutar la mismas sentencia


muchas veces (la prepara).
Acepta parmetros
PreparedStatement ps =
conn.prepareStatement(...);

Llamadas a procedimientos
almacenados
CallableStatement s =
conn.prepareCall(...);
Sentencias SQL
Uso de Statement
Tiene diferentes mtodos para ejecutar
una sentencia
executeQuery(...)
Se usa para sentencias SELECT. Devuelve un
ResultSet
executeUpdate()
Se usa para sentencias INSERT, UPDATE,
DELETE o sentencias DDL. Devuelve el
nmero de filas afectadas por la sentencia
execute()
Mtodo genrico de ejecucin de consultas.
Puede devolver uno o ms ResulSet y uno o
ms contadores de filas afectadas.
Sentencias SQL
Uso de
PreparedStatement
Los PreparedStatement se utilizan:
Cuando se requieren parmetros
Cuando se ejecuta muchas veces la misma sentencia
La sentencia se prepara al crear el objeto
Puede llamarse varias veces a los mtodos execute

PreparedStatement ps = conn.
prepareStatement("INSERT INTO Libros VALUES (?,?,?)");

ps.setInt(1, 23);
ps.setString(2, "Bambi");
ps.setInt(3, 45);

ps.executeUpdate();
Sentencias SQL
Uso de
CallableStatement
Permite hacer llamadas a los procedimientos
almacenados de la base de datos
Permite parmetros de entrada IN (como el
PreparedStatement), parmetros de entrada-
salida INOUT y parmetros de salida OUT

CallableStatement cstmt =
conn.prepareCall ("{call getEmpName (?,?)}");

cstmt.setInt(1,111111111);
cstmt.registerOutParameter(2,java.sql.Types.VARCHAR);

cstmt.execute();

String empName = cstmt.getString(2);


Transacciones
Las transacciones tratan un conjunto de
sentencias como una nica sentencia, de
forma que si una falla, todo lo anterior se
deshace
try { Por defecto se hace
conn.setAutoCommit(false); commit por cada
Statement statement = conn.createStatement(); sentencia. Hay que
statement.executeUpdate("DELETE );
statement.executeUpdate("DELETE ); desactivarlo
conn.commit();
conn.setAutoCommit(true);
statement.close(); Cuando se han
} catch (SQLException e) { ejecutado todas las
try { sentencias, se hace
conn.rollback();
Si algo } catch (SQLException e1) { commit
falla, se System.err.println("Error");
hace }
System.err.println("Error); Se vuelve a poner el
rollback autocommit, para el
} resto de la aplicacin
Uso de ResultSet

El ResultSet es el objeto que


representa el resultado de una
consulta
No carga toda la informacin en
memoria
Se pueden usar para actualizar, borrar
e insertar nuevas filas
Uso de ResultSet
Caractersticas
Al crear un Statement, un
PreparedStatement o un
CallableStatement, se pueden configurar
aspectos del ResultSet que devolver al
ejecutar la consulta

createStatement(
int resultSetType, int resultSetConcurrency);

prepareStatement(String SQL,
int resultSetType, int resultSetConcurrency);

prepareCall(String sql,
int resultSetType, int resultSetConcurrency);
Uso de ResultSet
Caractersticas
Caractersticas del ResultSet
resultSetType
ResultSet.TYPE_FORWARD_ONLY Slo movimiento
hacia delante (por defecto)
ResultSet.TYPE_SCROLL_INSENSITIVE Puede hacer
cualquier movimiento pero no refleja los cambios en la
base de datos
ResultSet.TYPE_SCROLL_SENSITIVE Puede hacer
cualquier movimiento y adems refleja los cambios en la
base de datos
resultSetConcurrency
ResultSet.CONCUR_READ_ONLY Slo lectura (por
defecto)
ResultSet.CONCUR_UPDATABLE - Actualizable
Uso de ResultSet
Caractersticas
Actualizacin de datos
rs.updateString(campo", valor");
rs.updateInt(1, 3);
rs.updateRow();

Insercin de datos

rs.moveToInsertRow();
rs.updateString(1, "AINSWORTH");
rs.updateInt(2,35);
rs.updateBoolean(3, true); Mueve el cursor a
rs.insertRow(); la posicin
anterior al
rs.moveToCurrentRow(); movimiento a
insercin
Uso de ResultSet
Posicionamiento del cursor

El cursor puede estar en una fila concreta


Tambin puede estar en dos filas especiales
Antes de la primera fila (Before the First Row, BFR)
Despus de la ltima fila (After the Last Row, ALR)
Inicialmente el ResultSet est en BFR
next() mueve el cursor hacia delante
Devuelve true si se encuentra en una fila concreta
y false si alcanza el ALR
while (rs.next()) {
String name = rs.getString("titulo");
float price = rs.getFloat("precio");
System.out.println(name + "\t" + price);
}
Uso de ResultSet
Posicionamiento del cursor
Uso de ResultSet
Mtodos que permiten un movimiento
por el ResultSet
next() Siguiente fila
previous() Fila anterior
beforeFirst() Antes de la primera
afterLast() Despus de la ltima
first() Primera fila
last() ltima fila
absolute() Movimiento a una fila concreta
relative() Saltar ciertas filas hacia delante
ResultSetMetaData

Es un objeto especial que contiene


toda la ifnormacin asociada a la
estructura del ResultSet
Se Obtiene ejecutando el mtodo
getMetaData del un objeto ResultSet
Entre otros datos provee informacin
acerca del nombre y label de las
columnas y tipos de datos de las
mismas.
DataSources en JDBC 4.0
En JDBC 4 existen los DataSources
Son objetos creados por el proveedor
del driver que me permiten obtener la
instancia de Connection sin pasar por
el DriverManager
Proveen mtodos para setear los
diferentes parmetros de la url de
conexin
Y luego se puede obtener la instancia
de connection a partir de ellos.
Uso de DataSource
Mtodo que devuelve una instancia de
Connection a partir del DataSource Creo una instancia del
Objeto DataSource del
private static Connection CrearConexionDS() Proveedor del Driver
{
Connection wCnn = null;
try
{
MysqlDataSource wDs = new MysqlDataSource();
wDs.setServerName("localhost");
wDs.setDatabaseName("PruebaGrafos");
wDs.setUser("root"); Establezco los
wDs.setPassword("mysqladmin"); parmetros de la
wCnn = wDs.getConnection();
}
conexin a la base
catch (SQLException ex) de datos
{
Logger
.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}

return wCnn; Obtengo la instancia


} de Connection
Preguntas

Felipe Steffolani
fsteffolani@sistemas.frc.utn.edu.ar