JDBC Básico

Anuncio
Introducción a XML
JDBC Básico
Amparo López Gaona
México, D.F.
Octubre del 2004
Introducción a XML
JDBC Básico
Introducción
JDBCT M es una API contenida en Java 2SDK que permite el acceso a virtualmente cualquier BD desde el lenguaje de programación Java. (java.sql)
ODBC (Open Database Conectivity) = Interfaz entre las BD y las aplicaciones que corren bajo Windows.
JDBC es una API en Java para ejecutar instrucciones SQL. Consta de un
conjunto de clases e interfaces escritas en Java.
JDBC Es una API a nivel SQL, es decir permite usar proposiciones SQL
como argumentos de los métodos.
La pareja Java-JDBC:
• Permite escribir una aplicación que corra en cualquier plataforma.
• Facilita el mapeo de relacional a objeto.
• Independencia de la BD.
• Cómputo distribuido.
c Amparo López Gaona, 2004
Transparencia No. 1
Introducción a XML
JDBC Básico
Estructura de JDBC
JDBC tiene la siguiente arquitectura:
Aplicacion
A
Aplicacion
B
JDBC
Oracle
c Amparo López Gaona, 2004
Sybase
Postgres
Transparencia No. 2
Introducción a XML
JDBC Básico
¿Qué hace JDBC?
De manera simplista JDBC permite hacer tres cosas:
Establecer conexión con una fuente de datos. (BD)
Connection con = DriveManager.getConnection("jdbc:miDriver:miBD
"miUsuario", "miClave");
Enviar proposiciones de consulta y actualización 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 López Gaona, 2004
Transparencia No. 3
Introducción a XML
JDBC Básico
1. Conexión 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 conexión 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 conexión devuelta puede usarse para crear las proposiciones JDBC que
reciben instrucciones SQL para el SABD.
Información de controladores en:
http://servlet.java.sun.com/products/jdbc/drivers
c Amparo López Gaona, 2004
Transparencia No. 4
Introducción a XML
JDBC Básico
Excepciones
JDBC permite ver las excepciones disparadas por el SABD y por Java. Éstas son:
ClassNotFoundException disparada por el método Class.forName.
Connection refused. Check that the hostname a
, and that the postmaster is running with the -i flag, which e
orking.
SQLException por los métodos de JDBC.
Estas excepciones tienen tres partes: mensaje, estado, código de error.
c Amparo López Gaona, 2004
Transparencia No. 5
Introducción a XML
JDBC Básico
try {
//Código que puede generar una excepción
} catch(SQLException ex) {
System.err.println("-----------SQLException------------\n");
System.err.println("Mensaje:
" + ex.getMessage());
System.err.println("Estado SQL:
" + ex.getSQLState());
System.err.println("Código de Error: " + ex.getErrorCode());
}
Por ejemplo, al tratar de crear una tabla existente se obtiene un mensaje:
-----------SQLException---------Mensaje:
ERROR: Relation ’cafe’ already exists
Estado SQL:
null
Código de Error: 0
c Amparo López Gaona, 2004
Transparencia No. 6
Introducción a XML
JDBC Básico
Ejemplo de conexión
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* Este programa establece una conexión 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 López Gaona, 2004
Transparencia No. 7
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 8
Introducción a XML
JDBC Básico
2. Envı́o de proposiciones SQL
El acceso básico a la BD:
• Actualizaciones (INSERT, UPDATE, CREATE, ...).
• Consultas (SELECT).
Existen tres clases para trabajar con las proposiciones SQL:
• Statement para trabajar con una proposición SQL sin parámetros.
• PreparedStatement para usar proposiciones SQL que se ejecutan con frecuencia, por tanto son pre-compiladas y pueden tomar parámetros.
• CallableStatement para trabajar con procedimientos almacenados.
c Amparo López Gaona, 2004
Transparencia No. 9
Introducción a XML
JDBC Básico
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 método apropiado para ejecutar con la proposición SQL
que 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 instrucción devuelve al menos
una tupla de la BD y false en otro caso.
c Amparo López Gaona, 2004
Transparencia No. 10
Introducción a XML
JDBC Básico
Creación de tablas
Se tiene una BD con el siguiente esquema:
Café(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 López Gaona, 2004
Transparencia No. 11
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 12
Introducción a XML
JDBC Básico
Programa para creación y llenado
import java.sql.*; //Para usar el paquete que contiene la API JDBC
public 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 López Gaona, 2004
Transparencia No. 13
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 14
Introducción a XML
JDBC Básico
Actualización
String actualizaDatos = "UPDATE Cafe " +
"SET ventas = 75 " +
"WHERE nombre LIKE ’Colombiano’";
stmt.executeUpdate(actualizaDatos);
stmt.executeUpdate("DELETE FROM Proveedor WHERE id = 109");
c Amparo López Gaona, 2004
Transparencia No. 15
Introducción a XML
JDBC Básico
Consulta
ResultSet rs = stmt.executeQuery("SELECT nombre, precio FROM Cafe");
El objeto rs contiene las tuplas resultado de la consulta. Para acceder a ellas se
tiene el método 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 debe
usar un método 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 López Gaona, 2004
Transparencia No. 16
Introducción a XML
JDBC Básico
La salida serı́a:
Colombiano
92.00
Chiapas_Organico
28.00
Pluma Oaxaca
30.00
Chiapas_Descafeinado
33.00
Mezcla_Casa
27.00
En lugar de recuperar los atributos por su nombre, también se puede hacer por
su posición: 1, 2, etc...
while (rs.next()) {
String s = rs.getString(1);
float n = rs.getFloat(2);
System.out.println(s + "
" + n);
}
c Amparo López Gaona, 2004
Transparencia No. 17
Introducción a XML
JDBC Básico
Métodos getXXXX
Tipo SQL
BIT
TINYINT
SMALLINT
INTEGER
BIGINT
REAL
FLOAT
DOUBLE
DECIMAL
NUMERIC
CHAR
VARCHAR
LONGVARCHAR
DATE
TIME
TIMESTAMP
BINARY
VARBINARY
LONGVARBINARY
c Amparo López Gaona, 2004
Tipo Java
boolean
byte
short
int
long
float
double
double
java.math.BigDecimal
java.math.BigDecimal
java.lang.String
java.lang.String
java.lang.String
java.sql.Date
java.sql.Time
java.sql.Timestamp
byte[]
byte[]
byte[]
Transparencia No. 18
Introducción a XML
JDBC Básico
Valores nulos
Si en la base de datos hay un valor null, el método getInt() devuelve un
cero.
En Java se tiene un null pero es para referencias.
Después de un getXXX se puede preguntar wasNull() para investigar si el valor
recuperado es el nulo de SQL.
c Amparo López Gaona, 2004
Transparencia No. 19
Introducción a XML
JDBC Básico
Proposiciones Pre-compiladas
Si se desea realizar varias veces la misma instrucción con diferentes valores
es conveniente usar una proposición preparada.
Un objeto PreparedStatement debe tener una proposición SQL en su creación.
Está se envı́a al SABD inmediatamente y se compila.
PreparedStatement ventasReales = con.PrepareStatement(
"UPDATE cafe SET ventas = ? WHERE nombre LIKE ?");
Existen métodos setXXX de la clase PreparedStatement para asignar valor a los
parámetros.
Para que se ejecute la instrucción se debe llamar al método executeUpdate().
ventasReales.setInt(1, 75);
ventasReales.setString(2, "Colombiano");
ventasReales.executeUpdate();
ventasReales.setString(2, "Oaxaca");
ventasReales.executeUpdate();
c Amparo López Gaona, 2004
Transparencia No. 20
Introducción a XML
JDBC Básico
Para limpiar los datos de un parámetro 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 López Gaona, 2004
Transparencia No. 21
Introducción a XML
JDBC Básico
Transacciones y JDBC
Una transacción es una unidad lógica de trabajo.
Al crear una conexión se está en modo auto-commit que significa que cada instrucción SQL se trata como una transacción.
Para permitir agrupar instrucciones en una transacción se debe desactivar el modo
de auto-commit vı́a la instrucción:
con.setAutoCommit(false);
La transacción termina al llamar al método commit o rollback.
Para que se graben los cambios efectuados por la transacción se debe llamar
explı́citamente al método commit.
c Amparo López Gaona, 2004
Transparencia No. 22
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 23
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 24
Introducción a XML
JDBC Básico
} catch(SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
if (con != null)
try {
System.out.println("La transacción 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 López Gaona, 2004
Transparencia No. 25
Introducción a XML
JDBC Básico
Procedimientos Almacenados
Un procedimiento almacenado (store procedure) es un grupo de instrucciones
SQL que forman una unidad lógica y realizan un tarea particular.
Pueden ser compilados y ejecutados con diferentes parámetros y resultados.
Ventajas:
Debido a que son precompilados se ejecutan mucho más rápido que cada
instrucción por separado.
Los errores de sintaxis pueden corregirse al momento de compilación no de
ejecución.
Los programadores Java sólo requieren el nombre del procedimiento, sus
entradas y salidas.
c Amparo López Gaona, 2004
Transparencia No. 26
Introducción a XML
JDBC Básico
Ejemplo
Creación:
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 CallableStatem
el cual contiene una llamada a un procedimiento almacenado no contiene el
procedimiento.
CallableStatement cs = con.prepareCall("{call lista_proveedores}");
ResultSet rs = cs.executeQuery();
c Amparo López Gaona, 2004
Transparencia No. 27
Introducción a XML
JDBC Básico
Ejemplo de un procedimiento con parámetros
CREATE PROCEDURE calcula_interes (id IN INTEGER, bal OUT FLOAT) IS
BEGIN
select balance into bal
from
cuenta
where cuenta_id = id;
bal := bal + bal * 0.03;
update cuenta
set
balance = bal
where cuenta_id = id;
END;
c Amparo López Gaona, 2004
Transparencia No. 28
Introducción a XML
JDBC Básico
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 función la sintaxis serı́a {? = call nombre(?,?)}
c Amparo López Gaona, 2004
Transparencia No. 29
Introducción a XML
JDBC Básico
JDBC 2.0
Con JDBC 2.0 es posible hacer lo siguiente:
Moverse en cualquier dirección 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 López Gaona, 2004
Transparencia No. 30
Introducción a XML
JDBC Básico
Movimiento en el resultado
El método createStatement puede tener dos parámetros:
El primero puede ser:
• TYPE FORWARD ONLY. *
• TYPE SCROLL INSENSITIVE.
• TYPE SCROLL SENSITIVE.
El segundo parámetro:
• CONCUR READ ONLY. *
• CONCUR UPDATABLE.
Es importante el orden de estos parámetros.
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet srs = stmt.executeQuery("SELECT nombre, precio FROM cafe");
c Amparo López Gaona, 2004
Transparencia No. 31
Introducción a XML
JDBC Básico
Métodos para moverse en el ResultSet
next. Se mueve hacia adelante.
previous. Se mueve hacia atrás.
afterLast,beforeFirst, first, last. Se mueve a la posición indicada.
absolute(int). Se mueve a la tupla especificada en el parámetro. Si éste es
negativo empieza a contar del final hacia arriba.
relative (int). A partir de la posición actual, se mueve tantos lugares como
se indique en su parámetro.
getRow. Devuelve el número de tupla en que se está posicionado.
isFirst, isLast, isBeforeFirst, isAfterLast. Devuelven un valor Booleano.
moveToInsertRow y moveToCurrentRow.
¿Cuántos renglones hay en el resultado?
¿Cómo listar al revés?
c Amparo López Gaona, 2004
Transparencia No. 32
Introducción a XML
JDBC Básico
Actualizaciones en lote
Con JDBC 2.0 los objetos de Statement, PreparedStatement y CallableStatement
tienen la capacidad de mantener una lista de comandos que pueden ser transmitos
como un lote.
Instrucciones:
clearBatch. Borra todo lo que haya en la lista. Al crearla está limpia.
addBatch. Agrega instrucciones a la lista.
executeBatch. Envia la lista de instrucciones a la BD.
c Amparo López Gaona, 2004
Transparencia No. 33
Introducción a XML
JDBC Básico
Mini ejemplo: El dueño del café ha decidido incluir cuatro nuevos tipos de cafés
a 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);
Sólo se pueden enviar en un lote instrucciones que regresan valor numérico. En
caso contrario se disparan las siguientes excepciones:
SQLException.
BatchUpdateException.
c Amparo López Gaona, 2004
Transparencia No. 34
Introducción a XML
JDBC Básico
Al igual que en el procesamiento en lı́nea, el ejemplo es ineficiente debido al uso
de 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 López Gaona, 2004
Transparencia No. 35
Introducción a XML
JDBC Básico
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 método getConcurrency() que devuelve:
• 1007 para indicar que es sólo de lectura.
• 1008 para indicar que es actualizable.
c Amparo López Gaona, 2004
Transparencia No. 36
Introducción a XML
2.
JDBC Básico
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, de
la tupla en donde se encuentra el cursor.
Recordar que la posición 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 actualización (en el conjunto de
resultados) se debe usar el método cancelRowUpdates pero antes de llamar a
updateRow.
nuevoRS.last();
nuevoRS.updateFloat("precio", 35.50);
...
nuevoRS.cancelRowUpdates();
El precio se mantiene tanto en el resultset como en la BD debido a que no
se llamo a updateRow.
c Amparo López Gaona, 2004
Transparencia No. 37
Introducción a XML
JDBC Básico
Supresiones del conjunto de resultados
Para eliminar tuplas sin usar SQL:
1.
Estar en la posición correcta.
2.
Borrarlo con la instrucción deleteRow
Ejemplo: Eliminar el cuarto renglón.
nuevoRS.absolute(4);
nuevoRS.deleteRow();
Lo que sucede en el ResultSet depende de la implementación. Puede ser que
elimine el renglón, lo marque como borrado o lo deje en blanco.
c Amparo López Gaona, 2004
Transparencia No. 38
Introducción a XML
JDBC Básico
Inserciones a la BD
Para insertar una nueva tupla modificando al ResultSet se debe:
1.
Mover el cursor vı́a el método moveToInsertRow.
2.
Asignar valor a cada columna con el método updateXXX apropiado.
3.
Llamar al método insertRow para insertar esta nueva tupla en el conjunto de
resultados y en la base de datos simultáneamente.
c Amparo López Gaona, 2004
Transparencia No. 39
Introducción a XML
JDBC Básico
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.updateInt("id_proveedor", 150);
nuevoRS.updateFloat("precio", 35.50);
nuevoRS.updateInt("ventas", 0);
nuevoRS.updateInt("total", 0);
nuevoRS.insertRow();
%
%
%
%
%
nuevoRS.updateString(1, "Java");
nuevoRS.updateInt(2, 150);
nuevoRS.updateFloat(3, 35.50);
nuevoRS.updateInt(4, 0);
nuevoRS.updateInt(5, 0);
Si se omite algún valor, pone el definido por omisión, o nulo, o si no está en
ninguno de los casos anterior dispara una excepción del tipo SQLException.
c Amparo López Gaona, 2004
Transparencia No. 40
Introducción a XML
JDBC Básico
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 como
bytes. Este tipo es mapeado a Blob.
CLOB (Character Large Object), para almacenar grandes cantidades de datos
como 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
BLOB
CLOB
ARRAY
Tipo estructurado
REF (tipo estructurado)
c Amparo López Gaona, 2004
Método getXXX
getBlob
getClob
getArray
getObject
getRef
Método setXXX
setBlob
setClob
setArray
setObject
setRef
Método updateXXX
updateBlob *
updateClob *
updateArray *
updateObject
updateRef *
Transparencia No. 41
Introducción a XML
JDBC Básico
Metadatos
Su objetivo es proporcionar las herramientas para evitar que el programador tenga
que conocer a fondo la organización de la BD.
Información acerca de los datos que no son de interés para el usuario final pero
que si requiere el programador para manejar los datos.
Existen dos interfaces en java.sql para los metadatos:
ResultSetMetaData. Proporciona información acerca del tipo y propiedades de
cada columna de un objeto ResultSet.
DatabaseMetaData. Proporciona información acerca de una base de datos o un
SABD particular.
c Amparo López Gaona, 2004
Transparencia No. 42
Introducción a XML
JDBC Básico
ResultSetMetaData
Como su nombre indica proporciona información acerca de los tipos y propiedades
de las columnas en un objeto ResultSet regresado por una consulta a la BD.
Un ejemplar de ResultSetMetaData contiene la información y sus métodos proporcionan el acceso a ella.
Creación.
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 López Gaona, 2004
Transparencia No. 43
Introducción a XML
JDBC Básico
Todos los métodos de esta clase devuelven información acerca de una columna
particular en rs, excepto el método getColumnCount que devuelve la cantidad total
de columnas en el resultado.
Para obtener el nombre de las columnas se usa el método 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 López Gaona, 2004
Transparencia No. 44
Introducción a XML
JDBC Básico
La interfaz completa es:
int getColumnCount()
int getColumnType(int)
int getColumnDisplaySize(int)
int getPrecision(int)
int getScale(int)
int isNullable (int)
String getColumnTypeName(int)
String getColumnName(int)
String getColumnLabel(int)
c Amparo López Gaona, 2004
boolean
boolean
boolean
boolean
isWritable (int)
isReadOnly(int)
isSigned (int)
isCaseSensitive (int)
String getTableName(int)
String getSchemaName(int)
String getCatalogName(int)
Transparencia No. 45
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 46
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 47
Introducción a XML
JDBC Básico
La salida de este programa es:
Columna
Columna
Columna
Columna
Columna
1
2
3
4
5
es
es
es
es
es
del
del
del
del
del
tipo
tipo
tipo
tipo
tipo
c Amparo López Gaona, 2004
JDBC
JDBC
JDBC
JDBC
JDBC
12 y corresponde a varchar en la BD.
4 y corresponde a int4 en la BD.
8 y corresponde a float8 en la BD.
4 y corresponde a int4 en la BD.
4 y corresponde a int4 en la BD.
Transparencia No. 48
Introducción a XML
JDBC Básico
DatabaseMetaData
Proporciona información acerca de la BD para un objeto Connection.
Usos principales:
Conocer información acerca de la BD que se está usando.
Permitir crear aplicaciones independientes de la BD.
Creación: DatabaseMetaData dbmd = con.getMetaData();
Uso: int n = dbmd.getMaxTableNameLength();
c Amparo López Gaona, 2004
Transparencia No. 49
Introducción a XML
JDBC Básico
Existen más de 150 métodos en esta interfaz, éstos se clasifican de acuerdo al
valor que devuelven:
Métodos que devuelven cadenas. Tales como el URL, nombre del usuario,
del producto, versión, nombre del controlador. Las palabras reservadas del
SABD, funciones numéricas, de cadenas, del sistema, fecha/hora.
Métodos que devuelven enteros. Generalmente tienen la forma getMaxXXX.
Máximo número de caracteres permitidos en una instrucción, para un identificador.
Métodos que devuelven Booleanos. Generalmente tienen la forma supportsXXX,
donde XXX es la capacidad que soportan. De estos hay más de 70.
Métodos que devuelven listas de información en objetos ResultSet, en este
caso 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 López Gaona, 2004
Transparencia No. 50
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 51
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 52
Introducción a XML
JDBC Básico
Parte de la salida de este ejemplo:
DBMS type varchar:
java.sql.Types: 12
parameters used to create: null
nullable?: 0
case sensitive?: false
DBMS type date:
java.sql.Types: 91
parameters used to create: null
nullable?: 0
case sensitive?: false
DBMS type time:
java.sql.Types: 92
parameters used to create: null
nullable?: 0
case sensitive?: false
información necesaria para conectarse a la BD.
c Amparo López Gaona, 2004
Transparencia No. 53
Introducción a XML
JDBC Básico
Monitor de terminal genérico
Esta aplicación permite introducir proposiciones SQL en la lı́nea de comandos y
ver el resultado formateado.
Las instrucciones permitidas son:
commit. Envı́a un commit a la BD.
go. Envı́a la instrucción que tenga el buffer para que sea procesada como
instrucción SQL. vı́a el método executeStatement()
quit. Cierra la BD y termina la aplicación.
reset. Limpia el buffer sin enviar su información a la BD.
rollback. Aborta cualquier transacción inconclusa.
show version. Despliega información acerca de este programa.
c Amparo López Gaona, 2004
Transparencia No. 54
Introducción a XML
JDBC Básico
EL método 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 López Gaona, 2004
Transparencia No. 55
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 56
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 57
Introducción a XML
JDBC Básico
else
System.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 López Gaona, 2004
Transparencia No. 58
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 59
Introducción a XML
JDBC Básico
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);
else
System.out.println("show version");
}
catch( SQLException e ) {
System.out.println("Failed to load meta data: " + e.getMessage());
}
c Amparo López Gaona, 2004
Transparencia No. 60
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 61
Introducción a XML
JDBC Básico
EL método 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 López Gaona, 2004
Transparencia No. 62
Introducción a XML
JDBC Básico
}
}
}
catch( SQLException e ) {
throw e;
}
finally { // close out the statement
if( statement != null ) {
try { statement.close(); }
catch( SQLException e ) { }
}
}
}
c Amparo López Gaona, 2004
Transparencia No. 63
Introducción a XML
JDBC Básico
EL método 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 López Gaona, 2004
Transparencia No. 64
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 65
Introducción a XML
JDBC Básico
label = label.substring(0, size);
else
while( 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";
else
str = value.toString();
c Amparo López Gaona, 2004
Transparencia No. 66
Introducción a XML
JDBC Básico
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 López Gaona, 2004
Transparencia No. 67
Introducción a XML
JDBC Básico
buffer = new StringBuffer("1 row selected.\n" +
buffer.toString() + bar.toString());
else
buffer = 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 López Gaona, 2004
Transparencia No. 68
Introducción a XML
JDBC Básico
EL método 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 López Gaona, 2004
Transparencia No. 69
Descargar