JDBC B asico - UNAM

70
Introducci´ on a XML JDBC B´ asico Amparo L´ opez Gaona exico, D.F. Octubre del 2004

Transcript of JDBC B asico - UNAM

Page 1: JDBC B asico - UNAM

Introduccion a XML

JDBC Basico

Amparo Lopez Gaona

Mexico, D.F. Octubre del 2004

Page 2: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Introduccion

JDBCTM es una API contenida en Java 2SDK que permite el acceso a vir-tualmente cualquier BD desde el lenguaje de programacion Java. (java.sql)

ODBC (Open Database Conectivity) = Interfaz entre las BD y las aplicacio-nes que corren bajo Windows.

JDBC es una API en Java para ejecutar instrucciones SQL. Consta de unconjunto de clases e interfaces escritas en Java.

JDBC Es una API a nivel SQL, es decir permite usar proposiciones SQLcomo argumentos de los metodos.

La pareja Java-JDBC:

• Permite escribir una aplicacion que corra en cualquier plataforma.

• Facilita el mapeo de relacional a objeto.

• Independencia de la BD.

• Computo distribuido.

©c Amparo Lopez Gaona, 2004 Transparencia No. 1

Page 3: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Estructura de JDBC

JDBC tiene la siguiente arquitectura:

AplicacionB

AplicacionA

JDBC

SybaseOracle Postgres

©c Amparo Lopez Gaona, 2004 Transparencia No. 2

Page 4: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

¿Que hace JDBC?

De manera simplista JDBC permite hacer tres cosas:

Establecer conexion con una fuente de datos. (BD)

