Manejar Conexiones a Bases de Datos con     JDBC 3.0
Manejar Conexiones a Bases de Datos con JDBC 3.0Introdución al Tutorial¿Debería leer este Tutorial?Este tutorial presenta ...
Manejar Conexiones a Bases de Datos con JDBC 3.0Arquitectura de la AplicaciónArquitecturar Nuestro SistemaUno de los probl...
Manejar Conexiones a Bases de Datos con JDBC 3.0Fundamentos de los Drivers JDBCIntroducción a los Drivers JDBCUna inspecci...
Manejar Conexiones a Bases de Datos con JDBC 3.0Como la propiedad jdbc.drivers sólo se chequea una vez durante la primera ...
Manejar Conexiones a Bases de Datos con JDBC 3.0Drivers del Tipo 1Los drivers del tipo uno tienen algo en común: todos usa...
Manejar Conexiones a Bases de Datos con JDBC 3.0Codificación para Drivers del Tipo 1El nombre de clase para el driver puen...
Manejar Conexiones a Bases de Datos con JDBC 3.0Drivers del Tipo 2Los drivers del tipo dos también son conocidos como driv...
Manejar Conexiones a Bases de Datos con JDBC 3.0Drivers del Tipo 3Los drivers del tipo tres son drivers puro Java que tran...
Manejar Conexiones a Bases de Datos con JDBC 3.0Drivers del Tipo 4Los drivers del tipo cuatro son drivers puro Java que se...
Manejar Conexiones a Bases de Datos con JDBC 3.0Un Ejemplo Completo de Driver del Tipo 4El siguiente ejemplo muestra cómo ...
Manejar Conexiones a Bases de Datos con JDBC 3.0Transaciones con Bases de DatosTransaciones BásicasUno concepto que causa ...
Manejar Conexiones a Bases de Datos con JDBC 3.0TRANSACTION_READ_COMMITTED indica que la lectura de datos no entregados, n...
Manejar Conexiones a Bases de Datos con JDBC 3.0Para seleccionar un punto de salvado, creamos un objeto Savepoint desde el...
Manejar Conexiones a Bases de Datos con JDBC 3.0Fuentes de DatosFuentes de Datos BásicasUno de los principales benficios d...
Manejar Conexiones a Bases de Datos con JDBC 3.0Registrar una Fuente de DatosEste ejemplo es una implementación de un Data...
Manejar Conexiones a Bases de Datos con JDBC 3.0Usar una Fuente de DatosEl ejemplo anterior establece la relación de unión...
Manejar Conexiones a Bases de Datos con JDBC 3.0Re-Unir una Fuente de DatosCuando queremos cambiar la base de datos partic...
Manejar Conexiones a Bases de Datos con JDBC 3.0Borrar una Fuente de DatosAlgunas veces, querremos borrar un nombre de Dat...
Manejar Conexiones a Bases de Datos con JDBC 3.0Almacenes de Conexiones¿Por qué necesitamos Almacenes de ConexionesCuando ...
Manejar Conexiones a Bases de Datos con JDBC 3.0base de datos. El proceso completo es mucho más sencillo de lo que suena, ...
Manejar Conexiones a Bases de Datos con JDBC 3.0Usar un Almacen de ConexionesUna vez que hemos inicializado el PooledDataS...
Manejar Conexiones a Bases de Datos con JDBC 3.0Optimizar las Comunicaciones con Bases de DatosMétodos JDBC DataSource y D...
Upcoming SlideShare
Loading in...5
×

Manejo conexbd

