10 JDBC 287 10 JDBC Introducción javasql JDBC(Java DataBase Connectivity), consiste en un conjunto de clases e interfaces Java que permiten desarrollar aplicaciones de acceso a Bases de Datos JDBC envía sentencias SQL a una base de datos relacional, no es necesario reescribir la aplicación para un SGBD (Sistema Gestor de Bases de Datos) distinto JDBC(Java DataBase Connectivity), está basado en X/Open SQL CLI(Call Level Interface) y ODBC de Microsoft David Contreras Bárcena 288
10 JDBC - Introducción Ventajas de JDBC frente a ODBC ODBC no es apropiado para un uso directo con Java, porque usa un interface C Una traslación literal del API ODBC en API Java no es deseable Cuando se usa ODBC, los drivers deben instalarse manualmente en todos los clientes David Contreras Bárcena 289 10 JDBC Introducción Pasos a dar para acceder desde una aplicación Java a una tabla de una Base de Datos: Paso 1 Cargar el driver adecuado que permita realizar la conexión: El driver se corresponderá con una clase Java que se deberá cargar en memoria Paso 2 Establecer la conexión con la base de datos: Se deberá conocer el nombre de la base de datos, ubicación, usuario, etc Paso 3 Enviar sentencias SQL a la Base de Datos: Gracias al lenguaje estándar SQL se generarán sentencias para manipular la tabla Paso 4 Procesar los resultados obtenidos de la sentencia SQL: Si la sentencia devuelve resultados (pe SELECT), se procesarán a través de un objeto Java David Contreras Bárcena 290
10 JDBC Drivers (Paso 1) Existen cuatro tipos de drivers: 1 JDBC-ODBC bridge, suministra acceso JDBC mediante drivers ODBC 2 Native- API- portly Java, convierte llamadas JDBC en llamadas al API de los SGBD (Oracle, Sybase, Informix, DB2,etc) 3 JDBC Net pure Java, translada llamadas JDBC en un protocolo independiente del SGBD 4 Native Protocol pure Java, convierte llamadas JDBC en un protocolo de red usado por el SGBD directamente Se deben emplear las categorías no puras JAVA cuando no existan drivers disponibles para el SGBD Las dos últimas categorías soportan tecnología JAVA pura David Contreras Bárcena 291 10 JDBC Drivers (Paso 1) El driver se corresponde con una clase Java que nuestro programa Java deberá cargar en memoria para poder dialogar con el SGBD El driver de tipo 1 está incuido en la API de JDBC, los de tipo 2, 3 y 4 los deberá suministrar el fabricante App JAVA JDBC Driver Driver JDBC Nativo BRIDGE BBDD Driver ODBC BBDD SQL 92 David Contreras Bárcena 292
10 JDBC Drivers (Paso 1) Ejemplos de drivers: Driver JDBC-ODBC: sunjdbcodbcjdbcodbcdriver (incluido en la API de JDBC de la plataforma J2SE) ClassforName("sunjdbcodbcJdbcOdbcDriver"); Driver MySQL: commysqljdbcdriver (no incluido) ClassforName ("oraclejdbcdriveroracledriver"); Driver DB2: COMibmdb2jdbcappDB2Driver (no incluido) ClassforName("COMibmdb2jdbcappDB2Driver"); Driver Oracle: oraclejdbcdriveroracledriver (no incluido) ClassforName("commysqljdbcDriver"); David Contreras Bárcena 293 10 JDBC Conexión (Paso 2) Una vez que se dispone del driver que permite dialogar con el SGBD, se puede establecer la conexión La conexión física con la base de datos se representa en Java a través del interface Connection Al utilizar el driver ODBC Bridge hay que establecer una relación entre la base de datos y el controlador ODBC de la máquina La forma de realizar la conexión física con la base de datos es a través de la invocación del método getconnection de la clase DriverManager Este método devuelve un objeto del tipo Connection Connection con = DriverManagergetConnection (nombrebbdd) David Contreras Bárcena 294
10 JDBC Conexión (Paso 2) Interface Connection: close() : Se encarga de cerrar la conexión con la BD commit(): Todos los cambios realizados desde el último commit se vuelven pemanentes rollback() : Desecha todos los cambios realizados desde el último commit createstatement(): Crea un objeto Statement que ejecutará sentencias SQL preparecall(string): Crea un objeto CallableStatement, para ejecutar llamada a Stored Procedures preparestatement(string) : Crea un objeto PreparedStatement, para realizar llamadas a sentencias SQL que contengan parametros de entrada setautocommit(boolean): Activa o desactiva el método autocommit Después de cada transacción se realiza un commit David Contreras Bárcena 295 10 JDBC Conexión (Paso 2) Importar las clases del paquete javasql; Habilitar el driver de acceso a la base de datos cargándolo en memoria: ClassforName("sunjdbcodbcJdbcOdbcDriver") Especificar el nombre completo de la base de datos: jdbc:<subprotocolo>:<nombre> <subprotocolo> es el driver utilizado, pe odbc <nombre> es la referencia a la base de datos Establecer la conexión: Connection con = DriverManagergetConnection (nombre_completo_bbdd) Realizar las consultas contra la BBDD David Contreras Bárcena 296
10 JDBC Conexión ODBC (Paso 2) La referencia ODBC a la base de datos se puede realizar de dos formas: Referencia física a la base de datos: Se escribe el nombre de la base de datos, empleando una ruta relativa o absoluta "jdbc:odbc:driver=microsoft Access Driver (*mdb); DBQ=datosmdb; PWD="; A través de un DSN (Data Source Name) : Es un nombre lógico asociado a una base de datos con su driver correspondiente Esto nos permite crear una independencia entre nuestro programa JAVA y el tipo de driver a emplear Es un único de Windows La relación entre el controlador ODBC y la base de datos recibe el nombre de DSN Esta relación se hace en el Panel de Control, Controladores ODBC "jdbc:odbc:clientes"; David Contreras Bárcena 297 10 JDBC Conexión Ejemplo (Paso 2) import javasql*; import javaio*; class JDBCConexion public static void main(string[] args) try String bd="jdbc:odbc:clientes"; //con DSN //String bd="jdbc:odbc:driver=microsoft Access Driver (*mdb); //DBQ=datosmdb; ; ClassforName("sunjdbcodbcJdbcOdbcDriver"); Connection con=drivermanagergetconnection(bd); conclose(); catch (SQLException e) Systemoutprintln( Error en la conexión ); catch (ClassNotFoundException e) Systemoutprintln( Driver no encontrado ); David Contreras Bárcena 298
10 JDBC Ejecutar sentencias SQL (Paso 3) Una vez que se ha establecido la conexión a la base de datos, se emplea el objeto Connection para enviar sentencias SQL al gestor Las sentencias SQL se pueden enviar al gestor de tres modos diferentes: Statement, creación de consultas de estructura estática PreparedStatement, creación de consultas de estructura dinámica CallableStatement, ejecución de procedimientos almacenados en el gestor David Contreras Bárcena 299 10 JDBC Statement (Paso 3) Clase que permite ejecutar cualquier tipo de sentencia SQL Se utilizará esta clase cuando se conozcan todos los parámetros de la consulta La construcción de la consulta, por lo tanto, es estática Métodos: ResultSet executequery(string s): Devuelve un conjunto de resultados dada un query int executeupdate (String s): Ejecuta una sentencia SQL de modifiación (INSERT, UPDATE o DELETE) devolviendo el número de filas afectadas Statement stm = concreatestatement(); ResultSet rs = stmexecutequery("select * FROM personas"); David Contreras Bárcena 300
10 JDBC Statement (Paso 3) import javasql*; class Lee public static void main(string args[]) Connection con; try ClassforName("sunjdbcodbcJdbcOdbcDriver"); con=drivermanagergetconnection("jdbc:odbc:tabla ); Statement stm = concreatestatement(); ResultSet rs = stmexecutequery( "SELECT nombre, dni from personas"); David Contreras Bárcena 301 10 JDBC Statement (Paso 3) while(rsnext()) String s=rsgetstring("nombre"); int i=rsgetint("dni"); Systemoutprintln("Nombre:" + s + " DNI:" + i); rsclose(); stmclose(); conclose(); catch (SQLException e) Systemoutprintln( Error en acceso a base de datos ); catch (ClassNotFoundException e) Systemoutprintln( Driver no encontrado ); David Contreras Bárcena 302
10 JDBC PreparedStatement (Paso 3) Clase que permite ejecutar cualquier tipo de sentencia SQL Se utilizará esta clase cuando no se conozcan alguno de los parámetros de la consulta La sentencia se prepara especificando la estructura y colocando comodines en aquellos puntos donde irán los futuros valores Una vez que se conozcan dichos valores, se asignarán con los métodos set correspondientes La construcción de la consulta, por lo tanto, es dinámica PreparedStatement pstm = conpreparestatement("select * FROM Personas WHERE Nombre =?"); pstmsetstring(1, Manuel ); ResultSet rs = stmexecutequery(); David Contreras Bárcena 303 10 JDBC PreparedStatement (Paso 3) Métodos: void settipodato(int, tipodato): Posee tantos métodos como tipos de datos soporta Java El primer argumento indica el comodín a sustituir (comienza en 1), y el segundo el valor void setint(int, int) void setstring(int, String) Resulset executequery(string s): Devuelve un conjunto de resultados dada un query int executeupdate (String s): Ejecuta una sentencia SQL de modifiación (INSERT, UPDATE o DELETE) devolviendo el número de filas afectadas David Contreras Bárcena 304
10 JDBC PreparedStatement (Paso 3) import javasql*; class Lee public static void main(string args[]) Connection con; try ClassforName("sunjdbcodbcJdbcOdbcDriver"); con=drivermanagergetconnection("jdbc:odbc:tabla ); PreparedStatement ps = conpreparestatement("select * FROM Persona WHERE Edad >? OR Nombre =?"); pssetint(1, 45); pssetstring(2, "David"); ResultSet rs = psexecutequery(); David Contreras Bárcena 305 10 JDBC PreparedStatement (Paso 3) while(rsnext()) Systemoutprintln(rsgetString("nombre")); //Systemoutprintln(rsgetString(1)); rsclose(); pstmclose(); conclose(); catch (SQLException e) Systemoutprintln( Error en acceso a base de datos ); catch (ClassNotFoundException e) Systemoutprintln( Driver no encontrado ); David Contreras Bárcena 306
10 JDBC ResultSet (Paso 4) Permite recoger el resultado de una sentencia SELECT La estructura interna del objeto es una tabla El cursor se posiciona en cada una de las filas de la vista resultado, permitiendo acceder a las columnas gracias a un índice numérico o al nombre del campo Métodos: boolean next(): Nos indica si hay más filas dentro de la vista resultado (ResultSet) y avanza a la siguiente tipodato gettipodato(int) ó tipodato gettipodato(string): Devuelve el valor de la columna indicada El entero hace referencia a la posición del campo, el String, al nombre La primera columna comienza en 1 int getint(int) ó int getint(string) String getstring(int) ó String getstring(string) David Contreras Bárcena 307 10 JDBC ResultSet (Paso 4) ResultSet rs = stmexecutequery("select nombre, dni FROM personas"); while(rsnext()) String s=rsgetstring("nombre"); int i=rsgetint("dni"); ResultSet rs = stmexecutequery("select nombre, dni FROM personas"); while(rsnext()) String s=rsgetstring(1); int i=rsgetint(2); David Contreras Bárcena 308
10 JDBC - Relación entre las clases DriverManager getconnection() Statement getmoreresults() executequery() ResultSet Connection commit() rollback() PreparedStatement CallableStatement executeupdate() setxxx() getxxx() getxxx() Tipos de de Datos David Contreras Bárcena 309 10 JDBC Tipos de datos Tabla de equivalencia entre tipos de datos SQL y JAVA SQL CHAR VARCHAR LONGVARCHAR NUMERIC DECIMAL BIT TINYINT SMALLINT INTEGER BIGINT REAL FLOAT DOUBLE BINARY VARBINARY LONGVARBINARY DATE TIME Java String String String javamathbigdecimal javamathbigdecimal boolean byte short int long float double double byte[] byte[] byte[] javasqldate javasqltime David TIMESTAMP Contreras Bárcena javasqltimestamp 310
10 JDBC Tipos de datos Para realizar reflection con las tablas de la base de datos, es necesario trabajar con la clase ResultSetMetaData Los métodos de esta clase permiten obtener información sobre el número de columnas, nombre, tipo de datos que almacena, etc Los tipos de datos de las tablas se identifican con atributos estáticos de la clase Types Valores enteros de cada uno de los tipos SQL de Java: BIT: -7 TINYINT: -6 SMALLINT: 5 INTEGER: 4 BIGINT: -5 FLOAT: 6 REAL: 7 DOUBLE: 8 NUMERIC: 2 DECIMAL: 3 CHAR: 1 OTHER: 1111 VARCHAR: 12 JAVA_OBJECT: 2000 LONGVARCHAR: -1 DISTINCT: 2001 DATE: 91 STRUCT: 2002 TIME: 92 ARRAY: 2003 TIMESTAMP: 93 BLOB: 2004 BINARY: -2 CLOB: 2005 VARBINARY: -3 REF: 2006 LONGVARBINARY: -4 DATALINK: 70 NULL: David 0Contreras Bárcena BOOLEAN: 16 311 10 JDBC Ejemplos de sentencias SQL Consulta: SELECT * FROM clientes SELECT nombre, direccion, ciudad FROM clientes SELECT * FROM clientes WHERE ciudad = Madrid ORDER BY nombre Inserción: INSERT INTO clientes (nombre, direccion, ciudad, telefono, dni) VALUES ('Carlos Rios', 'Caseros 2417', 'Madrid ', '48485825', 232525) INSERT INTO clientes VALUES ('Carlos Rios', 'Caseros 2417', 'Madrid', '48485825', 232525) //si se trata de todos los campos Actualización: UPDATE clientes SET nombre='carlos Rios' WHERE dni = 232525 Eliminación: DELETE FROM clientes WHERE dni = 232525 David Contreras Bárcena 312