Connection con = DriveManager.getConnection("jdbc:miDriver:miBD"miUsuario", "miClave");

Enviar proposiciones de consulta y actualizacion a la fuente de datos. (SQL)

Statement stmt = con.createStatement();ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM tabla1");

Procesar resultados.

while (rs.next()) {int x = getInt("a");String s = getString("b");float f = getFloat("c");

}

©c Amparo Lopez Gaona, 2004 Transparencia No. 3

Page 5: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

1. Conexion con la BD

Controlador (driver) es el intermediario entre la BD y Java.

Cargar un controlador.

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");Class.forName("org.postgresql.Driver");

Establecer la conexion del controlador con el SABD.

String url = "jdbc:postgresql:cafes";String login = "alg";String password = "mi.psswrd";Connection con = DriverManager.getConnection (url, login, password);

La conexion devuelta puede usarse para crear las proposiciones JDBC quereciben instrucciones SQL para el SABD.

Informacion de controladores en:

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

©c Amparo Lopez Gaona, 2004 Transparencia No. 4

Page 6: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Excepciones

JDBC permite ver las excepciones disparadas por el SABD y por Java. Estas son:

ClassNotFoundException disparada por el metodo Class.forName.

Connection refused. Check that the hostname a, and that the postmaster is running with the -i flag, which eorking.

SQLException por los metodos de JDBC.

Estas excepciones tienen tres partes: mensaje, estado, codigo de error.

©c Amparo Lopez Gaona, 2004 Transparencia No. 5

Page 7: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

try {//Codigo que puede generar una excepcion

} catch(SQLException ex) {System.err.println("-----------SQLException------------\n");

System.err.println("Mensaje: " + ex.getMessage());System.err.println("Estado SQL: " + ex.getSQLState());System.err.println("Codigo de Error: " + ex.getErrorCode());

}

Por ejemplo, al tratar de crear una tabla existente se obtiene un mensaje:

-----------SQLException----------

Mensaje: ERROR: Relation ’cafe’ already existsEstado SQL: nullCodigo de Error: 0

©c Amparo Lopez Gaona, 2004 Transparencia No. 6

Page 8: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Ejemplo de conexion

import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;/*** Este programa establece una conexion con la base de datos indicada.* Para ejecutarse debe darse java SoloConexion DRIVER URL UID PASSWORD*/public class SoloConexion {static public void main(String args[]) {Connection conexion = null;

if( args.length != 4 ) {System.out.println("Sintaxis: java SoloConexion DRIVER URL UID PASSWORD");return;

}try {

Class.forName(args[0]);}catch( Exception e ) {

©c Amparo Lopez Gaona, 2004 Transparencia No. 7

Page 9: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

e.printStackTrace();return;

}try {

conexion = DriverManager.getConnection(args[1], args[2], args[3]);System.out.println("Conexion exitosa :)");...// Aquı podrıa ir cualquier procesamiento adicional

}catch( SQLException e ) {

e.printStackTrace();}finally {

if( conexion != null ) {try { conexion.close(); }catch( SQLException e ) {

e.printStackTrace();}

}}

}}

©c Amparo Lopez Gaona, 2004 Transparencia No. 8

Page 10: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

2. Envıo de proposiciones SQL

El acceso basico a la BD:

• Actualizaciones (INSERT, UPDATE, CREATE, ...).

• Consultas (SELECT).

Existen tres clases para trabajar con las proposiciones SQL:

• Statement para trabajar con una proposicion SQL sin parametros.

• PreparedStatement para usar proposiciones SQL que se ejecutan con fre-cuencia, por tanto son pre-compiladas y pueden tomar parametros.

• CallableStatement para trabajar con procedimientos almacenados.

©c Amparo Lopez Gaona, 2004 Transparencia No. 9

Page 11: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

La clase Statement

Un objeto Statement es el que permite enviar instrucciones SQL a la base de datos.

Se crea un objeto Statement

Statement stm = con.createStatement();

Se proporciona el metodo apropiado para ejecutar con la proposicion SQLque se desea enviar.

• executeUpdate.

• executeQuery

• execute

Se procesan los resultados son:

• Modificaciones. Un entero indicando la cantidad de tuplas actualizadas.

• Consultas. Se obtiene un objeto de la clase ResultSet.

• En caso de usar execute devuelve true si la instruccion devuelve al menosuna tupla de la BD y false en otro caso.

©c Amparo Lopez Gaona, 2004 Transparencia No. 10

Page 12: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Creacion de tablas

Se tiene una BD con el siguiente esquema:

Cafe(nombre, id_proveedor, precio, ventas, total)------

Proveedor(id, nombre, calle, ciudad, estado, cp)--

stmt.executeUpdate("CREATE TABLE Cafe (nombre VARCHAR(32) PRIMARY KEY" +"id_proveedor INTEGER, precio FLOAT" +"ventas INTEGER, total INTEGER," +"FOREIGN KEY id_proveedor REFERENCES Proveedor(id))");

String creaTabla "CREATE TABLE Cafe (nombre VARCHAR(32) PRIMARY KEY" +"id_proveedor INTEGER, precio FLOAT" +"ventas INTEGER, total INTEGER," +"FOREIGN KEY id_proveedor REFERENCES Proveedor(id))";

stmt.executeUpdate(creaTabla);

©c Amparo Lopez Gaona, 2004 Transparencia No. 11

Page 13: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Llenado de la tabla

Statement stmt = con.createStatement();stmt.executeUpdate("INSERT INTO cafe " +

"VALUES (’Colombiano’, 101, 92.0, 0, 0)");stmt.executeUpdate("INSERT INTO cafe " +

"VALUES (’Chiapas_Organico’, 49, 28.00, 0, 0)");stmt.executeUpdate("INSERT INTO cafe " +

"VALUES (’Pluma Oaxaca’, 150, 30.00, 0, 0)");stmt.executeUpdate("INSERT INTO cafe " +

"VALUES (’Chiapas_Descafeinado’, 101, 33.00, 0, 0)");stmt.executeUpdate("INSERT INTO cafe " +

"VALUES (’Mezcla_Casa, 49, 27.00, 0, 0)");

©c Amparo Lopez Gaona, 2004 Transparencia No. 12

Page 14: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Programa para creacion y llenado

import java.sql.*; //Para usar el paquete que contiene la API JDBCpublic class CreaTCafes {public static void main(String args[]) {String url = "jdbc:postgresql:cafes";Connection con;String createString, crea2;createString = "create table cafe " +

"(nombre varchar(32) primary key, " +"id_proveedor int, " +"precio float, " +"ventas int, " + "total int)";

crea2 = "create table proveedor " + ...Statement stmt;try {

Class.forName("org.postgresql.Driver");} catch(java.lang.ClassNotFoundException e) {

System.err.print("ClassNotFoundException: ");System.err.println(e.getMessage());

}

©c Amparo Lopez Gaona, 2004 Transparencia No. 13

Page 15: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

try {con = DriverManager.getConnection(url, "amparo", "mi.psswrd");stmt = con.createcStatement();stmt.executeUpdate(createString);stmt.executeUpdate(crea2);stmt.executeUpdate("insert into CAFE " +

"VALUES (’Colombiano’, 101, 92.0, 0, 0)");stmt.executeUpdate("INSERT INTO cafe " +

"VALUES (’Chiapas_Organico’, 49, 28.00, 0, 0)");stmt.executeUpdate("INSERT INTO cafe " +

"VALUES (’Pluma Oaxaca’, 150, 30.00, 0, 0)");stmt.executeUpdate("INSERT INTO cafe " +

"VALUES (’Chiapas_Descafeinado’, 101, 33.00, 0, 0)");stmt.executeUpdate("INSERT INTO cafe " +

"VALUES (’Mezcla_Casa, 49, 27.00, 0, 0)");} catch(SQLException ex) {System.err.println("-----------SQLException------------\n");while (ex != null){ //Para atrapar todas las excepciones

System.err.println("Mensaje: " + ex.getMessage());...

} } }}

©c Amparo Lopez Gaona, 2004 Transparencia No. 14

Page 16: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Actualizacion

String actualizaDatos = "UPDATE Cafe " +"SET ventas = 75 " +"WHERE nombre LIKE ’Colombiano’";

stmt.executeUpdate(actualizaDatos);

stmt.executeUpdate("DELETE FROM Proveedor WHERE id = 109");

©c Amparo Lopez Gaona, 2004 Transparencia No. 15

Page 17: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Consulta

ResultSet rs = stmt.executeQuery("SELECT nombre, precio FROM Cafe");

El objeto rs contiene las tuplas resultado de la consulta. Para acceder a ellas setiene el metodo next() que devuelve true si hay datos y false en otro caso.

Para extraer cada atributo de la tupla actual (la recuperada con next) se debeusar un metodo getXXX de acuerdo al tipo del atributo.

String s = "";float n;

while (rs.next()) {s = rs.getString("nombre");n = rs.getFloat("precio");System.out.println(s + " " + n);

}

©c Amparo Lopez Gaona, 2004 Transparencia No. 16

Page 18: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

La salida serıa:

Colombiano 92.00Chiapas_Organico 28.00Pluma Oaxaca 30.00Chiapas_Descafeinado 33.00Mezcla_Casa 27.00

En lugar de recuperar los atributos por su nombre, tambien se puede hacer porsu posicion: 1, 2, etc...

