JDBC

Anuncio
Base de Datos Oracle:
desarrollo de aplicaciones
JDBC
Contenidos
jul-04
Introducción
Drivers
Conexión
Ejecución de sentencias
ResultSets y Cursores
Transacciones
Control de errores
Alberto M.F.A. [email protected]
2
Características
API Java OO que provee acceso
universal a DBMS relacionales
JDBC 3.0 también acceso a datos NO
Relacionales
Simplifica envío de sentencias SQL a
DBMS
NO estandariza el SQL, se pasa al driver
jul-04
Alberto M.F.A. [email protected]
3
Versiones de SQL
Formas de afrontar:
jul-04
Pasa el SQL directamente al driver
Se ajusta a las secuencias de escape ODBC
Interfaz DatabaseMataData. El programa
puede averiguar las capacidades del driver.
Todos los drivers deben soportar al menos
ANSI SQL-92 Entry Level
Alberto M.F.A. [email protected]
4
Arquitectura JDBC
jul-04
Alberto M.F.A. [email protected]
5
JDK Java
En el JDK SUN provee:
En WEB:
jul-04
JDBC DriverManager
JDBC-ODBC Bridge
JDBC driver test suite. Para homologar
drivers
http://java.sun.com/products/jdbc
Alberto M.F.A. [email protected]
6
Versiones de JDBC
JDBC 1.0
JDBC 2.0
Scrollable y updatable result sets
Pooling de conexiones
Oracle 8i es
JDBC 2.1
JDBC 2.0
JDBC 3.0
SavePoints
Claves autogeneradas
Pooled statements, etc
jul-04
Alberto M.F.A. [email protected]
7
Modelo de objetos
Statement
<excuteQuery>
<crea>
Connection
PreparedStatement
ResultSet
CallableStatement
jul-04
Alberto M.F.A. [email protected]
8
Contenidos
Introducción
Drivers
Conexión
Ejecución de sentencias
ResultSets y Cursores
Transacciones
Control de errores
jul-04
Alberto M.F.A. [email protected]
9
Drivers
Suministrados por los fabricantes
Cuatro tipos distintos:
jul-04
(1)
(2)
(3)
(4)
JDBCODBC + driver ODBC
JDBCAPI nativo
JDBCProtocolo Middleware
JDBCProtocolo Nativo
Alberto M.F.A. [email protected]
10
Drivers tipo 1
Para acceso desde Windows cualquier
DBMS que no tiene JDBC
Debe haber un driver ODBC instalado
en el equipo que accede a DBMS.
No apto para conectar desde applets
Solución de primera mano si no hay
otra forma
jul-04
Alberto M.F.A. [email protected]
11
Drivers tipo 1
Aplicación
Driver
JDBC
ODBC
Driver
ODBC
Programador
SUN, JDK
Microsoft
Fabricante DBMS
jul-04
Alberto M.F.A. [email protected]
DBMS
Máquina
cliente
12
Drivers tipo 2
El driver JDBC delega en las librerías del
API nativo (OCI por ejemplo)
También exige que en la máquina que
accede esté instalado el driver
adecuado.
Tampoco es apto para Applets.
Puede dar buen rendimiento, delega
con JNI en el API.
jul-04
Alberto M.F.A. [email protected]
13
Drivers tipo 2
Driver
JDBC
Aplicación
API
Nativo
DBMS
Programador
Fabricante DBMS
JNI
jul-04
Alberto M.F.A. [email protected]
Máquina
cliente
14
Drivers tipo 3
Entre el cliente y el DBMS hay un
servidor middleware conversor.
El driver convierte llamadas JDBC a un
protocolo intermedio.
El servidor middleware traduce a
llamadas al protocolo nativo del DBMS.
Solución cómoda para el fabricante,
facilita hacer muchos interfaces.
jul-04
Alberto M.F.A. [email protected]
Máquina
cliente
Drivers tipo 3
Aplicación
Driver
JDBC
15
Servidor
Middleware
DBMS
Programador
Fabricante DBMS
Protocolo Nativo
Otra
Máquina
Protocolo Intermedio
jul-04
Alberto M.F.A. [email protected]
16
Drivers tipo 4
Driver JDBC traduce al protocolo nativo
del DBMS.
Se obtiene buen rendimiento.
El cliente es independiente de
plataforma e instalación (Applet).
La JVM descarga todas las clases del
driver según demanda.
jul-04
Alberto M.F.A. [email protected]
17
Drivers tipo 4
Driver
JDBC
Aplicación
DBMS
Programador
Fabricante DBMS
Protocolo Nativo
jul-04
Alberto M.F.A. [email protected]
Máquina
cliente
18
JDBC de Oracle
Thin Driver, de tipo 4
OCI driver, de tipo 2
El DBMS incluye una JVM, para ella:
jul-04
Server-side thin driver
Server-side internal driver
Alberto M.F.A. [email protected]
19
JVM de Oracle
Admite procedimientos almacenados en
JAVA. Estos pueden conectarse a otros
servidores.
Incluye un contenedor J2EE de EJB’s.
jul-04
Incrusta la capa de lógica de negocio en la
base de datos.
Los drivers JDBC está optimizados para la
conexión interna.
Alberto M.F.A. [email protected]
20
Diagrama de drivers
jul-04
Alberto M.F.A. [email protected]
21
Contenidos
jul-04
Introducción
Drivers
Conexión
Ejecución de sentencias
ResultSets y Cursores
Transacciones
Control de errores
Alberto M.F.A. [email protected]
22
Conexión
Tres alternativas:
Usando el DriverManager
Usando un DataSource
Instanciando el Driver Directamente
Tras el proceso se obtiene un objeto de
la Clase Connection
jul-04
Alberto M.F.A. [email protected]
23
Conexión con DriverManager
Registra todos los drivers JDBC
jul-04
El driver a usar debe ser registrado
previamente
Al crear la conexión se le indica el URL
del driver
El DM localiza el driver adecuado
buscando el URL entre los que tiene
registrados
Alberto M.F.A. [email protected]
24
URL de driver
<protocol>:<sub-protocol>:<subname>
<protocol> Siempre JDBC
<sub-protocol> Nombre del driver o mecanismo
<subname> Dependiente de sub-protocol. Indicación de
cómo abrir sesión (User, Pass, Server, DataSource, alias,
etc)
jdbc:odbc:<miConexion>
jdbc:oracle:oci8:@<instancia>
jdbc:oracle:thin:@<maquina>:1521:<instancia>
jul-04
Alberto M.F.A. [email protected]
25
Ejemplo con DriverManager
DriverManager.registerDriver(
new oracle.jdbc.driver.OracleDriver()
);
conn = DriverManager.getConnection(
“jdbc:oracle:oci8:@desa”
, “scott”
, “tiger”
);
jul-04
Alberto M.F.A. [email protected]
26
DataSource
Desde JDBC 2.0. Representa cualquier fuente
de datos (Como si fuese un alias o DSN
ODBC).
Muchas similitudes con DriverManager
Importantes diferencias:
Se registra en un árbol JNDI
Permite gestionar pools de conexiones
jul-04
Independencia del programa
Aumenta la eficiencia si se abren y cierran muchas
conexiones
Transacciones distribuidas
Alberto M.F.A. [email protected]
27
Registro en JNDI
Se registra bajo una clave la conexión, el
driver y sus particularidades para un DBMS
El programa pregunta por la clave.
Es un nivel de indirección que independiza el
programa de la DBMS.
jul-04
Si mañana cambia la DBMS, se cambia en el JNDI,
el código del programa no se entera.
Alberto M.F.A. [email protected]
28
Propiedades de DataSource
jul-04
dataSourceName
databaseName
description
networkProtocol
user
password
serverName
port
Crear un DataSource
Especificar esto
Registrar en JNDI bajo
un nombre “miBD”
Programa pide
getConnection(“miBD”)
Alberto M.F.A. [email protected]
29
Ejemplo con DataSource
DataSource ds =
(DataSource)ctx.lookup(
"jdbc/miDB");
Connection con =
ds.getConnection();
jul-04
Alberto M.F.A. [email protected]
30
Responsabilidades Connection
Representar y cerrar sesión
Control de transacciones. Committ y RollBack
Creación de objetos sentencia:
jul-04
Statement. Para SQL sin parámetros.
PreparedStatement. SQL con parámetros de
entrada y/o ejecución repetida.
CallableStatement. Llamadas a proc. Almacenados
y parametros de IN/OUT
Alberto M.F.A. [email protected]
31
Contenidos
jul-04
Introducción
Drivers
Conexión
Ejecución de sentencias
ResultSets y Cursores
Transacciones
Control de errores
Alberto M.F.A. [email protected]
32
Statement
Connection con =
DriverManager.getConnection(...);
Statement stmt =
con.createStatement();
ResultSet rs = stmt.executeQuery(
“SELECT a, b, c FROM Table2”
);
jul-04
Alberto M.F.A. [email protected]
33
Formas ejecución Statement
executeQuery(<SQL>, ...)
executeUpdate(<SQL>, ...)
Ejecutar sentencias DDL y DML
Devuelve (int) el nº de filas afectas
execute(<SQL>, ...)
jul-04
Para ejecutar consultas: “SELECT ...”
Siempre devuelve un ResultSet
Devuelve varios ResulSet’s o int’s.
Alberto M.F.A. [email protected]
34
Ejecución en Batch
Statement stmt = con.createStatement();
con.setAutoCommit(false);
stmt.addBatch("INSERT INTO emp VALUES …");
stmt.addBatch("INSERT INTO dep VALUES …");
stmt.addBatch("INSERT INTO emp_dept VALUES
…");
int [] updateCounts = stmt.executeBatch();
jul-04
Alberto M.F.A. [email protected]
35
PreparedStatement
Sentencias SQL precompiladas
Si se van a repetir se deben pasar datos
nuevos en cada ejecución
jul-04
Mayor rendimiento si se van a ejecutar
repetidas veces
Admite parámetros de entrada
Solo parámetros de entrada
Alberto M.F.A. [email protected]
36
Ejemplos PreparedStatement
PreparedStatement pstmt =
con.prepareStatement(
"UPDATE table4 SET m = ? WHERE x = ?” );
...
pstmt.executeUpdate();
PreparedStatement pstmt2 =
con.prepareStatement(
"SELECT a, b, c FROM Table1”);
ResultSet rs = pstmt2.executeQuery();
jul-04
Alberto M.F.A. [email protected]
37
Formas ejecución
preparedStatement
executeQuery(...)
Ejecutar sentencias DDL y DML
Devuelve (int) el nº de filas afectas
execute(...)
jul-04
Para ejecutar consultas: “SELECT ...”
Siempre devuelve un ResultSet
executeUpdate(...)
Sin SQL
Devuelve varios ResulSet’s o int’s.
Alberto M.F.A. [email protected]
38
Valores de parámetros
prstmt.set<TIPO>(<pos>,<valor>);
Cada placeholder (?) en el SQL debe ser
ajustado antes de llamar a execute<>()
La clase PreparedStatement tiene setters
para todos los tipos básicos java
jul-04
setInt, setLong, setFloat, setString, ...
Alberto M.F.A. [email protected]
39
Parámetros
<pos> Se refiere a la posición del ? en la
sentencia
PreparedStatement pstmt =
con.prepareStatement(
"UPDATE table4 SET m = ? WHERE x = ?” );
pstmt.setString(1, “Valor”);
pstmt.setInt(2, 25);
pstmt.executeUpdate();
jul-04
Alberto M.F.A. [email protected]
40
Parámetros nulos
Método pstmt.setNull(...)
Posición del parámetro
Tipo de dato SQL
pstmt.setNull(3,
java.sql.Types.VARCHAR);
jul-04
Alberto M.F.A. [email protected]
41
CallableStatement
Sentencias que llaman a procedimientos
almacenados
Pueden devolver
jul-04
Procedimientos o funciones
ResultSet
Valores discretos en parámetros OUT e
INOUT
Sintaxis ODBC para invocar a proc’s.
Alberto M.F.A. [email protected]
42
Ejemplo
CallableStatement cstmt =
con.prepareCall(
"{call updatePrices(?, ?)}”
);
cstmt.setString(1, “xyz");
cstmt.setFloat(2, 8.49f);
cstmt.executeUpdate();
jul-04
Alberto M.F.A. [email protected]
43
Sintaxis ODBC
{[? =] call procedure_name[(?,
?, ...)]}
“{call procedure}”
“{call procedure(?, ?)}”
“{? = call function}”
“{? = call function(?, ?)}”
jul-04
Alberto M.F.A. [email protected]
44
Ejecución
De la misma forma que
preparedStatement
Hay jerarquía de herencia
jul-04
Statement
PreparedStatement extends Statement
CallableStatement extends
PreparedStatement
Alberto M.F.A. [email protected]
45
Parámetros IN
jul-04
De IN de la misma forma que
preparedStatement
Indicación de NULL en datos de entrada
igual.
Alberto M.F.A. [email protected]
46
Parámetros OUT
Se referencian también por posición
Deben ser registrados ANTES de la
ejecución.
jul-04
registerOutParameter(...)
Alberto M.F.A. [email protected]
47
Ejemplo parámetros OUT
CallableStatement cstmt =
con.prepareCall(
"{call getTestData(?, ?)}");
cstmt.registerOutParameter(1,
java.sql.Types.TINYINT);
cstmt.registerOutParameter(2,
java.sql.Types.DECIMAL);
ResultSet rs = cstmt.executeQuery();
// . . .
byte x = cstmt.getByte(1);
jul-04
Alberto M.F.A. [email protected]
48
Parámetros OUT nulos
Se detectan con el método
callableStatement.wasNull()
Debe ser llamado después del getter
byte x = cstmt.getByte(1);
if (cstmt.wasNull())
{ . . .
Puede que el manipulador del resultado sepa
tratar con valores null.
jul-04
Alberto M.F.A. [email protected]
49
Parámetros INOUT
Referenciados por posición
Combinación de las dos formas
jul-04
Método set<TIPO>(<pos>, <valor>)
registerOutParameter(...)
execute[<modo>]()
Método get<TIPO>(<pos>)
Alberto M.F.A. [email protected]
50
Ejemplo parámetros INOUT
CallableStatement cstmt =
con.prepareCall(
"{call reviseTotal(?)}");
cstmt.setByte(1, (byte)25);
cstmt.registerOutParameter(1,
java.sql.Types.TINYINT);
cstmt.executeUpdate();
byte x = cstmt.getByte(1);
jul-04
Alberto M.F.A. [email protected]
51
Contenidos
jul-04
Introducción
Drivers
Conexión
Ejecución de sentencias
ResultSets y Cursores
Transacciones
Control de errores
Alberto M.F.A. [email protected]
52
ResultSet
Conjunto de filas + cursor
Devuelto en todos los métodos
executeQuery(...)
jul-04
Alberto M.F.A. [email protected]
53
ResultSet + cursor
Posición inicial
jul-04
Alberto M.F.A. [email protected]
54
Ejemplo ResultSet
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(
"SELECT a, b, c FROM Table1");
while (rs.next()) {
int i = rs.getInt("a");
String s = rs.getString("b");
float f = rs.getFloat("c");
System.out.println(i+" "+s+" "+f);
}
jul-04
Alberto M.F.A. [email protected]
55
Cursores
Indican la fila activa del ResultSet
Pueden ser:
Por defecto solo FORWARD (menos recursos)
Para crearlos bidireccionales:
jul-04
Solo hacia delante
Bidireccionales
Indicación expresa en Connection al crear la
sentencia
Alberto M.F.A. [email protected]
56
Movimientos de Cursor
rs.beforeFirst()
rs.afterLast()
rs.next()
rs.previous()
rs.isBeforeFirst()
rs.isAfterLast()
rs.isFirst()
rs.isLast()
jul-04
movimiento
control
Alberto M.F.A. [email protected]
57
Datos de columnas
Métodos getter:
rs.get<TIPO>(<indicacion>);
<indicacion> Señala la columna
Por posición
Por nombre
String s = rs.getString(2);
String s = rs.getString("TITLE");
jul-04
Alberto M.F.A. [email protected]
58
Tipos de ResultSet
Según:
Movimiento del cursor
Si permiten ver cambios hechos por otros
usuarios mientras está abierto
3 tipos:
TYPE_FORWARD_ONLY
TYPE_SCROLL_INSENSITIVE
TYPE_SCROLL_SENSITIVE
jul-04
Alberto M.F.A. [email protected]
59
Tipos de Concurrencia
Forma en la que varios usuarios trabajan
sobre los mimos datos:
CONCUR_READ_ONLY
CONCUR_UPDATABLE
jul-04
Impone bloqueo de lectura
Impone bloqueo de escritura
UPDATABLE restringe mucho la concurrencia.
Se debe administrar con mucha cautela
Alberto M.F.A. [email protected]
60
Retenibilidad (Holdability)
Los ResultSet podrían permanecer en
memoria del cliente después de
terminar la transacción que los creó.
Dos modos:
ResultSet.HOLD_CURSORS_OVER_COMMIT
ResultSet.CLOSE_CURSORS_AT_COMMIT
jul-04
Alberto M.F.A. [email protected]
61
Tipos por defecto
Movimiento del cursor
Concurrencia
CONCUR_READ_ONLY
Holdability
jul-04
TYPE_FORWARD_ONLY
Depende del driver consultar
DatabaseMetadata
Alberto M.F.A. [email protected]
62
Creación de otros tipos de RS
A partir de JDBC 2.0
Se indica al objeto Connection al pedir una
Statement
Statement stmt =
con.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE,
ResultSet.HOLD_CURSORS_OVER_COMMIT
);
jul-04
Alberto M.F.A. [email protected]
63
Otro ejemplo
PreparedStatement pstmt =
con.prepareStatement(
"SELECT EMP_NO, SALARY FROM
EMPLOYEES WHERE EMP_NO = ?",
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE,
ResultSet.HOLD_CURSORS_OVER_COMMIT
);
jul-04
Alberto M.F.A. [email protected]
64
Actualización de datos
Si el rs es CONCUR_UPDATABLE
Sin usar SQL
int n = rs.getInt(3);
rs.updateInt(3, 88);
n = rs.getInt(3); // n = 88
rs.updateString("ADDRESS", "321
Kasten");
jul-04
Alberto M.F.A. [email protected]
65
Borrado de filas
jul-04
Si el rs es CONCUR_UPDATABLE
Se debe posicionar el cursor en la fila a
borrar
rs.deleteRow();
Alberto M.F.A. [email protected]
66
Inserción de nuevas filas
Los RS actualizables tienen una fila especial
para inserciones
Se coloca el cursor en ella y “updates”
rs.moveToInsertRow();
rs.updateObject(1, myArray);
rs.updateInt(2, 3857);
rs.updateString(3, "Mysteries");
rs.insertRow();
rs.first();
jul-04
Alberto M.F.A. [email protected]
67
Contenidos
jul-04
Introducción
Drivers
Conexión
Ejecución de sentencias
ResultSets y Cursores
Transacciones
Control de errores
Alberto M.F.A. [email protected]
68
Transacciones
jul-04
Por defecto la Connection está con:
connection.AutoCommitMode = TRUE
Cada sentencia que se ejecuta es una
transacción.
Para TRX largas:
connection.AutoCommitMode = FALSE
Alberto M.F.A. [email protected]
69
Transacciones distribuidas
jul-04
Solo posible con Connection obtenidas a
través de DataSource
Si son para distribuidas
AutoCommitMode=FALSE
Alberto M.F.A. [email protected]
70
Nivel de aislamiento en TRX
Cuando dos TRX coinciden ¿cómo se
comportan?
4 niveles:
jul-04
Connection.TRANSACTION_READ_UNCOMMITTED
Connection.TRANSACTION_READ_COMMITTED
Connection.TRANSACTION_REPEATABLE_READ
Connection.TRANSACTION_SERIALIZABLE
Depende de DBMS que niveles se soportan
Método setTransactionIsolation(...)
Alberto M.F.A. [email protected]
71
Contenidos
jul-04
Introducción
Drivers
Conexión
Ejecución de sentencias
ResultSets y Cursores
Transacciones
Control de errores
Alberto M.F.A. [email protected]
72
Control de errores (try catch)
Uso adecuado del mecanismo de Excepciones
Java
Las operaciones JDBC “levantan” excepciones
de tipo SQLException
try{
... Código JDBC
}catch(SQLException e){
... Control del error
}
jul-04
Alberto M.F.A. [email protected]
73
Control de errores (try finally)
try{
... Código JDBC
} finally {
... Acción con o sin error
Cerrar siempre RS, Stmt y
Connection
}
jul-04
Alberto M.F.A. [email protected]
74
Mapeado de SQL a Java
El driver debe mapear:
jul-04
Tipos java a tipos java.sql.Types.XXXX
java.sql.Types.XXXX a tipos nativos del
DBMS
En la documentación de SUN y del
fabricante del driver se especifican las
equivalencias
Alberto M.F.A. [email protected]
75
Descargar