340

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
340
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
14
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Manejo conexbd

  1. 1. Manejar Conexiones a Bases de Datos con JDBC 3.0
  2. 2. Manejar Conexiones a Bases de Datos con JDBC 3.0Introdución al Tutorial¿Debería leer este Tutorial?Este tutorial presenta los diferentes conceptos implicados en el establecimiento y control de unaconexión con bases de datos dentro de una aplicación Java usando Java Database Connection(JDBC). Está dirigido principalmente a desarrolladores que quieren entender que "qué haydetrás de la escena" cuando usan una base de datos desde dentro de una aplicación JavaEste tutorial asume que estás familiarizado con el lenguaje de programación Java.¿Sobre qué va este Tutorial?Este tutorial demuestra cómo conectar con una base de datos usando JDBC. Aunque pareceinocuo, este punto es realmente un obstáculo tanto para novatos como para veteranos en Java.Este tutorial explicará cómo una aplicación Java dentro de una JVM descubre y se comunica conuna base de datos, empezando con el tradicional driver JDBC y los objetos DriverManager.Después de varios ejemplos que demuestran los cuatro tipos diferentes de drivers JDBC, eltutorial se mueve sobre una explicación de objetos DataSource que usan JNDI. También seincluye una discusión sobre JNDI, y cómo unir, usar, reunir y borrar el objeto DataSource.Finalmente, se presentan y demuestran los conceptos de almacen de conexiones, yespecíficamente los objetos PooledConnection. El tutorial concluye con una discusión deproblemas de ajuste que normalmente se nos pasan cuando desarrollamos aplicaciones deconectividad de base de datos.HerramientasAunque el tutorial proporciona numerosos fragmentos de código para reflejar conceptos ymétodos descritos en el texto, la mayoría de la gente aprenderá mejor trabajando realmente através de los ejemplos. Para trabajar con los ejemplos, necesitarás tener instaladas yfuncionando las siguientes herramientas:Un editor de texto: los ficheros fuente Java son simplemente texto, por eso para crearlos yleerlos, necesitamos un editor de texto. Si tienen acceso a un IDE Java, puedes usarlo, peroalgunas veces ocultan muchos detalles.Un entorno de desarrollo Java, como el Java2 SDK, que está disponible enhttp://java.sun.com/j2se/1.4/. El Java2 SDK, Standard Edition versión 1.4, incluye lasextensiones estándard JDBC así como JNDI, ámbos son necesarios para algunos de losejemplos posteriores de este tutorialUna base de datos compatible SQL: los ejemplos de este tutorial usan una amplia variedad debases de datos para ayudarnos a demostrar cómo se puede hacer programación JDBCindependiente de la base de datos.Un driver JDBC: como el API JDBC está predominantemente compuesto por interfaces,necesitamos obtener una implementación de un driver JDBC real para poder conectarrealmente con una base de datos usando JDBC. Si nuestra base de datos (o nuestra maleta) nopermite el uso de JDBC, siempre podemos usar el dirver puente JDBC-ODBC para conectar concualquier base de datos (o fuente de datos) que soporta el protocolo ODBC. Página 2 de 23
  3. 3. Manejar Conexiones a Bases de Datos con JDBC 3.0Arquitectura de la AplicaciónArquitecturar Nuestro SistemaUno de los problemas de diseño más importantes cuando desarrollamos una aplicación debases de datos en Java es la arquitectura general del sistema; en particular, cuántoscomponentes diferentes deberíamos desplegar. Tradicinonalmente, esto está caracterízado porel número de capas que requiere la aplicación. Hay dos modelos arquitecturales básicos quepueden describir un sistema: el modelo de dos capas y el modelo de n-capas.Antes de entrar en los detalles del manejo de conexiones a bases de datos desde una aplicaciónJava, necesitamos explicar estos dos modelos. Cada modelo tiene sus propias ventajas einconvenientes; cada uno también requiere que ciertos componentes se configurenapropiadamente, y , como resultado, cada uno funciona mejor en entornos diferentes. Las dossiguientes secciones explican en más detalle cada uno de los dos modelos arquitecturales.El Modelo de Dos CapasEl modelo de dos capas es el marco de trabajo tradicional cliente-servidor; tiene una capacliente y una capa servidor. Este modelo simple requiere que el cliente tenga cuidado específicode la base de datos. Así, por ejemplo, el cliente necesita código específico de la base de datosresultando en un acoplamiento fuerte entre las dos capas. Este acoplamiento fuerte tienesvarias ventajas. Primero, puede reducir el tiempo de desarrollo debido al hecho de que todo elsistema es considerablemente más simple y más pequeño. Segundo, el acoplamiento fuertepuede mejorar potencialmente el rendimiento del sistema ya que el cliente puede fácilmenteaprovecharse de las funcionalidades específicas del servidor que podrían no estar disponiblespara sistemas con un acoplamiento más ligero.Por otro lado, este acoplamiento fuerte puede provocar varios problemas. El mas notable, elmantenimiento del sistema se puede volver más díficil porque los cambios en el servidorpueden romper al cliente y viceversa. Además, si la base de datos cambia, todo el código delcliente deberá ser modificado. Si el cliente está altamente distribuido, la propagación de loscambios en el sistema puede ser díficil, y en algunos escenarios imposible. Como resultado, lasaplicaciones de dos capas pueden ser útiles en un entorno de LAN corporativa donde elcompleto control de todos los clientes se consigue, o al inicio, o en el estado prototipal de unproyecto donde diferentes opciones están siendo evaluadas.El Modelo de n-CapasEl modelo de n-capas tiene una capa cliente, al menos una capa servidor, y al menos una cadaintermedia. Debido a la capa extra, muchos de los problemas que afectan a los modelos de doscapas no afectarán. Por ejemplo, la capa media ahora mentiene información de la conexión a labase de datos. Esto significa que los clientes sólo tienen que conocer la capa media. Como lacapa media generalmente está operando en la misma localización física que el servidor (porejemplo, ambos componentes pueden estar detrás del mismo firewall), mantener la capa mediaes considerablemente más sencillo que mantener cientos de instalaciones clientes.Otra ventaja de la aproximación de n-capas es que todo el sistema se puede escalar fácilmentepara manejar más usuarios.Todo lo que necesitamos hacer es añadir más capas medias o máscapas servidores, dependiendo de los resultados de las operaciones de perfilado. Como lascapas intermedias normalmente se implementan usado servidores Web -- usando tecnologíasJavaServer Pages y Servlets -- es muy sencillo añadir balance de carga o incluso nuevoscomponentes hardware.Sin embargo, no todo es de color rosa, ya que la capa extra intoduce complejidad adicional entodo el sistema. Esto significa más código, más duro de probar y potencialmente más díficil deencontrar sus errores. Afortunadamente, el lenguaje Java proporciona muchos de loscomponentes necesarios, pre-construidos. para construir aplicaciones de n-capas viables.Además, este modelo se presta a si mismo el fácil soporte de autentificación einternacionalización, ya que la capa media controla el flujo de información y proporcionalocalización natural para manjear todo lo que concierne al manejo de seguridad y lalocalización. Página 3 de 23
  4. 4. Manejar Conexiones a Bases de Datos con JDBC 3.0Fundamentos de los Drivers JDBCIntroducción a los Drivers JDBCUna inspección casual del API JDBC muestra rápidamente la dominación de los interfacesdentro del API, lo que podría llevar al usuario a preguntarse dónde se realiza el trabajo.Realmente esta es sólo una aproximación que tocan los desarrolladores JDBC porque laimplementación real es la proporcionada por los vendedores de Drivers JDBC, que a su vezproporcionan las clases que implementan los interfaces necesarios. Esta aproximación presentala competición que proporciona al consumidor más opciones, y para la mayor parte, producemejor software. Con todos los drivers disponibles. elegir uno puede ser díficil.Aforturnadamente, Sun Microsystems mantiene una base de datos con más de 150 driversJDBC de una amplia variedad de vendedores. Esta debería ser la primera parada después deseleccionar una base de datos.Desde una perspectiva de programación, hay dos clases principales respnsables para elestablecimiento de una conexión con una base de datos. La primera clase es DriverManager,que es una de las clases que realmente proprociona el API JDBC. DriverManager es responsablede manejar un almacen de drivers registrados, esencialmente abstrayendo los detalles del usode un driver para que el programador no tenga que tratar con ellos directamente. La segundaclase es la clase real del Driver JDBC. Estas son proporcionadas por vendedores independientes.La clase Driver JDBC es la responsable de establecer la conexión con la base de datos y demanejar todas las comunicaciones con la base de datos. Los drivers JDBC vienen en cuatrotipos diferentesRegistrar un Driver JDBCEl primer paso en el proceso de crear una conexión entre una aplicación Java y una base dedatos es el registro de un driver JDBC con la Máquina Virtual Java (JVM) en la que se estáejecutando la aplicación Java. En el mecanimso de conexión tradicional (en oposición almecanismo de conexión del DataSource) la conexión y todas las comunicación con la base dedatos son controladas por un objeto DriverManager. Para establecer una conexión, se deberegistrar un driver JDBC adecuado para la base de datos objetivo con el objeto DriverManager.La especificación JDBC, dice que se supone que los dirvers JDBC se registran automáticamentea sí mismos con el objeto DriverManager cuando se cargan en la JVM. Por ejemplo, el siguientefragmento de código usa un inicializador estático para primero crear un ejemplar del driverJDBC persistentjava y luego resgistrarlo con el DriverManager:static { java.sql.DriverManager.registerDriver(new com.persistentjava.JdbcDriver()) ;}Registrar un driver es tan simple como cargar la clase del driver en la JVM, lo que puedehacerse de muchas maneras. Una forma es con el ClassLoaderClass.forName(com.persistentjava.JdbcDriver). Otro método, que no es tan bienconocido, usa la propidad del sistema jdbc.drivers. Este método se puede usar de tres formasdistintas:Desde la línea de comandos:java -Djdbc.drivers=com.persistentjava.JdbcDriver ConnectDentro de la palicación Java:System.setProperty("jdbc.drivers","com.persistentjava.JdbcDriver") ;Seleccionando la propiedad jdbc.drivers en el fichero de propiedades del sistema, quegeneralmente depende del sistema.Separando los drivers con una coma, se pueden registrar varios drivers usando la técnica de lapropiedad del sistema mostrada arriba. Uno de los beneficios de usar la técnica de la propiedaddel sistema es que se los drivers se pueden intercambiar fácilmente sin modificar ningún código(o al menos con unos mínimos cambios). Si se registran varios drivers, su orden de precedenciaes:Drivers JDBC registrados por la propiedad jdbc.drivers en la inicialización de la JVM, yDrivers JDBC cargados dinámicamente. Página 4 de 23
  5. 5. Manejar Conexiones a Bases de Datos con JDBC 3.0Como la propiedad jdbc.drivers sólo se chequea una vez durante la primera invocación delmétodo DriverManager(), es importante asegurarse de que todos los drivers están registradoscorrectamente antes de establecer la conexión con la base de datos. Sin embargo, no todas lasJVM están creadas igual, y algunas de ellas no siguen la especificación JVM. Como resultado,los inicializadores estáticos no siempre funcionan como hemos dibujado. Esto resulta enmúltiples formas de registrar un driver JDBC, incluyendo:Class.forName("com.persistentjava.JdbcDriver").newInstance();DriverManager.registerDriver(new com.persistentjava.JdbcDriver()) ;Estas alternativas deberían funcionar bien en todas las JVMs, por eso deberíamos sentirnosagusto usándolas a lo largo del amplio conjunto de JVM disponibles. Un problema final es queClass.forname() puede lanzar una ClassNotFoundException, por eso debemos envolver elcódigo de registro en un manejador de excepción apropiado.URLs de Drivers JDBCUna vez que un Driver JDBC se ha registrado con el DriverManager, puede usarse paraestablecer una conexión a una base de datos. ¿Pero cómo selecciona DriverManager el drivercorrecto, dado que puede haber realmente rigstrados cualquier número de drivers? (Recuerda,una sóla JVM podría soportar múltiples aplicaciones concurrentes, que podrían conectarse condiferentes bases de datos con diferentes drivers). La técnica es bastante simple: cada driverJDBC usa una URL JDBC específica (que tiene el mismo formato que una dirección Web) comoun significado de auto-identificación. El formato de la URL es correcto y probablemente parecefamiliar: jdbc:sub-protocol:database locator. El sub-protocol es específico del driver JDBC ypuede ser odbc, oracle, db2, etc., dependiendo del vendedor del driver real. El localizador dela base de datos es un indicador específico del driver para específicar de forma única la base dedatos con la que una aplicación quiere interactúar. Dependiendo del tipo de driver, estelocalizador incluye un nombre de host, un puerto, y un nombre de sistema de base de datos.Cuando se presenta con una URL específica, el DriverManager itera sobre la colección dedrivers registrados hasta que uno de ellos reconoce la URL específicada. Si no se encuentraningún driver adecuado, se lanza una SQLException. La siguiente lista presenta varios ejemplosespecíficos de URLs JDBC reales:jdbc:odbc:jdbcjdbc:oracle:thin:@persistentjava.com:1521:jdbc";jdbc:db2:jdbcMuchos drivers, incluyendo el driver puente JDBC-ODBC, acepta parámetros adicionales alfinal de la URL como un nombre de usuario y una password.El método para obtener una conexión a una base de datos, dando una URL JDBC específica, esllamar a getConnection() sobre el objeto DriverManager. Este método tiene varias formas:DriverManager.getConnection(url) ;DriverManager.getConnection(url, username, password) ;DriverManager.getConnection(url, dbproperties) ;Aquí url es un objeto String que es la URL JDBC, username y password son objetos String querepresentan el nombre de usuario y la password que la aplicación JDBC debería usar paraconectar con la fuente de datos; y dbproperties es un objeto Properties de Java que encapsulatodos los parámetros (posiblemente incluyendo nombre de usuario y la password) que requiereun driver JDBC para hacer una conexión con éxito. Ahora que tenemos el driver básico en lamano, podemos examinar los tipos de drivers individuales con más detalle: Página 5 de 23
  6. 6. Manejar Conexiones a Bases de Datos con JDBC 3.0Drivers del Tipo 1Los drivers del tipo uno tienen algo en común: todos usan el puente JDBC-ODBC, que estáincluido como parte estándard del JDK. Los drivers del tipo uno son diferentes al driver ODBC(Open DataBase Connectivity) adjunto al puente JDBC-ODBC. Para conectar con una fuentede datos diferente, simplemente tenemos que registrar (o unir efectivamente) una fuente dedatos ODBC diferente, usando el Administrador ODBC, al nombre de la fuente de datosapropiada.Como ODBC se ha estado utilizando desde hace bastante tiempo (más que el lenguaje Java),los drivers ODBC son ubicuos. Esto hace de este tipo de drivers una buena elección paraaprender cómo conectar programas Java a bases de datos. De hecho, incluso hay drivers ODBCque nos permiten asignar fuentes de datos ODBC a una aplicación Microsoft Excel o ficheros detexto plano. Sin embargo, el nivel extra de indirección, puede resultar en una pérdida derendimiento ya que el JDBC es transferido dentro de ODBC, que luego es transferido en elprotocolo específico de la base de datos.Otro problema potencial de los drivers del tipo uno es su utilización en aplicaciones distribuidas.Como el propio puente no soporta comunicación distribuida, la única forma de que los driversdel tipo uno puedan trabajar a través de la red es si el propio driver ODBC soporta interacciónremota. Para drivers ODBC sencillos, esta no es una opción, y mientras que las grandes basesde datos tienen drivers ODBC que pueden trabajar de forma remota, no pueden competir con elmejor rendimiento de los drivers JDBC puro Java. Página 6 de 23
  7. 7. Manejar Conexiones a Bases de Datos con JDBC 3.0Codificación para Drivers del Tipo 1El nombre de clase para el driver puente JDBC-ODBC es sun.jdbc.odbc.JdbcOdbcDriver y alURL JDBC toma la forma jdbc:odbc:dsn, donde dsn es el Data Source Name (nombre de lafuente de datos) usado para registrar la base de datos con el Administrador ADBC. Por ejemplo,si una base de datos se registra con una fuente de datos ODBC llamada jdbc; un nombre deusuario de java y una password de sun, se puede usar el siguiente fragmento de código paraestablecer una conexión. Nota: En interés de la claridad y la brevedad, se ha eliminado del listado el chequeo y manejo de errores. Posteriores ejemplos, demostrarán la importancia de estos mecanismos (específicamente, la captura de errores encadenando sentencias SQLException).String url = "jdbc:odbc:jdbc" ;Connection con ;try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver") ;} catch(java.lang.ClassNotFoundException e) { System.err.print("ClassNotFoundException: ") ; System.err.println(e.getMessage()) ; return ;}try { con = DriverManager.getConnection(url, "java", "sun");} catch(SQLException ex) { System.err.println("SQLException: " + ex.getMessage());} finally { try{ con.close ; } catch(SQLException ex) { System.err.println(SQLException: " + ex.getMessage()) ; }} Página 7 de 23
  8. 8. Manejar Conexiones a Bases de Datos con JDBC 3.0Drivers del Tipo 2Los drivers del tipo dos también son conocidos como drivers Java parciales, porque traducendirectamente el API JDBC en un API específico de la base de datos. La aplicación cliente debase de datos (para el propóstio de este tutorial, el host que está ejecutando la JVM) debetener las librerías cliente apropiadas para la base de datos, que podrían incluir código binarioinstalado y posiblemente ejecutándose. Para una aplicación distribuida, este requerimietnopuede introducir problemas extra con las licencias, así como posibles pesadillas con losproblemas de distribución de código. Por ejemplo, usar un modelo del tipo dos restringe a losdesarrolladores a utilizar plataformas y sistemas operativos soportados por la librería cliente dela base de datos.Sin embargo, este modelo puede funcionar eficientemente, cuando la base cliente estáfuertemente controlada.. Esto ocurre típicamente en LANs corporativas. Un ejemplo de driverdel tipo dos es el driver de aplicación JDBC para DB2. El siguiente ejemplo demuestra cómoestablecer una conexión usando un driver DB2:String url = "jdbc:db2:jdbc" ;try { Class.forName("COM.ibm.db2.jdbc.app.DB2Driver") ;} catch(java.lang.ClassNotFoundException e) { System.err.print("ClassNotFoundException: ") ; System.err.println(e.getMessage()) ; return ;}...Observa la similitud que tiene este fragmento de código con el del ejemplo 1. Esta es laprincipal característica del modelo del tipo 2: la curva de aprendizaje para un programador quese mueve de un modelo a otro es prácticamente inexistente.Los dos últimos tipos de drivers son drivers puro Java. El beneficio de los drivers puro Java essu fácil despliegue en entonos altamente distribuidos. Página 8 de 23
  9. 9. Manejar Conexiones a Bases de Datos con JDBC 3.0Drivers del Tipo 3Los drivers del tipo tres son drivers puro Java que transforman el API JDBC en un protocoloindependiente de la base de datos. El driver JDBC no comunica directamente con la base dedatos; comunica con un servidor de capa media, que a su vez comunica con la base de datos.Este nivel extra de indirección proporciona flexibilidad en que se puede acceder a diferentesbases de datos desde el mismo código porque el servidor de la capa media oculta lasespecificidades a la aplicación Java. Para cambiar a una base de datos diferente, sólonecesitamos cambiar los parámetros en el servidor de la capa media. (Un punto a observar: elformato de la base de datos a la que estamos accediendo debe ser soportado por el servidor dela capa media).El lado negativo de los drivers del tipo tres es que el nivel extra de indirección puede perjudicarel rendimiento general del sistema. Por otro lado, si una aplicación necesita interactúar con unavariedad de formatos de bases de datos, un driver del tipo tres en una aproximación adecuadadebido al hecho de que se usa el mismo driver JDBC sin importar la base de datos subyacente.Además, como el servidor de la capa media se puede instalar sobre una plataforma hardwareespecífica, se pueden realizar ciertas optimizaciones para capitalizar los resultados perfilados. Página 9 de 23
  10. 10. Manejar Conexiones a Bases de Datos con JDBC 3.0Drivers del Tipo 4Los drivers del tipo cuatro son drivers puro Java que se comunican directamente con la base dedatos. Muchos programadores consideran éste el mejor tipo de driver, ya que normalmenteproporciona un rendimiento óptimo y permite al desarrollador utilizar las funcionalidadesespecíficas de la base de datos. Por supuesto este acoplamiento puede reducir la flexibilidad,especialmente si necesitamos cambiar la base de datos subyacente en una aplicación. Este tipode driver se usa frecuentemente en applets y otras aplicaciones altamente distribuidas. Elsiguiente fragmento de código muestra cómo usar un driver DB2 del tipo cuatro:String url = "jdbc:db2://persistentjava.com:50000/jdbc" ;try { Class.forName("COM.ibm.db2.jdbc.net.DB2Driver") ;} catch(java.lang.ClassNotFoundException e) { System.err.print("ClassNotFoundException: ") ; System.err.println(e.getMessage()) ; return ;}... Página 10 de 23
  11. 11. Manejar Conexiones a Bases de Datos con JDBC 3.0Un Ejemplo Completo de Driver del Tipo 4El siguiente ejemplo muestra cómo usar un driver JDBC de un vendedor de terceras partes, eneste caso Merant, para conectar con una base de datos DB2. DB2 UDB requiere informaciónadicional, no estándard para establecer la conexión a la base de datos, que en este ejemploestán añadidos a la URL JDBC como parámetros opcionales.package com.persistentjava;import java.sql.*;public class ConnectMerantDB2 { static { try { Class.forName("com.merant.datadirect.jdbc.db2.DB2Driver").newInstance(); } catch (Exception e) { System.out.println(e); } }public static void main(String args[]) { String url = "jdbc:merant:db2://persistentjava.com:50000;" ; url += "DatabaseName=jdbc;CollectionId=DEFAULT;" ; url += "PackageName=JDBCPKG;CreateDefaultPackage=TRUE"; Connection con; System.out.println("Connecting"); try { con = DriverManager.getConnection(url, "java", "sun"); System.out.println("Connection Established"); con.close(); // In this example, the proper handling of SQLExceptions is // demonstrated as they can be potentially chained. } catch (SQLException e) { System.out.println("nERROR:----- SQLException -----n"); while (e != null) { System.out.println("Message: " + e.getMessage()); System.out.println("SQLState: " + e.getSQLState()); System.out.println("ErrorCode: " + e.getErrorCode()); e.printStackTrace(); e = e.getNextException(); } } }} Página 11 de 23
  12. 12. Manejar Conexiones a Bases de Datos con JDBC 3.0Transaciones con Bases de DatosTransaciones BásicasUno concepto que causa problemas a los principiantes en el mundo del desarrollo deaplicaciones de base de datos es la idea de transaciones. Fundamentalmente, una transaciónrepresenta una unidad de trabajo lógica. Como la principal responsabilidad de una base dedatos es preservar la información, necesita tener algo que le indique a un usuario que se debesalvar el estado actual del programa. De igual forma, cuando las cosas han ido mal, necesitauna forma para indicar que una base de datos deberia ignorar el estado actual y volver a atrás,al estado del programa salvado anteriormente.En el idioma de las bases de datos, estas funciones se llaman entregar una transación ydeshacer una transación, respectivamente. Para realizar estas tareas, el API JDBC incluyedos métodos como parte del interface Connection. Dando un objeto Connection llamado con, elestado del programa se graba llamando a con.commit(), para volver al estado salvadoanteriormente, con.rollback(). Estos dos métodos pueden lanzar SQLExceptions si algo vamal cuando la base de datos realice realmente la operación, por eso necesitamos envolverlosen bloques try ... catch.Más sobre TransacionesEn un entorno mono-usuairo, las transaciones son bastantes sencillas de entender --simplemente implican salvar o deshacer el estado de una aplicación. Sin embargo, en modomulti-usuario, las transaciones son más complejas. La demostración clásica de una transaciónmulti-usuario es una cuenta bancaria donde una aplicación está intentando hacer un cargomientras otra aplicación está intentando hacer un depósito en la misma cuenta. Si estasfamiliarizado con la programación concurrente (también conocida como programación multi-thread), probablemente hayas visto este problema antes. El problema fundamental es que amenos que las dos transaciones estén aisladas la una de la otra, una aplicación podríainterrumpir a la otra resultando en un estado del programa incorrecto. En nuestra sencillademostración, esto podría significar una cuenta con un saldo erróneo, algo que no esprecisamente bueno para retener clientes.Pueden aparecer tres problemas comunes cuando tratamos con varios usuarios que acceden alos mismos datos:Lecturas sucias. Un lectura sucia ocurre cuando una aplicación usa datos que han sidomodificados por otra aplicación, y esos datos están en un estado sin entregar. La segundaaplicación entonces solicita que los datos que fueron modificados sean desechos. Entonces losdatos de la primera transación están corruptos o "sucios".Lecturas no-repetibles. Una lectura no-repetible ocurre cuando una transación obtienedatos, que posteriormente son alterados por una transación separada, y la primera transaciónre-lee los datos ahora alterados. Así, la primera transación hizo una lectura no-repetible.Lecturas fantasmas. Una lectura fantasma ocurre cuando una transación adquiere datosmediante alguna consulta, otra transación modifica algunos de los datos, y la transación originalrecupera los datos una segunda vez. La primera transación ahora tendrá un conjunto deresultados diferentes, que podrían contener datos fantasmas.Niveles de TransaciónPara resolver los problemas asociados a múltiples threads solicitando los mismos datos, lastransaciones están aisladas unas de otras por bloqueos. La mayoría de las bases de datossoportan diferentes tipos de bloqueo; por lo tanto, el API JDBC soporta diferentes tipos detransaciones, que son asignadas o determinadas por el objeto Connection. En el API JDBC tienedisponibles los siguientes niveles de transaciones:TRANSACTION_NONE indica que las transaciones no están soportadas.TRANSACTION_READ_UNCOMMITTED indica que una transación puede ver los cambios de otratransación antes de ser entregada. Así están permitidas las lecturas sucias, las lecturas no-repetibles, y las lecturas fantasmas. Página 12 de 23
  13. 13. Manejar Conexiones a Bases de Datos con JDBC 3.0TRANSACTION_READ_COMMITTED indica que la lectura de datos no entregados, no estápermitida. Este nivel todavía permite que ocurran las lecturas no-repetibles y las lecturasfantasmas.TRANSACTION_REPEATABLE_READ indica que una transación está garantizada que pueda re-leer el mismo dato sin fallar, pero las lecturas fantasmas todavía pueden ocurrir.TRANSACTION_SERIALIZABLE es la transación de más alto nivel y evita que ocurran laslecturas sucias, las lecturas no-repetibles y las lecturas fantasmas. Podríamos preguntarnosporqué todas las transaciones no operan en modo TRANSACTION_SERIALIZABLE paragarantizar el grado más alto de integridad de datos. El problema es, de forma similar a losproblemas implicados con el manejo de la programación de múltiples threads, que cuanto mássea el nivel de protección de transación, más alta será la pérdida de rendimiento.Dando un objeto Connection podemos seleccionar explícitamente el nivel de transación,asumiendo que nuestra base de datos y nuestro driver JDBC soporten esta característica:con.setTransactionLevel(TRANSACTION_SERIALIZABLE) ;También podemos determinar el nivel de transación actual:if(con.getTransactionLevel() == TRANSACTION_SERIALIZABLE) System.out.println("Highest Transaction Level in operation.") ;Lotes y TransacionesPor defecto, los drivers JDBC operan en lo que se llama modo autoentrega. En este modo,todos los comandos enviados a la base de datos operan en su propia transación. Aunque estopuede ser útil para los principiantes, implica una pérdida de rendimiento porque lastransaciones requieren una cierta cantidad de sobrecarga para configurar todo apropiadamente.Si queremos poder controlar explícitamente las entregas y los retrocesos (deshacer latransación), necesitamos desactivar el modo autocommit:con.setAutoCommit(false) ;También podemos determinar rápidamente el modo autocommit de un objeto Connection dado:if(con.getAutoCommit() == true) System.out.println("Auto Commit mode");Muchas bases de datos soportan lotes, en los que se minimiza la sobrecarga de transacionesrealizando múltiples operaciones update de la base de datos en una sóla operación, o lote. Lasoperaciones por lotes fueron introducidas en JDBC 2.0 y requieren que una transación no estéen modo autocommit. En el siguiente ejemplo tenemos una operación por lotes, que asume queexiste una Connection a una base de datos que tiene una sola tabla:con.setAutoCommit(false) ;Statement stmt = connection.createStatement() ;stmt.addBatch("INSERT INTO people VALUES(Joe Jackson, 0.325, 25, 105) ;stmt.addBatch("INSERT INTO people VALUES(Jim Jackson, 0.349, 18, 99) ;stmt.addBatch("INSERT INTO people VALUES(Jack Jackson, 0.295, 15, 84) ;int[] updateCounts = stmt.executeBatch() ;con.commit() ;Observa que el método executeBatch() devuelve un array de cuentas actualizadas, una porcada operación del lote. Un último problema con las operaciones por lotes es que pueden lanzaruna nueva excepción del tipo BatchUpdateException, lo que indica que falló al menos uno delos comandos del lote. Por eso, necesitamos añadir un manejador de excepcionescorrespondiente a nuestras operaciones por lotes.Control Fino de las TransacionesEmpezando con el API JDBC 3.0, se añadió un nuevo elemento interface relacionado con lastransaciones. Este interface presenta el concepto de savepoints. Los Savepoints proporcionanun marca dentro de una aplicación de base de datos que puede usarse como un argumentocuando se llama al método rollback. Como resultado, usando el API JDBC 3.0, ahora es posibleseleccionar un savepoint antes de empezar una interacción complicada con la base de datos y,dependiendo del resultado, entregar la transación completa o deshacer hasta el savepoint ydevolver la aplicación a un punto conocido. Página 13 de 23
  14. 14. Manejar Conexiones a Bases de Datos con JDBC 3.0Para seleccionar un punto de salvado, creamos un objeto Savepoint desde el objetoConnection, como se ve aquí:Savepoint svpt = con.setSavepoint("Savepoint") ;Para deshacer hasta un Savepoint dado, simplemente le pasamos el objeto Savepoint deseadoal método rollback:con.rollback(svpt) ;Cuando no se necesitan más, liberamos todos los objetos Savepoint para liberar los carosrecursos de la base de datos para otros usuarios:con.releaseSavepoint(svpt) ;Observa que cuando entregamos o deshacemos una transación, cualquier Savepoints creadopodría convertirse en inválido dependiendo del orden exacto y del tipo de operación. Puedesver la especificación del API JDBC 3.0 o el manual de tu driver para más información. Página 14 de 23
  15. 15. Manejar Conexiones a Bases de Datos con JDBC 3.0Fuentes de DatosFuentes de Datos BásicasUno de los principales benficios de usar el API JDBC es facilitar una programaciónindependiente de la base de datos, así la mayoría de las aplicaciones JDBC pueden transferirsefácilmente a otra base de datos diferente. Sin embargo, todavía hay dos ítems que permacenenunidos a una base de datos particular, la clase JDBC Driver y la URL JDBC. Con la introduciónde las fuentes de datos en el API JDBC 2.0, se eliminaron incluso estas dependencias.Esencialmente un objeto DataSource representa una fuente de datos particular en unaaplicación Java. Además de encapsular la información específica de la base de datos y del driverJDBC en un sólo objeto estándarizado, las fuentes de datos pueden actuar como una factoríade Connection y proporcionar métodos para seleccionar y obtener propiedades particulares querequiere el objeto DataSource para una operación satisfactoria. Algunas propiedades estándarque podría requerir un objeto DataSource incluyen: ·databaseName ·serverName ·portNumber ·userName ·passwordUn beneficio adicional de usar una DataSource, que podrías haber adivinado de la lista anterior,es que la información sensible relacionada con la seguridad como el nombre de usuario, lapassword, e incluso el servidor de la base de datos están códificados sólo en un lugar, lo quepuede hacer un administrador de sistemas. Mientras que la interacción con un objetoDataSource se puede hacer con una aplicación gráfica, es instructivo ver como trabajanrealmente los ejemplos. Aunque los conceptos de un objeto DataSource son bastantes simples,para usarlo dentro de una aplicación Java, un objeto DataSource es referenciado usando JavaNaming and Directory Interface, o JNDI. Antes de saltar dentro del código de ejemplo deDataSource, el siguiente punto presenta conceptos relevantes de JNDI que son necesarios parausar apropiadamente un objeto DataSource.Repaso Rápido de JNDIJNDI es un API Java que encapsula el concepto de servidores de nombres y directorios de lamisma forma que JDBC encapsula los conceptos que hay detrás de la comunicación con unabase de datos. Aunque podría parecer confuso, es bastante sencillo -- todos lo usuarios deordenadores usan servicios de nombres y directorios todos los días. Por ejempo, los discosduros trabajan con pistas y sectores, aunque un usuario sólo se preocupa de nombres deficheros y directorios. El sistema de ficheros maneja el servicio de nombrado que asocia unnombre de fichero dado con una localización específica en el disco duro. Otro ejemplo es laWeb, donde la mayoría de los usuarios sólo se preocupan del nombre de la Web site, comowww.persistentjava.com, y no de la dirección IP subyacente. Sin embargo, la comunicaciónTCP/IP se hace usando la dirección IP y no usando el nombre que leemos los humanos. Latransformación entre las dos representaciones la realiza el DNS, o Domain Name System.Aunque JDNI proporciona un API ámplio y útil por sí mismo, nuestras necesidades sonconsiderablemente simples. En breve, necesitamos conocer como hacer cuatro cosas: ·Crear un nombre y unirlo a un objeto Java. ·Buscar un nombre para recuperar un objeto Java. ·Borrar un nombre. ·Re-unir un nombre a nuevo objeto Java.En vez de proporcionar ejemplos JNDI imaginarios para las tareas anteriores, las siguientessecciones muestran ejemplos de estas tareas usando fuentes de datos JDBC. Todos estosejemplos usan el proveedor de sistema de ficheros, que es una descarga separada. Página 15 de 23
  16. 16. Manejar Conexiones a Bases de Datos con JDBC 3.0Registrar una Fuente de DatosEste ejemplo es una implementación de un DataSource de tereceras partes de i-net softwarepara conectar con una base de datos MS SQL Server. Los comentarios en el código marcan lospuntos importantes de registro (o inicialziación) de una fuente de datos JDBC:// We need to import the actual DataSource implementationimport com.inet.tds.TdsDataSource;import java.util.Hashtable;import javax.naming.*;import javax.naming.directory.*;import java.sql.* ;import javax.sql.* ;public class InitializeJNDI { // First we define the relevant parameters for this datasource private String serverName = "persistentjava.com"; private int portNumber = 1433; private String login = "java"; private String password = "sun"; private String databaseName = "jdbc"; // This is the name we will assign to our datasource. Because we are // using the file system provider, our name follows the file system // naming rules. The JNDI reserved subcontext for JDBC applications is // jdbc, thus our name starts appropriately. private String filePath = "jdbc/pjtutorial"; public InitializeJNDI() { // To pass in the necessary parameters, we need to create and then // populate a Hashtable. Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory"); try { // Create the initial context Context ctx = new InitialContext(env); // Here we create the actual DataSource and then set the relevant // parameters. TdsDataSource ds = new TdsDataSource(); ds.setServerName(serverName); ds.setPortNumber(portNumber); ds.setDatabaseName(databaseName); ds.setUser(login); ds.setPassword(password); ds.setDescription("JDBC DataSource Connection"); // Now we bind the DataSource object to the name we selected earlier. ctx.bind(filePath, ds); ctx.close(); // Generic Exception handler, in practice, this would be replaced by an // appropriate Exception handling hierarchy. } catch (Exception ex) { System.err.println("ERROR: " + ex.getMessage()); } } public static void main(String args[]) { new InitializeJNDI(); }} Página 16 de 23
  17. 17. Manejar Conexiones a Bases de Datos con JDBC 3.0Usar una Fuente de DatosEl ejemplo anterior establece la relación de unión entre el objeto DataSource y un nombreparticular. La mágia de JNDI realmente la realiza el proveedor de servicio apropiado. En nuestrocaso, usamos el proveedor del sistema de ficheros. Existen otras opciones, incluyendo LDAP(Lightweight Directory Access Protocol) o incluso un DNS. Para hacer realmente una conexión,necesitamos buscar el objeto DataSource usando el nombre al que fue unido. Observa en elsiguiente ejemplo que no hay ningún código específico de base de datos en ningún lugar:import java.util.Hashtable ;import javax.naming.* ;import java.sql.* ;import javax.sql.* ;public class UtilizeJNDI { public UtilizeJNDI(){ try { // We need to set up the JNDI context so that we can properly interface // to the correct service provider, in this case the file system. Hashtable env = new Hashtable() ; env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory") ; Context ctx = new InitialContext(env) ; // Given the JNDI Context, we lookup the object and are returned // our DataSource DataSource ds = (DataSource)ctx.lookup("jdbc/pjtutorial") ; // Now we get a database connection and proceed to do our job. Connection con = ds.getConnection() ; System.out.println("Connection Established.") ; con.close(); // Note that proper error handling is not included here in order to keep // the example short. }catch(Exception e ) { e.printStackTrace(); } } public static void main (String args[]){ new UtilizeJNDI() ; }} Página 17 de 23
  18. 18. Manejar Conexiones a Bases de Datos con JDBC 3.0Re-Unir una Fuente de DatosCuando queremos cambiar la base de datos particular o incluso el vendedor del DataSourceJDBC con el que queremos que comunique nuestro código, todo lo que necesitamos hacer esre-unir un nuevo DataSource al nombre original. En este ejemplo, usamos el mismo driver, perocambiamos varios parámetros relevantes:// We need to import the actual DataSourceimport com.inet.tds.TdsDataSource;import java.util.Hashtable;import javax.naming.*;import javax.naming.directory.*;import java.sql.* ;import javax.sql.* ;public class InitializeJNDI { // First we define the relevant parameters for this datasource private String serverName = "persistentjava.com"; private int portNumber = 1434; // Note the new port number private String login = "sun"; // New username/password combination private String password = "java"; private String databaseName = "ds"; // And even a new database name. // We keep the same name for our datasource, just bind a new DataSource // to it. private String filePath = "jdbc/pjtutorial"; public InitializeJNDI() { // Establish the proper JNDI Context Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory"); try { // Create the context Context ctx = new InitialContext(env); TdsDataSource ds = new TdsDataSource(); ds.setServerName(serverName); ds.setPortNumber(portNumber); ds.setDatabaseName(databaseName); ds.setUser(login); ds.setPassword(password); ds.setDescription("JDBC DataSource Connection, take two"); // Now we just call the rebind method with the new DataSource. ctx.rebind(filePath, ds); ctx.close(); // Replace this with real Exception handlers in production code. } catch (Exception ex) { System.err.println("ERROR: " + ex.getMessage()); } } public static void main(String args[]) { new InitializeJNDI(); }} Página 18 de 23
  19. 19. Manejar Conexiones a Bases de Datos con JDBC 3.0Borrar una Fuente de DatosAlgunas veces, querremos borrar un nombre de DataSource para que no pueda volver a serusado:import java.util.Hashtable ;import javax.naming.* ;import java.sql.* ;import javax.sql.* ;public class DeleteJNDI { public DeleteJNDI() { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory"); try { Context ctx = new InitialContext(env); // unbinding the name object association effectively deletes the object. ctx.unbind("jdbc/pjtutorial") ; ctx.close() ; }catch (Exception ex) { System.err.println("ERROR: " + ex.getMessage()) ; } } public static void main (String args[]){ new DeleteJNDI() ; }} Página 19 de 23
  20. 20. Manejar Conexiones a Bases de Datos con JDBC 3.0Almacenes de Conexiones¿Por qué necesitamos Almacenes de ConexionesCuando usamos el DriverManager o el método DataSource para obtener conexiones a bases dedatos, cada solicitud para una nueva conexión implica una sobrecarga significante. Esto puedeimpactar en el rendimiento si la obtención de nuevas conexiones ocurre con cierta frecuencia,como podría ser el caso en un entorno de servidor Web. Para enfatizar por qué esto es cierto,sigamos un camino potencial de una solicitud de conexión típica con una base de datos:La aplicación Java llama a getConnection().El código del vendedor JDBC (la implementación del driver o del DataSource) solicita unaconexión socket desde la JVM.La JVM necesita chequear los aspectos de seguridad de la llamada potencial. Por ejemplo, losapplets sólo se pueden comunicar con el servidor del que son originarios.Si lo aprueba, la llamada necesita pasar a través del interface de red del host hasta la LANcorporativa.La llamada podría necesitar pasar a través de un cortafuegos para alcanzar Internet o unaWAN.La llamada alcanza eventualmente su subred de destino, donde podría necesitar pasar a travésde otro cortafuegos.La llamada alcanza el host de la base de datos.El servidor de base de datos procesa la solicitud de la nueva conexión.Se podría necesitar requerir la licencia del servidor para determinar si hay una licenciaapropiada disponible.La base de datos inicializa una nueva conexión cliente, incluyendo toda las sobrecargas dememoria y sistema operativo.La llamada de retorno es enviada de vuelta al cliente JDBC (donde tiene que pasar por todoslos cortafuegos y routers).La JVM recibe la llamada de retorno y crea un objeto Connection apropiado.La aplicación Java recibe el objeto Connection.Claramente, solicitar un nuevo objeto Connection presenta una gran sobrecarga y muchospuntos de fallo potenciales. Para minimizar esta sobrecarga, ¿por qué no reutilizar conexiones abases de datos en vez de borrarlas cuando hayamos terminado con ellas? Los diseñadores deJDBC usaron este patrón de diseño popular cuando crearon el ConnectionPoolDataSource, quenos permite crear un almacen de conexiones a bases de datos que son reutilizadas en vez deeliminarlas cuando se cierran.¿Qué es una PooledConnection?Una PooledConnection es un tipo especial de conexión a base de datos que no se borra cuandose cierra, al contrario que los objetos Connection normales (el recolector de basura puedeborrar las conexiones normales una vez que ya no son referenciadas). En en vez de esto, laPooledConnection es almacenada para una reutilización posterior, produciendo potencialmenteuna gran mejora del rendimiento. Trabajar con un almacen de conexiones a bases de datos escasi idéntico a trabajar con objetos DataSource. Primero, en vez de crear un ejemplar de unaclase que implemente el interface DataSource, creamos un ejemplar de una clase queimplemente ConnectionPoolDataSource. Podemos usar JDNI para unir esta nueva fuente dedatos a un nombe como antes.Para usar realmente un objeto de fuente de datos almacenado, llamamos agetPooledConnection() sobre el ConnectionPooledDataSource, que a su vez establececonexiones con la base de datos. Para crear un objeto Connection que será usado, llamamos agetConnection() sobre el objeto PooledConnection en vez sobre los objetos DriverManager oDataSource como antes. Un beneficio adicional de esta aproximación es que es mucho más fácilmanejar varios conjuntos de conexiones a bases de datos con un ConnectionPool porque éltiene cuidado automáticamente. Esta automatización puede ser muy importante si nuestralicencias de cliente limitan el número de clientes que pueden conectarse simultáneamente a la Página 20 de 23
  21. 21. Manejar Conexiones a Bases de Datos con JDBC 3.0base de datos. El proceso completo es mucho más sencillo de lo que suena, como muestran lossiguientes ejemplos.Inicialiar un Almacen de ConexionesEn este ejemplo, usamos una base de datos mSQL y el driver JDBC de código abierto mSQLpara crear un PooledDataSource. Todo el código específico de la base de datos está contenidoen los procesos de inicialización o de unión.// First we import the relevant packageimport com.imaginary.sql.msql.* ;import java.util.Hashtable ;import javax.naming.* ;public class InitializeJNDI { private String serverName = "localhost" ; private String databaseName = "jdbc" ; private String userName = "java" ; private String password = "sun" ; // The appropriate JNDI subcontext for PooledDataSources is jdbcpool private String filePath = "jdbcPool/pjtutorial" ; private int portNumber = 1114 ; private int poolSize= 10 ; // We want to create a pool with 10 connections. public InitializeJNDI() { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory"); try { Context ctx = new InitialContext(env); // Create the PooledDataSource and set the relevant parameters. MsqlPooledDataSource ds = new MsqlPooledDataSource() ; ds.setServerName(serverName) ; ds.setPort(portNumber) ; ds.setDatabaseName(databaseName) ; ds.setUser(userName) ; ds.setPassword(password) ; ds.setMaxPoolSize(poolSize) ; // Bind the name and the DataSource object together ctx.bind(filePath, ds) ; ctx.close() ; } catch (Exception ex) { System.err.println("ERROR: " + ex.getMessage()) ; } } public static void main (String args[]){ new InitializeJNDI() ; }} Página 21 de 23
  22. 22. Manejar Conexiones a Bases de Datos con JDBC 3.0Usar un Almacen de ConexionesUna vez que hemos inicializado el PooledDataSource, ahora podemos usarlo en aplicacionesJava para crear almacenes de conexiones a bases de datos. El siguiente ejemplo, es imaginario,pero efectivamente demuestra los puntos importantes. Un ejemplo más realista podría ser unservlet, que configuraría el almacen de conexiones en el método init() del servlet y(re-)utilizaría la conexión por cada nueva solicitud del servicio:import java.util.Hashtable ;import javax.naming.* ;import java.sql.* ;import javax.sql.* ;public class UtilizeJNDI { public UtilizeJNDI(){ try { Hashtable env = new Hashtable() ; env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory") ; Context ctx = new InitialContext(env) ; // Look up the DataSource given the appropriate name. ConnectionPoolDataSource ds = (ConnectionPoolDataSource)ctx.lookup("jdbcPool/pjtutorial") ; // A PooledConnection provides a special Connection which is not // destroyed when it is closed, but is instead placed back into the // pool of connections. PooledConnection pcon = ds.getPooledConnection() ; Connection con = pcon.getConnection() ; System.out.println("Connection Established") ; con.close(); } catch(Exception e ) { e.printStackTrace(); } } public static void main (String args[]){ new UtilizeJNDI() ; }} Página 22 de 23
  23. 23. Manejar Conexiones a Bases de Datos con JDBC 3.0Optimizar las Comunicaciones con Bases de DatosMétodos JDBC DataSource y DriverEsta sección ecplia algunos de los métodos menos conocidos del API JDBC que pueden serutilizados para mejorar el rendimiento del sistema. Primero, todas las clases de fuentes dedatos JDBC, el Driver , el DataSource, o el ConnectionPooledDataSource, proporcionan lahabilidad de designar explícitamente un stream de salida del tipo caracter, setLogWriter(). Estestream acepta todos los logs y mensajes de seguimiento. También hay un método disponiblepara obtener el stream actual, getLogWriter(). Este puede ser extremadamente valioso cuandointentamos diagnosticar extraños bugs o para seguir el flujo de la aplicación. Además, todas lasclases de fuentes de datos JDBc proporcionan un medio para asignar (setLoginTimeout()) uobtener (getLoginTimeout()) la cantidad de tiempo máxima que la clase de fuente de datosdebería esperar a que se estalezca una conexión.Una clase interesante y rara vez utilizada es la clase DriverPropertyInfo. Esta clase encapsulatoda la información de propiedades que necesita un driver para establecer una conexión a unabase de datos. DriverPropertyInfo puede usarse en una herramienta gráfica para encontrarinteractivamente los parámetros que un driver necesita y pedirle al usuario de la base de datoslos valores correctos.Métodos JDBC ConnectionUn objeto Connection o PooledConnection también tienen varios métodos que se puedenutilizar para mejorar el rendimiento del sistema, tanto directa como indirectamente. Primero,asumiendo que el driver JDBC y la base de datos subyacente lo soportan, un objeto connectionse puede configurar para ser de sólo lectura, setReadOnly(). Esto puede mejorar el rendimientodel sistema para aplicaciones que no necesitan hacer cambios en la base de datos, ya que labase de datos no necesita preocuparse de almacenar nuevas páginas, mantener entradas dediario, o adquirir bloqueos de escritura sobre cualquiera de los datos.Otros métodos que están relacioandos de alguna forma son setAutoCommit() ysetTransactionIsolation(). Como el descontrol de las transaciones puede causar grandespérdidas de rendimiento en la base de datos, estos métodos métodos y sus efecto deberían serclaramente entenedidos y cuidadosamente aplicados.Finalmente, un último y frecuentemente olvidado método es nativeSQL(), que taduce unaconsulta SQL dada en el lenguaje de consulta nativo de la base de datos subyacente.Examinando la versión nativa SQL de nuestra consulta, podriamos entender mejor cómo la basede datos está intepretando nuestra consulta, y entonces hacer las modificaciones adecuadas anuestra aplicación para mejorar el rendimiento general. Página 23 de 23

×