while (rs.next()) {String s = rs.getString(1);float n = rs.getFloat(2);System.out.println(s + " " + n);

}

©c Amparo Lopez Gaona, 2004 Transparencia No. 17

Page 19: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Metodos getXXXX

Tipo SQL Tipo Java

BIT booleanTINYINT byte

SMALLINT shortINTEGER int

BIGINT longREAL float

FLOAT double

DOUBLE doubleDECIMAL java.math.BigDecimal

NUMERIC java.math.BigDecimalCHAR java.lang.String

VARCHAR java.lang.StringLONGVARCHAR java.lang.String

DATE java.sql.Date

TIME java.sql.TimeTIMESTAMP java.sql.Timestamp

BINARY byte[]VARBINARY byte[]

LONGVARBINARY byte[]

©c Amparo Lopez Gaona, 2004 Transparencia No. 18

Page 20: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Valores nulos

Si en la base de datos hay un valor null, el metodo getInt() devuelve uncero.

En Java se tiene un null pero es para referencias.

Despues de un getXXX se puede preguntar wasNull() para investigar si el valorrecuperado es el nulo de SQL.

©c Amparo Lopez Gaona, 2004 Transparencia No. 19

Page 21: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Proposiciones Pre-compiladas

Si se desea realizar varias veces la misma instruccion con diferentes valoreses conveniente usar una proposicion preparada.

Un objeto PreparedStatement debe tener una proposicion SQL en su creacion.Esta se envıa al SABD inmediatamente y se compila.

PreparedStatement ventasReales = con.PrepareStatement("UPDATE cafe SET ventas = ? WHERE nombre LIKE ?");

Existen metodos setXXX de la clase PreparedStatement para asignar valor a losparametros.

Para que se ejecute la instruccion se debe llamar al metodo executeUpdate().

ventasReales.setInt(1, 75);ventasReales.setString(2, "Colombiano");ventasReales.executeUpdate();

ventasReales.setString(2, "Oaxaca");ventasReales.executeUpdate();

©c Amparo Lopez Gaona, 2004 Transparencia No. 20

Page 22: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Para limpiar los datos de un parametro hay dos opciones:

Asignar un nuevo valor.

Usar clearParameters.

Otro ejemplo:

PreparedStatement ventasReales = con.PrepareStatement("UPDATE cafe SET ventas = ? WHERE nombre LIKE ?");

int [] ventasSemanales = {175, 150, 60, 155, 90};String [] tipoCafe = {"Colombiano", "Oaxaca", "Chiapas_Descafeinado",

"Chiapas_Organico", "Mezcla_Casa"};int cuantos = tipoCafe.length;

for (int i = 0; i < cuantos; i++) {ventasReales.setInt(1,ventasSemanales[i]);ventasReales.setString(2,tipoCafe[i]);ventasReales.executeUpdate();

}

©c Amparo Lopez Gaona, 2004 Transparencia No. 21

Page 23: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Transacciones y JDBC

Una transaccion es una unidad logica de trabajo.

Al crear una conexion se esta en modo auto-commit que significa que cada ins-truccion SQL se trata como una transaccion.

Para permitir agrupar instrucciones en una transaccion se debe desactivar el modode auto-commit vıa la instruccion:

con.setAutoCommit(false);

La transaccion termina al llamar al metodo commit o rollback.

Para que se graben los cambios efectuados por la transaccion se debe llamarexplıcitamente al metodo commit.

©c Amparo Lopez Gaona, 2004 Transparencia No. 22

Page 24: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Ejemplo de transacciones

import java.sql.*;public class Transaccion {

public static void main(String args[]) {String url = "jdbc:postgresql:cafes";Connection con = null;Statement stmt;PreparedStatement actualizaVentas;PreparedStatement actualizaTotal;String nuevaVenta = "update cafe " +

"set ventas = ? where nombre like ?";String nuevoTotal = "update cafe " +

"set total = total + ? where nombre like ?";String consulta = "select nombre, ventas, total from cafe";try {

Class.forName("org.postgresql.Driver");} catch(java.lang.ClassNotFoundException e) {

System.out.print("ClassNotFoundException: ");System.out.println(e.getMessage());

}

©c Amparo Lopez Gaona, 2004 Transparencia No. 23

Page 25: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

try {con = DriverManager.getConnection(url, "amparo", "mi.psswrd");actualizaVentas = con.prepareStatement(nuevaVenta);actualizaTotal = con.prepareStatement(nuevoTotal);int [] ventasSemanales = {175, 150, 60, 155, 90};String [] cafes = {"Colombiano", "Chiapas Organico",

"Pluma Oaxaca", "Chiapas Descafeinado", "Mezcla Casa"};int len = cafes.length;con.setAutoCommit(false);for (int i = 0; i < len; i++) {

actualizaVentas.setInt(1, ventasSemanales[i]);actualizaVentas.setString(2, cafes[i]);actualizaVentas.executeUpdate();

actualizaTotal.setInt(1, ventasSemanales[i]);actualizaTotal.setString(2, cafes[i]);actualizaTotal.executeUpdate();con.commit();

}con.setAutoCommit(true);actualizaVentas.close();actualizaTotal.close();

©c Amparo Lopez Gaona, 2004 Transparencia No. 24

Page 26: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

} catch(SQLException ex) {System.out.println("SQLException: " + ex.getMessage());if (con != null)

try {System.out.println("La transaccion ha sido abortada ");con.rollback();

} catch(SQLException e) {System.out.print("SQLException: ");System.out.println(e.getMessage());

}} finally {

if (con != null)try {con.close();}catch(SQLException e) { e.printStackTrace();}

}}

}

©c Amparo Lopez Gaona, 2004 Transparencia No. 25

Page 27: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Procedimientos Almacenados

Un procedimiento almacenado (store procedure) es un grupo de instruccionesSQL que forman una unidad logica y realizan un tarea particular.

Pueden ser compilados y ejecutados con diferentes parametros y resultados.

Ventajas:

Debido a que son precompilados se ejecutan mucho mas rapido que cadainstruccion por separado.

Los errores de sintaxis pueden corregirse al momento de compilacion no deejecucion.

Los programadores Java solo requieren el nombre del procedimiento, susentradas y salidas.

©c Amparo Lopez Gaona, 2004 Transparencia No. 26

Page 28: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Ejemplo

Creacion:

String creaProcedure = "CREATE PROCEDURE lista_proveedores " +"AS " +"SELECT proveedor.nombre, cafe.nombre " +"FROM proveedor, cafe " +"WHERE proveedor.id = cafe.id_proveedor " +"ORDER BY proveedor.nombre";

Statement stmt = con.createStatement();stmt.executeUpdate(creaProcedure);

Uso: Para llamar al procedimiento se debe crear un objeto de la clase CallableStatementel cual contiene una llamada a un procedimiento almacenado no contiene elprocedimiento.

CallableStatement cs = con.prepareCall("{call lista_proveedores}");ResultSet rs = cs.executeQuery();

©c Amparo Lopez Gaona, 2004 Transparencia No. 27

Page 29: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Ejemplo de un procedimiento con parametros

CREATE PROCEDURE calcula_interes (id IN INTEGER, bal OUT FLOAT) ISBEGINselect balance into balfrom cuentawhere cuenta_id = id;

bal := bal + bal * 0.03;

update cuentaset balance = balwhere cuenta_id = id;

END;

©c Amparo Lopez Gaona, 2004 Transparencia No. 28

Page 30: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

try {CallableStatement cs = con.prepareCall("{call calcula_interes(?,?)}");

cs.registerOutParameter(2, java.sql.Types.FLOAT);for(int i=1; i < cuentas.length; i++) {cs.setInt(1, cuentas[i].getId());cs.execute();System.out.println("Nuevo balance: "+ cs.getFloat(2));

}con.commit();stm.close();con.close();

}

Si fuera una funcion la sintaxis serıa {? = call nombre(?,?)}

©c Amparo Lopez Gaona, 2004 Transparencia No. 29

Page 31: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

JDBC 2.0

Con JDBC 2.0 es posible hacer lo siguiente:

Moverse en cualquier direccion en el resultado de la consulta.

Actualizar las tablas de la BD sin utilizar SQL.

Enviar, en lote, un conjunto de instrucciones SQL a la BD.

Usar los tipos de datos de SQL3.

©c Amparo Lopez Gaona, 2004 Transparencia No. 30

Page 32: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Movimiento en el resultado

El metodo createStatement puede tener dos parametros:

El primero puede ser:

• TYPE FORWARD ONLY. *

• TYPE SCROLL INSENSITIVE.

• TYPE SCROLL SENSITIVE.

El segundo parametro:

• CONCUR READ ONLY. *

• CONCUR UPDATABLE.

Es importante el orden de estos parametros.

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);

ResultSet srs = stmt.executeQuery("SELECT nombre, precio FROM cafe");

©c Amparo Lopez Gaona, 2004 Transparencia No. 31

Page 33: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Metodos para moverse en el ResultSet

next. Se mueve hacia adelante.

previous. Se mueve hacia atras.

afterLast,beforeFirst, first, last. Se mueve a la posicion indicada.

absolute(int). Se mueve a la tupla especificada en el parametro. Si este esnegativo empieza a contar del final hacia arriba.

relative (int). A partir de la posicion actual, se mueve tantos lugares comose indique en su parametro.

getRow. Devuelve el numero de tupla en que se esta posicionado.

isFirst, isLast, isBeforeFirst, isAfterLast. Devuelven un valor Booleano.

moveToInsertRow y moveToCurrentRow.

¿Cuantos renglones hay en el resultado?

¿Como listar al reves?

©c Amparo Lopez Gaona, 2004 Transparencia No. 32

Page 34: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Actualizaciones en lote

Con JDBC 2.0 los objetos de Statement, PreparedStatement y CallableStatementtienen la capacidad de mantener una lista de comandos que pueden ser transmitoscomo un lote.

Instrucciones:

clearBatch. Borra todo lo que haya en la lista. Al crearla esta limpia.

addBatch. Agrega instrucciones a la lista.

executeBatch. Envia la lista de instrucciones a la BD.

©c Amparo Lopez Gaona, 2004 Transparencia No. 33

Page 35: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Mini ejemplo: El dueno del cafe ha decidido incluir cuatro nuevos tipos de cafesa la tabla Cafe.

con.setAutoCommit(false);Statement stmt = con.createStatement();stmt.addBatch("INSERT INTO cafe " + "VALUES(’Amareto’, 49, 29, 0, 0)");stmt.addBatch("INSERT INTO cafe " + "VALUES(’Kenya’, 49, 110, 0, 0)");stmt.addBatch("INSERT INTO cafe " + "VALUES(’Coatepec, 49, 30, 0, 0)");stmt.addBatch("INSERT INTO cafe " + "VALUES(’Coatepec D’, 49, 35, 0, 0)");

int [] updateCounts = stmt.executeBatch();con.commit();con.setAutoCommit(true);

Solo se pueden enviar en un lote instrucciones que regresan valor numerico. Encaso contrario se disparan las siguientes excepciones:

SQLException.

BatchUpdateException.

©c Amparo Lopez Gaona, 2004 Transparencia No. 34

Page 36: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Al igual que en el procesamiento en lınea, el ejemplo es ineficiente debido al usode Statement.

con.setAutoCommit(false);PreparedStatement stmt = con.prepareStatement(

"INSERT INTO cafe VALUES(?, ?, ?, ?, ?)");stmt.setString(1,"Coatepec");stmt.setInt(2,49);stmt.setInt(3,30);stmt.setInt(4,0);stmt.setInt(5,0);stmt.addBatch();stmt.setInt((1,"Coatepec Descafeinado");stmt.setInt(2,49);stmt.setInt(3,35);stmt.setInt(4,0);stmt.setInt(5,0);stmt.addBatch();

// Etc...

int [] updateCounts = stmt.executeBatch();con.commit();con.setAutoCommit(true);

©c Amparo Lopez Gaona, 2004 Transparencia No. 35

Page 37: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Actualizaciones a la BD

Dos posibilidades:

La tradicional, usando SQL:

stmt.executeUpdate("UPDATE cafe SET precio = 35.50" +"WHERE nombre = Descafeinado");

La nueva, modificando al ResultSet.

1. El ResultSet debe ser actualizable:

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

Para verificar que el conjunto de resultados es actualizable existe el meto-do getConcurrency() que devuelve:

• 1007 para indicar que es solo de lectura.

• 1008 para indicar que es actualizable.

©c Amparo Lopez Gaona, 2004 Transparencia No. 36

Page 38: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

2. Luego modificar el ResultSet vıa updateXXX.

ResultSet nuevoRS = stmt.executeQuery("SELECT nombre, precio FROM cafe");nuevoRS.last();nuevoRS.updateFloat("precio", 35.50);nuevoRS.updateRow();

Las instrucciones updateXXX actualizan el valor de la columna indicada, dela tupla en donde se encuentra el cursor.

Recordar que la posicion de la tupla es en el ResultSet no la en la BD.

3. Actualizar la base de datos con updateRow.

Si se desea restaurar el valor anterior a la actualizacion (en el conjunto deresultados) se debe usar el metodo cancelRowUpdates pero antes de llamar aupdateRow.

nuevoRS.last();nuevoRS.updateFloat("precio", 35.50);...nuevoRS.cancelRowUpdates();

El precio se mantiene tanto en el resultset como en la BD debido a que nose llamo a updateRow.

©c Amparo Lopez Gaona, 2004 Transparencia No. 37

Page 39: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Supresiones del conjunto de resultados

Para eliminar tuplas sin usar SQL:

1. Estar en la posicion correcta.

2. Borrarlo con la instruccion deleteRow

Ejemplo: Eliminar el cuarto renglon.

nuevoRS.absolute(4);nuevoRS.deleteRow();

Lo que sucede en el ResultSet depende de la implementacion. Puede ser queelimine el renglon, lo marque como borrado o lo deje en blanco.

©c Amparo Lopez Gaona, 2004 Transparencia No. 38

Page 40: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Inserciones a la BD

Para insertar una nueva tupla modificando al ResultSet se debe:

1. Mover el cursor vıa el metodo moveToInsertRow.

2. Asignar valor a cada columna con el metodo updateXXX apropiado.

3. Llamar al metodo insertRow para insertar esta nueva tupla en el conjunto deresultados y en la base de datos simultaneamente.

©c Amparo Lopez Gaona, 2004 Transparencia No. 39

Page 41: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Ejemplo

Connection con = DriverManager.getConnection("jdbc:mySubprotocol:mySubName");Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,

ResultSet.CONCUR_UPDATABLE);ResultSet nuevoRS = stmt.executeQuery("SELECT * FROM cafe");

nuevoRS.moveToInsertRow();nuevoRS.updateString("nombre", "Java"); % nuevoRS.updateString(1, "Java");nuevoRS.updateInt("id_proveedor", 150); % nuevoRS.updateInt(2, 150);nuevoRS.updateFloat("precio", 35.50); % nuevoRS.updateFloat(3, 35.50);nuevoRS.updateInt("ventas", 0); % nuevoRS.updateInt(4, 0);nuevoRS.updateInt("total", 0); % nuevoRS.updateInt(5, 0);nuevoRS.insertRow();

Si se omite algun valor, pone el definido por omision, o nulo, o si no esta enninguno de los casos anterior dispara una excepcion del tipo SQLException.

©c Amparo Lopez Gaona, 2004 Transparencia No. 40

Page 42: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Uso de datos de SQL3

Los tipos de datos incorporados a SQL3 y denominados tipos de datos SQL3 son:

BLOB (Binary Large Object) para almacenar grandes cantidas de datos comobytes. Este tipo es mapeado a Blob.

CLOB (Character Large Object), para almacenar grandes cantidades de datoscomo caracters. Clob.

ARRAY permite usar un arreglo como valor de una columna. Array.

Tipos estructurados mapeados a Struct.

Referencia (REF) mapeada a Ref.

Tipo SQL3 Metodo getXXX Metodo setXXX Metodo updateXXX

BLOB getBlob setBlob updateBlob *CLOB getClob setClob updateClob *ARRAY getArray setArray updateArray *Tipo estructurado getObject setObject updateObjectREF (tipo estructurado) getRef setRef updateRef *

©c Amparo Lopez Gaona, 2004 Transparencia No. 41

Page 43: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Metadatos

Su objetivo es proporcionar las herramientas para evitar que el programador tengaque conocer a fondo la organizacion de la BD.

Informacion acerca de los datos que no son de interes para el usuario final peroque si requiere el programador para manejar los datos.

Existen dos interfaces en java.sql para los metadatos:

ResultSetMetaData. Proporciona informacion acerca del tipo y propiedades decada columna de un objeto ResultSet.

DatabaseMetaData. Proporciona informacion acerca de una base de datos o unSABD particular.

©c Amparo Lopez Gaona, 2004 Transparencia No. 42

Page 44: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

ResultSetMetaData

Como su nombre indica proporciona informacion acerca de los tipos y propiedadesde las columnas en un objeto ResultSet regresado por una consulta a la BD.

Un ejemplar de ResultSetMetaData contiene la informacion y sus metodos propor-cionan el acceso a ella.

Creacion.

Statment stmt = con.createStament();ResultSet rs = stmt.executeQuery("select * from Cafe");ResultSetMetaData rsmd = rs.getMetaData();

Uso.

int nColumnas = rsmd.getColumnCount();while (rs.next())for (int i = 1; i < nColumnas; i++) {

String s = rs.getString(i);System.out.print(s);

}System.out.println("");

©c Amparo Lopez Gaona, 2004 Transparencia No. 43

Page 45: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Todos los metodos de esta clase devuelven informacion acerca de una columnaparticular en rs, excepto el metodo getColumnCount que devuelve la cantidad totalde columnas en el resultado.

Para obtener el nombre de las columnas se usa el metodo getColumnLabel:

int nColumnas = rsmd.getColumnCount();for(int i = 1; i < nColumnas; i++) {

if (i > 1) System.out.println(",");String nombre = rsmd.getColumnLabel(i);System.out.print(nombre);

}System.out.println("");

©c Amparo Lopez Gaona, 2004 Transparencia No. 44

Page 46: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

La interfaz completa es:

int getColumnCount()int getColumnType(int) boolean isWritable (int)int getColumnDisplaySize(int) boolean isReadOnly(int)int getPrecision(int) boolean isSigned (int)int getScale(int) boolean isCaseSensitive (int)int isNullable (int)String getColumnTypeName(int) String getTableName(int)String getColumnName(int) String getSchemaName(int)String getColumnLabel(int) String getCatalogName(int)

©c Amparo Lopez Gaona, 2004 Transparencia No. 45

Page 47: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Imprime Tipo de columnas

import java.sql.*;class ImprimeCols {

public static void imprimeTipo(ResultSetMetaData rsmd) throws SQLException {int cols = rsmd.getColumnCount();int tipo;String nombre;for (int i = 1; i <= cols; i++) {

tipo = rsmd.getColumnType(i);nombre = rsmd.getColumnTypeName(i);System.out.print("Columna " + i + " es del tipo JDBC " + tipo);System.out.println(" y corresponde a " + nombre + " en la BD.");

}}public static void main(String args[]) {

String url = "jdbc:postgresql:cafes", login = "amparo", pss = "mi.psswrd";Connection con;String consulta = "select * from cafe";Statement stmt;

©c Amparo Lopez Gaona, 2004 Transparencia No. 46

Page 48: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

try {Class.forName("org.postgresql.Driver");

} catch(java.lang.ClassNotFoundException e) {System.err.print("ClassNotFoundException: ");System.err.println(e.getMessage());

}try {

con = DriverManager.getConnection(url, login, pss);stmt = con.createStatement();

ResultSet rs = stmt.executeQuery(consulta);ResultSetMetaData rsmd = rs.getMetaData();

imprimeTipo(rsmd);System.out.println("");stmt.close();con.close();

} catch(SQLException ex) {System.err.print("SQLException: ");System.err.println(ex.getMessage());

}} }

©c Amparo Lopez Gaona, 2004 Transparencia No. 47

Page 49: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

La salida de este programa es:

Columna 1 es del tipo JDBC 12 y corresponde a varchar en la BD.Columna 2 es del tipo JDBC 4 y corresponde a int4 en la BD.Columna 3 es del tipo JDBC 8 y corresponde a float8 en la BD.Columna 4 es del tipo JDBC 4 y corresponde a int4 en la BD.Columna 5 es del tipo JDBC 4 y corresponde a int4 en la BD.

©c Amparo Lopez Gaona, 2004 Transparencia No. 48

Page 50: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

DatabaseMetaData

Proporciona informacion acerca de la BD para un objeto Connection.

Usos principales:

Conocer informacion acerca de la BD que se esta usando.

Permitir crear aplicaciones independientes de la BD.

Creacion: DatabaseMetaData dbmd = con.getMetaData();

Uso: int n = dbmd.getMaxTableNameLength();

©c Amparo Lopez Gaona, 2004 Transparencia No. 49

Page 51: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Existen mas de 150 metodos en esta interfaz, estos se clasifican de acuerdo alvalor que devuelven:

Metodos que devuelven cadenas. Tales como el URL, nombre del usuario,del producto, version, nombre del controlador. Las palabras reservadas delSABD, funciones numericas, de cadenas, del sistema, fecha/hora.

Metodos que devuelven enteros. Generalmente tienen la forma getMaxXXX.

Maximo numero de caracteres permitidos en una instruccion, para un identi-ficador.

Metodos que devuelven Booleanos. Generalmente tienen la forma supportsXXX,donde XXX es la capacidad que soportan. De estos hay mas de 70.

Metodos que devuelven listas de informacion en objetos ResultSet, en estecaso se usan de manera normal, con getXXX.

ResultSet rs = dbmd.getSchemas();while (rs.next()){String s = rs.getString(1);System.out.println("NOmbre d esquema = " + s);

}

©c Amparo Lopez Gaona, 2004 Transparencia No. 50

Page 52: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Ejemplo

import java.sql.*;public class TypeInfo {

public static void main(String args[]) {String url = "jdbc:postgresql:cafes";Connection con;DatabaseMetaData dbmd;try {

Class.forName("org.postgresql.Driver");} catch(java.lang.ClassNotFoundException e) {

System.err.print("ClassNotFoundException: ");System.err.println(e.getMessage());

}try {

con = DriverManager.getConnection(url, "amparo", "myPassword");dbmd = con.getMetaData();ResultSet rs = dbmd.getTypeInfo();while (rs.next()) {

String typeName = rs.getString("TYPE_NAME");short dataType = rs.getShort("DATA_TYPE");

©c Amparo Lopez Gaona, 2004 Transparencia No. 51

Page 53: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

String createParams = rs.getString("CREATE_PARAMS");int nullable = rs.getInt("NULLABLE");boolean caseSensitive = rs.getBoolean("CASE_SENSITIVE");System.out.println("DBMS type " + typeName + ":");System.out.println(" java.sql.Types: " + dataType);System.out.print(" parameters used to create: ");System.out.println(createParams);System.out.println(" nullable?: " + nullable);System.out.print(" case sensitive?: ");System.out.println(caseSensitive);System.out.println("");

}con.close();

} catch(SQLException ex) {System.err.println("SQLException: " + ex.getMessage());

}}

}

©c Amparo Lopez Gaona, 2004 Transparencia No. 52

Page 54: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Parte de la salida de este ejemplo:

DBMS type varchar:java.sql.Types: 12parameters used to create: nullnullable?: 0case sensitive?: false

DBMS type date:java.sql.Types: 91parameters used to create: nullnullable?: 0case sensitive?: false

DBMS type time:java.sql.Types: 92parameters used to create: nullnullable?: 0case sensitive?: false

informacion necesaria para conectarse a la BD.

©c Amparo Lopez Gaona, 2004 Transparencia No. 53

Page 55: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

Monitor de terminal generico

Esta aplicacion permite introducir proposiciones SQL en la lınea de comandos yver el resultado formateado.

Las instrucciones permitidas son:

commit. Envıa un commit a la BD.

go. Envıa la instruccion que tenga el buffer para que sea procesada comoinstruccion SQL. vıa el metodo executeStatement()

quit. Cierra la BD y termina la aplicacion.

reset. Limpia el buffer sin enviar su informacion a la BD.

rollback. Aborta cualquier transaccion inconclusa.

show version. Despliega informacion acerca de este programa.

©c Amparo Lopez Gaona, 2004 Transparencia No. 54

Page 56: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

EL metodo main

static public void main(String args[]) {DriverPropertyInfo[] required;StringBuffer buffer = new StringBuffer();Properties props = new Properties();boolean connected = false;Driver driver;String url;int line = 1; // Mark current input line

if( args.length < 1 ) {System.out.println("Syntax: <java -Djdbc.drivers=DRIVER_NAME " +

"TerminalMonitor JDBC_URL>");return;

}url = args[0];try {

driver = DriverManager.getDriver(url);}catch( SQLException e ) {

©c Amparo Lopez Gaona, 2004 Transparencia No. 55

Page 57: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

e.printStackTrace();System.err.println("Unable to find a driver for the specified " + "URL.");return;

}try {

required = driver.getPropertyInfo(url, props);}catch( SQLException e ) {

e.printStackTrace();System.err.println("Unable to get driver property information.");return;

}input = new BufferedReader(new InputStreamReader(System.in));try {

if( required.length < 1 ) {props.put("user", prompt("user: "));props.put("password", prompt("password: "));

} else {for(int i=0; i<required.length; i++) {if( !required[i].required )

continue;props.put(required[i].name,

©c Amparo Lopez Gaona, 2004 Transparencia No. 56

Page 58: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

prompt(required[i].name + ": "));}

}}catch( IOException e ) {

e.printStackTrace();System.err.println("Unable to read property info.");return;

}try {

connection = DriverManager.getConnection(url, props);}catch( SQLException e ) {

e.printStackTrace();System.err.println("Unable to connect to the database.");

}connected = true;System.out.println("Connected to " + url);while( connected ) {

String tmp, cmd;if( line == 1 )System.out.print("TM > ");

©c Amparo Lopez Gaona, 2004 Transparencia No. 57

Page 59: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

elseSystem.out.print(line + " -> ");

System.out.flush();try {tmp = input.readLine();

} catch( java.io.IOException e ) {e.printStackTrace();return;

}cmd = tmp.trim();if( cmd.equals("commit") ) {try {connection.commit();System.out.println("Commit successful.");

}catch( SQLException e ) {System.out.println("Error in commit: " + e.getMessage());}buffer = new StringBuffer();line = 1;

} else if( cmd.equals("go") ) {if( !buffer.equals("") ) {

©c Amparo Lopez Gaona, 2004 Transparencia No. 58

Page 60: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

try {executeStatement(buffer);

}catch( SQLException e ) {

System.out.println(e.getMessage());}

}buffer = new StringBuffer();line = 1;continue;

}else if( cmd.equals("quit") ) {connected = false;continue;}else if( cmd.equals("reset") ) {buffer = new StringBuffer();line = 1;continue;

}else if( cmd.equals("rollback") ) {

try {

©c Amparo Lopez Gaona, 2004 Transparencia No. 59

Page 61: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

connection.rollback();System.out.println("Rollback successful.");

}catch( SQLException e ) {System.out.println("An error occurred during rollback: " + e.getMessage());

}buffer = new StringBuffer();line = 1;

}else if( cmd.startsWith("show") ) {

DatabaseMetaData meta;try {meta = connection.getMetaData();cmd = cmd.substring(5, cmd.length()).trim();if( cmd.equals("version") )

showVersion(meta);elseSystem.out.println("show version");

}catch( SQLException e ) {System.out.println("Failed to load meta data: " + e.getMessage());

}

©c Amparo Lopez Gaona, 2004 Transparencia No. 60

Page 62: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

buffer = new StringBuffer();line = 1;

}else {

buffer.append(" " + tmp);line++;continue;

}}try {connection.close();}catch( SQLException e ) {System.out.println("Error closing connection: " + e.getMessage());}System.out.println("Connection closed.");

}

©c Amparo Lopez Gaona, 2004 Transparencia No. 61

Page 63: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

EL metodo executeStatement

static public void executeStatement(StringBuffer buff) throws SQLException {String sql = buff.toString();Statement statement = null;

try {statement = connection.createStatement();if( statement.execute(sql) ) // true means the SQL was a SELECT

processResults(statement.getResultSet());else { // no result sets, see how many rows were affected

int num;switch(num = statement.getUpdateCount()) {case 0:

System.out.println("No rows affected.");break;

case 1:System.out.println(num + " row affected.");break;

default:System.out.println(num + " rows affected.");

©c Amparo Lopez Gaona, 2004 Transparencia No. 62

Page 64: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

}}

}catch( SQLException e ) {throw e;

}finally { // close out the statementif( statement != null ) {try { statement.close(); }catch( SQLException e ) { }

}}

}

©c Amparo Lopez Gaona, 2004 Transparencia No. 63

Page 65: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

EL metodo processResults

static public void processResults(ResultSet results) throws SQLException {try {

ResultSetMetaData meta = results.getMetaData();StringBuffer bar = new StringBuffer();StringBuffer buffer = new StringBuffer();int cols = meta.getColumnCount();int row_count = 0;int i, width = 0;

// Prepare headers for each of the columns// The display should look like:// --------------------------------------// | Column One | Column Two |// --------------------------------------// | Row 1 Value | Row 1 Value |// --------------------------------------

for(i=1; i<=cols; i++)width += meta.getColumnDisplaySize(i);

©c Amparo Lopez Gaona, 2004 Transparencia No. 64

Page 66: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

width += 1 + cols;for(i=0; i<width; i++)

bar.append(’-’);bar.append(’\n’);buffer.append(bar.toString() + "|");

for(i=1; i<=cols; i++) {StringBuffer filler = new StringBuffer();String label = meta.getColumnLabel(i);int size = meta.getColumnDisplaySize(i);int x;

if( label.length() > size )label = label.substring(0, size);

if( label.length() < size ) {int j;x = (size-label.length())/2;for(j=0; j<x; j++)filler.append(’ ’);

label = filler + label + filler;if( label.length() > size )

©c Amparo Lopez Gaona, 2004 Transparencia No. 65

Page 67: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

label = label.substring(0, size);elsewhile( label.length() < size )

label += " ";}buffer.append(label + "|");

}buffer.append("\n" + bar.toString());while( results.next() ) {

row_count++;buffer.append(’|’);for(i=1; i<=cols; i++) {StringBuffer filler = new StringBuffer();Object value = results.getObject(i);int size = meta.getColumnDisplaySize(i);String str;

if( results.wasNull() )str = "NULL";

elsestr = value.toString();

©c Amparo Lopez Gaona, 2004 Transparencia No. 66

Page 68: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

if( str.length() > size )str = str.substring(0, size);

if( str.length() < size ) {int j, x;

x = (size-str.length())/2;for(j=0; j<x; j++)

filler.append(’ ’);str = filler + str + filler;if( str.length() > size )

str = str.substring(0, size);else

while( str.length() < size )str += " ";

}buffer.append(str + "|");

}buffer.append("\n");

}if( row_count == 0 )

buffer = new StringBuffer("No rows selected.\n");else if( row_count == 1 )

©c Amparo Lopez Gaona, 2004 Transparencia No. 67

Page 69: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

buffer = new StringBuffer("1 row selected.\n" +buffer.toString() + bar.toString());

elsebuffer = new StringBuffer(row_count + " rows selected.\n" +

buffer.toString() + bar.toString());System.out.print(buffer.toString());System.out.flush();

}catch( SQLException e ) {throw e;

}finally {try { results.close(); }catch( SQLException e ) { }

}}

©c Amparo Lopez Gaona, 2004 Transparencia No. 68

Page 70: JDBC B asico - UNAM

Introduccion a XML JDBC Basico

EL metodo showVersion

static public void showVersion(DatabaseMetaData meta) {try {

System.out.println("TerminalMonitor v2.0");System.out.println("DBMS: " + meta.getDatabaseProductName() +

" " + meta.getDatabaseProductVersion());System.out.println("JDBC Driver: " + meta.getDriverName() +

" " + meta.getDriverVersion());}catch( SQLException e ) {

System.out.println("Failed to get version info: " + e.getMessage());}

}}

©c Amparo Lopez Gaona, 2004 Transparencia No. 69