Está en la página 1de 54

JDBC Anterior | Siguiente 1. JDBC 2. Bases de Datos 3.

Conectividad JDBC Acceso de JDBC a Bases de Datos Modelo de 2 Capas Modelo de 3 Capas Tipos de Drivers Puente JDBC-ODBC Java Binario 100% Java / Protocolo Nativo 100% Java / Protocolo Independiente 4. Primera Aproximacin a JDBC 5. Transacciones 6. Informacin de la Base de Datos 7. Tipos SQL en Java 8. Modelo Relacional de Objetos 9. Modelo de Conexin 10.JDBC y Servlets 11. Introduccin a SQL El Modelo Relacional Creacin de Tablas Recuperar Informacin Almacenar Informacin 12.Cdigo Independiente y Portable Cap.Anterior | Cap.Siguiente

JDBC (Java DataBase Connectivity) es un API de Java que permite al programador ejecutar instrucciones en lenguaje estndar de acceso a Bases de Datos, SQL (Structured Query Language, lenguaje estructurado de consultas), que es un lenguaje de muy alto nivel que permite crear, examinar, manipular y gestionar Bases de Datos relacionales. Para que una aplicacin pueda hacer operaciones en una Base de Datos, ha de tener una conexin con ella, que se establece a travs de un driver, que convierte el lenguaje de alto nivel a sentencias de Base de Datos. Es decir, las tres acciones principales que realizar JDBC son las de establecer la conexin a una base de datos, ya sea remota o no; enviar sentencias SQL a esa base de datos y, en tercer lugar, procesar los resultados obtenidos de la base de datos. Bases de Datos Anterior | Siguiente Una Base de Datos es una serie de tablas que contienen informacin ordenada en alguna estructura que facilita el acceso a esas tablas, ordenarlas y seleccionar filas de las tablas segn criterios especficos. Las bases de datos generalmente tienen ndices asociados a alguna de sus columnas, de forma que el

acceso sea lo ms rpido posible. Las Bases de Datos son, sin lugar a dudas, las estructuras ms utilizadas en ordenadores; ya que son el corazn de sistemas tan complejos como el censo de una nacin, la nmina de empleados de una empresa, el sistema de facturacin de una multinacional, o el medio por el que nos expiden el billete para las prximas vacaciones. En el caso, por ejemplo, del registro de trabajadores de una empresa, se puede imaginar una tabla con los nombres de los empleados y direcciones, y sueldos, retenciones y beneficios. Para organizar esta informacin, se puede empezar con una tabla que contenga los nombres de los empleados, su direccin y su nmero de telfono. Tambin se podra incluir la informacin relativa a su sueldo, categora, ltima subida de salario, etc. Podra todo esto colocarse en una sola tabla? Casi seguro que no. Los rangos de salario para diferentes empleados probablemente sean iguales, por lo que se podra optimizar la tabla almacenando solamente el tipo de salario en la tabla de empleados y los rangos de salario (en euros) en otra tabla, indexada a travs del tipo de salario. Por ejemplo

Los datos de la columna Tipo de Salario estn referidos a la segunda tabla. Se pueden imaginar muchas categoras para estas tablas secundarias, como por ejemplo la provincia de residencia y los tipos de retencin de Hacienda, o si tiene seguro de vida, vivienda propia, coche, apartamento en la playa, casa en el campo, etc. Cada tabla tiene una primera columna que sirve de clave para las dems columnas, que ya contienen datos. La construccin de tablas en las bases de datos es tanto un arte como una ciencia, y su estructura est referida por su forma normal. Las tablas se dice que estn en primera, segunda o tercera forma normal, o de modo abreviado como 1NF, 2NF o 3NF.

Cada celda de la tabla debe tener solamente un valor (nunca un conjunto de valores). (1NF) 1NF y cada columna que no es clave depende completamente de la columna clave. Esto significa que hay una relacin uno a uno entre la clave primaria y las restantes celdas de la fila. (2NF) 2NF y todas las columnas que no son clave son mutuamente independientes. Esto significa que no hay columnas de datos que contengan datos calculados a partir de los datos de otras columnas. (3NF)

Actualmente todas las bases de datos se construyen de forma que todas sus tablas estn en la Tercera Forma Normal (3NF); es decir, que las bases de datos estn constituidas por un nmero bastante alto de tablas, cada una de ellas con relativamente pocas columnas de informacin.

A la hora de extraer datos de las tablas, se realizan consultas contra ella. Por ejemplo, si se quiere generar una tabla de empleados y sus rangos de salario para algn tipo de plan especial de la empresa, esa tabla no existe directamente en la base de datos, as que debe construirse haciendo una consulta a la base de datos, y se obtendra una tabla que contendra la siguiente informacin:

O quiz ordenada por el incremento de salario:

Para generar la tabla anterior se habra de realizar una consulta a la base de datos que tendra la siguiente forma:
SELECT DISTINCTROW Empleados.Nombre, TipoDeSalario.Minimo, TipoDeSalario.Maximo FROM Empleados INNER JOIN TipoDeSalario ON Empleados.SalarioKe ! TipoDeSalario.SalarioKe ORDER "# TipoDeSalario.Minimo$

El lenguaje en que se ha escrito la consulta es SQL, actualmente soportado por casi todas las bases de datos a lo largo del mundo. Los estndares de SQL han sido varios a lo largo de los aos y muchas de las bases de datos para PC soportan alguno de esos tipos. El estndar SQL-92 es el que se considera origen de todas las actualizaciones. Hay que tener en cuenta, que hay posteriores versiones de SQL, perfeccionadas y extendidas para explotar caractersticas nicas de bases de datos particulares; as que no conviene separarse del estndar bsico si se pretende hacer una aplicacin que pueda atacar a cualquier tipo de base de datos. Al final del captulo, el lector puede encontrar una pequea revisin del lenguaje SQL. Desde que los PC se han convertido en una herramienta presente en la mayor parte de las oficinas, se han desarrollado un gran nmero de bases de datos para ejecutarse en ese tipo de plataformas; desde bases de datos muy elementales como Microsoft Works, hasta otras ya bastante sofisticadas como Approach, dBase, Paradox, Access y Foxbase. Otra categora ya ms seria de bases de datos para PC son aquellas que usan la plataforma PC como

cliente para acceder a un servidor. Estas bases de datos son IBM DB/2, Microsoft SQL Server, Oracle, Sybase, SQLBase, Informix, XDB y Postgres. Todas estas bases de datos soportan varios dialectos similares de SQL, y todas parecen, a primera vista, intercambiables. La razn de que no sean intercambiables, por supuesto, es que cada una est diseada con unas caractersticas de rendimiento distintas, con un interfaz de usuario y programacin diferente. Aunque todas ellas soportan SQL y la programacin es similar, cada base de datos tiene su propia forma de recibir las consultas SQL y su propio modo de devolver los resultados. Aqu es donde aparece el siguiente nivel de estandarizacin, de la mano de ODBC (Open DataBase Conectivity). La idea es que se pueda escribir cdigo independientemente de quien sea el propietario de la base de datos a la que se quiera acceder, de forma que se puedan extraer resultados similares de diferentes tipos de bases de datos sin necesidad de tocar el cdigo del programa. Si se consiguiese escribir alguna forma de trazadores para estas bases de datos que tuviesen un interfaz similar, el objetivo no sera difcil de alcanzar. Microsoft hizo su primer intento en 1992, con la especificacin que llamaron Object Database Connectivity; y que se supona iba a ser la respuesta a la conexin a cualquier tipo de base de datos desde Windows. Como en toda aplicacin informtica, esta no fue la nica versin, sino que hubo varias hasta llegar a la de 1994, que era ms rpida y ms estable, adems de ser la primera de las versiones de 32 bits. Y, por si fuera poco, ODBC comenz a desplazarse a otras plataformas diferentes de Windows, acaparando adems de los PC tambin el mundo de las estaciones de trabajo. Tanto es as, que ahora casi todos los fabricantes de bases de datos proporcionan un driver ODBC para acceder a su base de datos. Sin embargo, ODBC dista mucho de ser la panacea que en un principio se poda pensar y que Microsoft se encarg de hacer creer. Muchos fabricantes de bases de datos soportan ODBC como un interfaz alternativo al suyo estndar, y la programacin en ODBC no es nada, pero que nada trivial; incluyendo toda la parafernalia de la programacin para Windows con handles, punteros y opciones que son duras de asimilar. Finalmente, ODBC no es un estndar libre, ha sido desarrollado y es propiedad de Microsoft, lo cual, dados los vientos que soplan en este competitivo mundo de las compaas de software, hace su futuro difcil de predecir.

Conectividad JDBC Anterior | Siguiente Para la gente del mundo Windows, JDBC es para Java lo que ODBC es para Windows. Windows en general no sabe nada acerca de las bases de datos, pero define el estndar ODBC consistente en un conjunto de primitivas que cualquier driver o fuente ODBC debe ser capaz de entender y manipular. Los programadores que a su vez deseen escribir programas para manejar bases de datos genricas en Windows utilizan las llamadas ODBC. Con JDBC ocurre exactamente lo mismo: JDBC es una especificacin de un conjunto de clases y mtodos de operacin que permiten a cualquier programa Java acceder a sistemas de bases de datos de forma homognea. Lgicamente, al igual que ODBC, la aplicacin de Java debe tener acceso a un driver JDBC adecuado. Este driver es el que implementa la funcionalidad de todas las clases de acceso

a datos y proporciona la comunicacin entre el API JDBC y la base de datos real. La necesidad de JDBC, a pesar de la existencia de ODBC, viene dada porque ODBC es un interfaz escrito en lenguaje C, que al no ser un lenguaje portable, hara que las aplicaciones Java tambin perdiesen la portabilidad. Y adems, ODBC tiene el inconveniente de que se ha de instalar manualmente en cada mquina; al contrario que los drivers JDBC, que al estar escritos en Java son automticamente instalables, portables y seguros.

Toda la conectividad de bases de datos de Java se basa en sentencias SQL, por lo que se hace imprescindible un conocimiento adecuado de SQL para realizar cualquier clase de operacin de bases de datos. Aunque, afortunadamente, casi todos los entornos de desarrollo Java ofrecen componentes visuales que proporcionan una funcionalidad suficientemente potente sin necesidad de que sea necesario utilizar SQL, aunque para usar directamente el JDK se haga imprescindible. La especificacin JDBC requiere que cualquier driver JDBC sea compatible con al menos el nivel de entrada de ANSI SQL 92 (ANSI SQL 92 Entry Level). Acceso de JDBC a Bases de Datos El API JDBC soporta dos modelos diferentes de acceso a Bases de Datos, los modelos de dos y tres capas. Modelo de dos capas Este modelo se basa en que la conexin entre la aplicacin Java o el applet que se ejecuta en el navegador, se conectan directamente a la base de datos.

Esto significa que el driver JDBC especfico para conectarse con la base de datos, debe residir en el sistema local. La base de datos puede estar en cualquier otra mquina y se accede a ella mediante la red. Esta es la configuracin de tpica Cliente/Servidor: el programa cliente enva instrucciones SQL a la base de datos, sta las procesa y enva los resultados de vuelta a la aplicacin. Modelo de tres capas En este modelo de acceso a las bases de datos, las instrucciones son enviadas a una capa intermedia entre Cliente y Servidor, que es la que se encarga de enviar las sentencias SQL a la base de datos y recoger el resultado desde la base de datos. En este caso el usuario no tiene contacto directo, ni a travs de la red, con la mquina donde reside la base de datos.

Este modelo presenta la ventaja de que el nivel intermedio mantiene en todo momento el control del tipo de operaciones que se realizan contra la base de datos, y adems, est la ventaja adicional de que los drivers JDBC no tienen que residir en la mquina cliente, lo cual libera al usuario de la instalacin de cualquier tipo de driver. Tipos de drivers

Un driver JDBC puede pertenecer a una de cuatro categoras diferentes en cuanto a la forma de operar. Puente JDBC-ODBC La primera categora de drivers es la utilizada por Sun inicialmente para popularizar JDBC y consiste en aprovechar todo lo existente, estableciendo un puente entre JDBC y ODBC. Este driver convierte todas las llamadas JDBC a llamadas ODBC y realiza la conversin correspondiente de los resultados.

La ventaja de este driver, que se proporciona con el JDK, es que Java dispone de acceso inmediato a todas las fuentes posibles de bases de datos y no hay que hacer ninguna configuracin adicional aparte de la ya existente. No obstante, tiene dos desventajas muy importantes; por un lado, la mayora de los drivers ODBC a su vez convierten sus llamadas a llamadas a una librera nativa del fabricante DBMS, con lo cual la lentitud del driver JDBC-ODBC puede ser exasperante, al llevar dos capas adicionales que no aaden funcionalidad alguna; y por otra parte, el puente JDBC-ODBC requiere una instalacin ODBC ya existente y configurada. Lo anterior implica que para distribuir con seguridad una aplicacin Java que use JDBC habra que limitarse en primer lugar a entornos Windows (donde est definido ODBC) y en segundo lugar, proporcionar los drivers ODBC adecuados y configurarlos correctamente. Esto hace que este tipo de drivers est totalmente descartado en el caso de aplicaciones comerciales, e incluso en cualquier otro desarrollo, debe ser considerado como una solucin transitoria, porque el desarrollo de drivers totalmente en Java har innecesario el uso de estos puentes. Java/Binario

Este driver se salta la capa ODBC y habla directamente con la librera nativa del fabricante del sistema DBMS (como pudiera ser DB-Library para Microsoft SQL Server o CT-Lib para Sybase SQL Server). Este driver es un driver 100% Java pero an as necesita la existencia de un cdigo binario (la librera DBMS) en la mquina del cliente, con las limitaciones y problemas que esto implica. 100% Java/Protocolo nativo Es un driver realizado completamente en Java que se comunica con el servidor DBMS utilizando el protocolo de red nativo del servidor. De esta forma, el driver no necesita intermediarios para hablar con el servidor y convierte todas las peticiones JDBC en peticiones de red contra el servidor. La ventaja de este tipo de driver es que es una solucin 100% Java y, por lo tanto, independiente de la mquina en la que se va a ejecutar el programa.

Igualmente, dependiendo de la forma en que est programado el driver, puede no necesitar ninguna clase de configuracin por parte del usuario. La nica desventaja de este tipo de drivers es que el cliente est ligado a un servidor DBMS concreto, ya que el protocolo de red que utiliza MS SQL Server por ejemplo no tiene nada que ver con el utilizado por DB2, PostGres u Oracle. La mayora de los fabricantes de bases de datos han incorporado a sus propios drivers JDBC del segundo o tercer tipo, con la ventaja de que no suponen un coste adicional. 100% Java/Protocolo independiente

Esta es la opcin ms flexible, se trata de un driver 100% Java / Protocolo independiente, que requiere la presencia de un intermediario en el servidor. En este caso, el driver JDBC hace las peticiones de datos al intermediario en un protocolo de red independiente del servidor DBMS. El intermediario a su vez, que est ubicado en el lado del servidor, convierte las peticiones JDBC en peticiones nativas del sistema DBMS. La ventaja de este mtodo es inmediata: el programa que se ejecuta en el cliente, y aparte de las ventajas de los drivers 100% Java, tambin presenta la independencia respecto al sistema de bases de datos que se encuentra en el servidor. De esta forma, si una empresa distribuye una aplicacin Java para que sus usuarios puedan acceder a su servidor MS SQL y posteriormente decide cambiar el servidor por Oracle, PostGres o DB2, no necesita volver a distribuir la aplicacin, sino que nicamente debe reconfigurar la aplicacin residente en el servidor que se encarga de transformar las peticiones de red en peticiones nativas. La nica desventaja de este tipo de drivers es que la aplicacin intermediaria es una aplicacin independiente que suele tener un coste adicional por servidor fsico, que hay que aadir al coste del servidor de bases de datos. En el Tutorial todos los ejemplos estarn referidos al puente JDBC-ODBC y a la conectividad JDBC con servidores SQL comerciales Si el lector quiere seguir experimentando sin necesidad de adquirir paquetes comerciales, en el caso de Windows puede utilizar el conocido mSQL (mini SQL), un servidor SQL escrito por David J. Hughes y que es de distribucin shareware, siendo gratuita para fines no comerciales y de investigacin; y en el caso de Linux, aunque tambin se puede utilizar mSQL, el autor recomienda PostGres, que es un sistema de base de datos relacional que une las estructuras clsicas con los conceptos de programacin orientada a objetos. Lgicamente, el lector no debe esperar de mSQL una potencia, rendimiento o compatibilidad con ANSI SQL como la que tienen los servidores SQL comerciales, aunque en el caso de PostGres la funcionalidad es al menos igual a otras bases de datos profesionales existentes en el mercado; y aunque, como casi todos los productos Linux, carece de un interfaz cmodo, s permite realizar las tareas de administracin y explotacin con bastante comodidad.

Aproximacin a JDBC Anterior | Siguiente JDBC define ocho interfaces para operaciones con bases de datos, de las que se derivan las clases correspondientes. La figura siguiente, en formato OMT, con nomenclatura UML, muestra la interrelacin entre estas clases segn el modelo de objetos de la especificacin de JDBC.

La clase que se encarga de cargar inicialmente todos los drivers JDBC disponibles es DriverManager. Una aplicacin puede utilizar DriverManager para obtener un objeto de tipo conexin, Connection, con una base de datos. La conexin se especifica siguiendo una sintaxis basada en la especificacin ms amplia de los URL, de la forma jdbc:subprotocolo//servidor:puerto/base de datos

Por ejemplo, si se utiliza mSQL el nombre del subprotocolo ser msql. En algunas ocasiones es necesario identificar an ms el protocolo. Por ejemplo, si se usa el puente JDBC-ODBC no es suficiente con jdbc:odbc, ya que pueden existir mltiples drivers ODBC, y en este caso, hay que especificar an ms, mediante jdbc:odbc:fuente de datos. Una vez que se tiene un objeto de tipo Connection, se pueden crear sentencias, statements, ejecutables. Cada una de estas sentencias puede devolver cero o ms resultados, que se devuelven como objetos de tipo ResultSet. Y la tabla siguiente muestra la misma lista de clases e interfaces junto con una breve descripcin. Clase/Interface Driver DriverManager DriverPropertyInfo Connection Descripcin Permite conectarse a una base de datos: cada gestor de base de datos requiere un driver distinto Permite gestionar todos los drivers instalados en el sistema Proporciona diversa informacin acerca de un driver Representa una conexin con una base de datos. Una aplicacin puede tener ms de una conexin a ms de una base de datos Proporciona informacin acerca de una Base de Datos, como las tablas que contiene, etc. Permite ejecutar sentencias SQL sin parmetros Permite ejecutar sentencias SQL con parmetros de entrada/TD> Permite ejecutar sentencias SQL con parmetros de entrada y salida, tpicamente procedimientos almacenados Contiene las filas o registros obtenidos al ejecutar un SELECT Permite obtener informacin sobre un ResultSet, como el nmero de columnas, sus nombres, etc.

DatabaseMetadata Statement PreparedStatement CallableStatement ResultSet ResultSetMetadata

La primera aplicacin que se va a crear simplemente crea una tabla en el servidor, utilizando para ello el puente JDBC-ODBC, siendo la fuente de datos un servidor SQL Server. Si el lector desea utilizar otra fuente ODBC, no tiene ms que cambiar los parmetros de getConnection() en el cdigo fuente. El establecimiento de la conexin es, como se puede es fcil suponer, la parte que mayores problemas puede dar en una aplicacin de este tipo. Si algo no funciona, cosa ms que probable en los primeros intentos, es muy recomendable activar la traza de llamadas ODBC desde el panel de control. De esta forma se puede ver lo que est haciendo exactamente el driver JDBC y por qu motivo no se est

estableciendo la conexin. El siguiente diagrama relaciona las cuatro clases principales que va a usar cualquier programa Java con JDBC, y representa el esqueleto de cualquiera de los programas que se desarrollan para atacar a bases de datos.

La aplicacin siguiente es un ejemplo en donde se aplica el esquema anterior, se trata de instalacin java2101.java, crea una tabla y rellena algunos datos iniciales.
impor% &a'a.s(l.)$ *lass &a'a+,-, . s%a%i* p/bli* 'oid main0 S%rin123 ar1s 4 . Conne*%ion *onexion$ S%a%emen% sen%en*ia$ Res/l%Se% res/l%ado$ S s%em.o/%.prin%ln0 5Ini*iando pro1rama.5 4$ 66 Se *ar1a el dri'er JD"C7OD"C %r . Class.8orName0 5s/n.&db*.odb*.Jdb*Odb*Dri'er5 4$ 9 *a%*:0 Ex*ep%ion e 4 . S s%em.o/%.prin%ln0 5No se p/do *ar1ar el p/en%e JD"C7OD"C.5 4$ re%/rn$

9 %r . 66 Se es%able*e la *onexi;n *on la base de da%os *onexion ! Dri'erMana1er.1e%Conne*%ion0 5&db*<odb*<T/%orial5,55,55 4$ sen%en*ia ! *onexion.*rea%eS%a%emen%04$ %r . 66 Se elimina la %abla en *aso de (/e a exis%iese sen%en*ia.exe*/%e0 5DRO= T>"LE >?END>5 4$ 9 *a%*:0 S@LEx*ep%ion e 4 .9$ 66 Es%o es *;di1o S@L sen%en*ia.exe*/%e0 5CRE>TE T>"LE >MI?OS 05A 5 NOM"RE B>RCC>R0,D4 NOT NELL, 5 A 5 >=ELLIDOS B>RCC>R0F-4 NOT NELL, 5 A 5 CEM=LE D>TETIME4 5 4$ sen%en*ia.exe*/%e0 5INSERT INTO >MI?OS 5 A 5B>LEES0GJOSEG,G?ONH>LEHG,G-F6,D6,IJFG45 4$ sen%en*ia.exe*/%e0 5INSERT INTO >MI?OS 5 A 5B>LEES0G=EDROG,G?OMEHG,G-K6,D6,IL,G45 4$ sen%en*ia.exe*/%e0 5INSERT INTO >MI?OS 5 A 5B>LEES0G?ONH>LOG,G=EREHG, NELL45 4$ 9 *a%*:0 Ex*ep%ion e 4 . S s%em.o/%.prin%ln0 e 4$ re%/rn$ 9 S s%em.o/%.prin%ln0 5Crea*ion 8inaliMada.5 4$ 9

Las partes ms interesantes del cdigo son las que se van a revisar a continuacin, profundizando en cada uno de los pasos. Lo primero que se hace es importar toda la funcionalidad de JDBC, a travs de la primera sentencia ejecutable del programa.
impor% &a'a.s(l.)$

Las siguientes lneas son las que cargan el puente JDBC-ODBC, mediante el mtodo forName() de la clase Class.
%r . Class.8orName0 5s/n.&db*.odb*.Jdb*Odb*Dri'er5 4$ 9 *a%*:0 Ex*ep%ion e 4 . S s%em.o/%.prin%ln0 5No se p/do *ar1ar el p/en%e JD"C7OD"C.5 4$ re%/rn$ 9

En teora esto no es necesario, ya que DriverManager se encarga de leer todos los drivers JDBC compatibles, pero no siempre ocurre as, por lo que es mejor asegurarse. El mtodo forName() localiza, lee y enlaza dinmicamente una clase determinada. Para drivers JDBC, la sintaxis que JavaSoft recomienda de forName() es nombreEmpresa.nombreBaseDatos.nombreDriver, y el driver deber estar ubicado en el directorio nombreEmpresa\nombreBaseDatos\nombreDriver.class a partir del directorio

indicado por la variable de entorno CLASSPATH. En este caso se indica que el puente JDBC-ODBC que se desea leer es precisamente el de Sun. Si por cualquier motivo no es posible conseguir cargar JdbcOdbcDriver.class, se intercepta la excepcin y se sale del programa. En este momento es la hora de echar mano de la informacin que puedan proporcionar las trazas ODBC. La carga del driver tambin se puede especificar desde la lnea de comandos al lanzar la aplicacin:
&a'a 7D&db*.dri'ers!s/n.&db*.odb*.Jdb*Odb*Dri'er El=ro1rama

A continuacin, se solicita a DriverManager que proporcione una conexin para una fuente de datos ODBC. El parmetro jdbc:odbc:Tutorial especifica que la intencin es acceder a la fuente de datos con nombre Tutorial, Data Source Name o DSN, en la terminologa ODBC.
*onexion ! Dri'erMana1er.1e%Conne*%ion05&db*<odb*<T/%orial5,55,55 4$

El segundo y tercer parmetro son el nombre del usuario y la clave con la cual se intentar la conexin. En este caso el acceso es libre, para acceder como administrador del sistema en el caso de un servidor MS SQL se usa la cuenta sa o system administrator, cuya cuenta de acceso no tiene clave definida; en caso de acceder a un servidor MS Access, la cuenta del administrador es admin y tambin sin clave definida. Esta es la nica lnea que con seguridad habr de cambiar el programador para probar sus aplicaciones. getConnection admite tambin una forma con un nico parmetro (el URL de la base de datos), que debe proporcionar toda la informacin de conexin necesaria al driver JDBC correspondiente. Para el caso JDBC-ODBC, se puede utilizar la sentencia equivalente: DriverManager.getConnection ( "jdbc:odbc:SQL;UID=sa;PWD=" ); Para el resto de los drivers JDBC, habr que consultar la documentacin de cada driver en concreto. Inmediatamente despus de obtener la conexin, en la siguiente lnea
sen%en*ia ! *onexion.*rea%eS%a%emen%04$

se solicita que proporcione un objeto de tipo Statement para poder ejecutar sentencias a travs de esa conexin. Para ello se dispone de los mtodos execute(String sentencia) para ejecutar una peticin SQL que no devuelve datos o executeQuery(String sentencia) para ejecutar una consulta SQL. Este ltimo mtodo devuelve un objeto de tipo ResultSet. Una vez que se tiene el objeto Statement ya se pueden lanzar consultas y ejecutar sentencias contra el servidor. A partir de aqu el resto del programa realmente es SQL adornado: en la lnea:
sen%en*ia.exe*/%e0 5DRO= T>"LE >MI?OS5 4$

se ejecuta DROP TABLE AMIGOS para borrar cualquier tabla existente anteriormente. Puesto que este ejemplo es una aplicacin de instalacin y es posible que la tabla AMIGOS no exista, dando como

resultado una excepcin, se asla la sentencia.execute() mediante un try y un catch. La lnea siguiente ejecuta una sentencia SQL que crea la tabla AMIGOS con tres campos: NOMBRE, APELLIDOS y CUMPLE. De ellos, nicamente el tercero, correspondiente al cumpleaos, es el que puede ser desconocido, es decir, puede contener valores nulos.
sen%en*ia.exe*/%e0 5CRE>TE T>"LE >MI?OS 05A 5 NOM"RE B>RCC>R0,D4 NOT NELL, 5 A 5 >=ELLIDOS B>RCC>R0F-4 NOT NELL, 5 A 5 CEM=LE D>TETIME4 5 4$

Y ya en las lneas siguientes se ejecutan sentencias INSERT para rellenar con datos la tabla. En todo momento se ha colocado un try ... catch exterior para interceptar cualquier excepcin que puedan dar las sentencias. En general, para java.sql est definida una clase especial de excepciones que es SQLException. Se obtendr una excepcin de este tipo cuando ocurra cualquier error de proceso de JDBC, tanto si es a nivel JDBC como si es a nivel inferior (ODBC o de protocolo). Por ejemplo, si en lugar de GONZALO en la lnea correspondiente a la ltima insercin en la Base de Datos, se intenta aadir un nombre nulo (NULL), se generar una excepcin SQLException con el mensaje [Microsoft][ODBC SQL Server Driver][SQL Server]Attempt to insert the value NULL into column 'NOMBRE', table 'master.dbo.AGENDA'; column does not allow nulls. INSERT fails. que en el caso de Microsoft Access sera: [Microsoft][ODBC Microsoft Access 97 Driver] The field 'AGENDA.NOMBRE' can't contain a Null value because the Required property for this field is set to True. Enter a value in this field. En romn paladino, el hecho de que la columna NOMBRE est definida como NOT NULL, hace que no pueda quedarse vaca. Ahora se vern los pasos que hay que dar para obtener informacin a partir de una base de datos ya creada. Como se ha dicho anteriormente, se utilizar executeQuery en lugar de execute para obtener resultados. Se sustituyen las lneas que contenan esa sentencia por :
res/l%ado ! sen%en*ia.exe*/%e@/er 0 5SELECT ) FROM >MI?OS5 4$ N:ile0 res/l%ado.nex%04 4 . S%rin1 nombre ! res/l%ado.1e%S%rin10 5NOM"RE5 4$ S%rin1 apellidos ! res/l%ado.1e%S%rin10 5>=ELLIDOS5 4$ S%rin1 */mple ! res/l%ado.1e%S%rin10 5CEM=LE5 4$ S s%em.o/%.prin%ln0 5El ani'ersario de D. 5 A nombre A 5 5 A apellidos A 5, se *elebra el 5 A */mple 4$ 9

En este caso, en la primera lnea se utiliza executeQuery para obtener el resultado de SELECT * FROM AMIGOS. Mediante resultado.next() la posicin se situar en el siguiente elemento del resultado, o bien sobre el primero si todava no se ha utilizado. La funcin next() devuelve true o false si el elemento existe, de forma que se puede iterar mediante while ( resultado.next() ) para tener acceso

a todos los elementos. A continuacin, en las lneas siguientes se utilizan los mtodos getXXX() de resultado para tener acceso a las diferentes columnas. El acceso se puede hacer por el nombre de la columna, como en las dos primeras lneas, o bien mediante su ubicacin relativa, como en la ltima lnea. Adems de getString() estn disponibles getBoolean(), getByte(), getDouble(), getFloat(), getInt(), getLong(), getNumeric(), getObject(), getShort(), getDate(), getTime() y getUnicodeStream(), cada uno de los cuales devuelve la columna en el formato correspondiente, si es posible. Despus de haber trabajado con una sentencia o una conexin es recomendable cerrarla mediante sentencia.close() o conexin.close(). De forma predeterminada los drivers JDBC deben hacer un COMMIT de cada sentencia. Este comportamiento se puede modificar mediante el mtodo Connection.setAutoCommit( boolean nuevovalor). En el caso de que se establezca AutoCommit a false, ser necesario llamar de forma explcita a Connection.commit() para guardar los cambios realizados o Connection.rollback() para deshacerlos. Como el lector habr podido comprobar hasta ahora, no hay nada intrnsecamente difcil en conectar Java con una base de datos remota. Los posibles problemas de conexin que puede haber (seleccin del driver o fuente de datos adecuada, obtencin de acceso, etc.), son problemas que se tendran de una u otra forma en cualquier lenguaje de programacin. El objeto ResultSet devuelto por el mtodo executeQuery(), permite recorrer las filas obtenidas, no proporciona informacin referente a la estructura de cada una de ellas; para ello se utiliza ResultSetMetaData, que permite obtener el tipo de cada campo o columna, su nombre, si es del tipo autoincremento, si es sensible a maysculas, si se puede escribir en dicha columna, si admite valores nulos, etc. Para obtener un objeto de tipo ResultSetMetaData basta con llamar al mtodo getMetaData() del objeto ResultSet. En la lista siguiente aparecen algunos de los mtodos ms importantes de ResultSetMetaData, que permiten averiguar toda la informacin necesaria para formatear la informacin correspondiente a una columna, etc. getCatalogName() Nombre de la columna en el catlogo de la base de datos getColumnName() Nombre de la columna getColumnLabel() Nombre a utilizar a la hora de imprimir el nombre de la columna getColumnDisplaySize() Ancho mximo en caracteres necesario para mostrar el contenido de la columna

getColumnCount() Nmero de columnas en el ResultSet getTableName() Nombre de la tabla a que pertenece la columna getPrecision() Nmero de dgitos de la columna getScale() Nmero de decimales para la columna getColumnType() Tipo de la columna (uno de los tipos SQL en java.sql.Types) getColumnTypeName() Nombre del tipo de la columna isSigned() Para nmeros, indica si la columna corresponde a un nmero con signo isAutoIncrement() Indica si la columna es de tipo autoincremento isCurrency() Indica si la columna contiene un valor monetario isCaseSensitive() Indica si la columna contiene un texto sensible a maysculas isNullable() Indica si la columna puede contener un NULL SQL. Puede devolver los valores columnNoNulls, columnNullable o columnNullableUnknown, miembros finales estticos de ResultSetMetaData (constantes) isReadOnly() Indica si la columna es de solo lectura isWritable() Indica si la columna puede modificarse, aunque no lo garantiza isDefinitivelyWritable() Indica si es absolutamente seguro que la columna se puede modificar isSearchable()

Indica si es posible utilizar la columna para determinar los criterios de bsqueda de un SELECT getSchemaName() Devuelve el texto correspondiente al esquema de la base de datos para esa columna En general pues, los objetos que se van a poder encontrar en una aplicacin que utilice JDBC, sern los que se indican a continuacin. Connection Representa la conexin con la base de datos. Es el objeto que permite realizar las consultas SQL y obtener los resultados de dichas consultas. Es el objeto base para la creacin de los objetos de acceso a la base de datos. DriverManager Encargado de mantener los drivers que estn disponibles en una aplicacin concreta. Es el objeto que mantiene las funciones de administracin de las operaciones que se realizan con la base de datos. Statement Se utiliza para enviar las sentencias SQL simples, aquellas que no necesitan parmetros, a la base de datos. PreparedStatement Tiene una relacin de herencia con el objeto Statement, aadindole la funcionalidad de poder utilizar parmetros de entrada. Adems, tiene la particularidad de que la pregunta ya ha sido compilada antes de ser realizada, por lo que se denomina preparada. La principal ventaja, aparte de la utilizacin de parmetros, es la rapidez de ejecucin de la pregunta. CallableStatement Tiene una relacin de herencia cn el objeto PreparedStatement. Permite utilizar funciones implementadas directamente sobre el sistema de gestin de la base de datos. Teniendo en cuenta que ste posee informacin adicional sobre el uso de las estructuras internas, ndices, etc.; las funciones se realizarn de forma ms eficiente. Este tipo de operaciones es muy utilizada en el caso de ser funciones muy complicadas o bien que vayan a ser ejecutadas varias veces a lo largo del tiempo de vida de la aplicacin. ResultSet Contiene la tabla resultado de la pregunta SQL que se haya realizado. En prrafos anteriores se han comentado los mtodos que proporciona este objeto para recorrer dicha tabla.

Transacciones, Tipos... Anterior | Siguiente Transacciones En prrafos anteriores se ha tratado de la creacin y uso de sentencias SQL, que siempre se obtenan llamando a un mtodo de un objeto de tipo Connection, como createStatement() o prepareStatement(). El uso de transacciones, tambin se controla mediante mtodos del objeto Connection. Como ya se ha dicho, Connection representa una conexin a una Base de datos dada, luego representa el lugar adecuado para el manejo de transacciones, dado que estas afectan a todas las sentencias ejecutadas sobre una conexin a la base de datos. Por defecto, una conexin funciona en modo autocommit, es decir, cada vez que se ejecuta una sentencia SQL se abre y se cierra automticamente una transaccin, que slo afecta a dicha sentencia. Es posible modificar esta opcin mediante setAutoCommit(), mientras que getAutoCommit() indica si se est en modo autocommit o no. Si no se est trabajando en modo autocommit ser necesario que se cierren explcitamente las transacciones mediante commit() si tienen xito, o rollback(), si fallan; ntese que, tras cerrar una transaccin, la prxima vez que se ejecute una sentencia SQL se abrir automticamente una nueva, por lo que no existe ningn mtodo del tipo que permita iniciar una transaccin. Es posible tambin especificar el nivel de aislamiento de una transaccin, mediante setTransactionIsolation(), as como averiguar cul es el nivel de aislamiento de la actual mediante getTransactionIsolation(). Los niveles de aislamiento se representan mediante las constantes que se muestran en la lista siguiente, en la cual se explica muy bsicamente el efecto de cada nivel de aislamiento. TRANSACTION_NONE No se pueden utilizar transacciones. TRANSACTION_READ_UNCOMMITTED Desde esta transaccin se pueden llegar a ver registros que han sido modificados por otra transaccin, pero no guardados, por lo que podemos llegar a trabajar con valores que nunca llegan a guardarse realmente. TRANSACTION_READ_COMMITTED Se ven solo las modificaciones ya guardadas hechas por otras transacciones. TRANSACTION_REPEATABLE_READ Si se ley un registro, y otra transaccin lo modifica, guardndolo, y lo volvemos a leer, seguiremos viendo la informacin que haba cuando lo lemos por primera vez. Esto

proporciona un nivel de consistencia mayor que los niveles de aislamiento anteriores. TRANSACTION_SERIALIZABLE Se vern todos los registros tal y como estaban antes de comenzar la transaccin, no importa las modificaciones que otras transacciones hagan, ni que lo hayamos ledo antes o no. Si se aadi algn nuevo registro, tampoco se ver. Adems de manejar transacciones, el objeto Connection tambin proporciona algunos otros mtodos que permiten especificar caractersticas de una conexin a una base de datos; por ejemplo, los mtodos isReadOnly() y setReadOnly() permiten averiguar si una conexin a una base de datos es de slo lectura, o hacerla de slo lectura. El mtodo isClosed() permite averiguar si una conexin est cerrada o no, y nativeSQL() permite obtener la cadena SQL que el driver mandara a la base de datos si se tratase de ejecutar la cadena SQL especificada, permitiendo averiguar qu es exactamente lo que se le enva a la base de datos. Informacin de la Base de Datos Falta an una pieza importante a la hora de trabajar con la conexin a la base de datos mediante Connection, y es la posibilidad de poder interrogar sobre las caractersticas de una base de datos; por ejemplo, puede se interesante saber si la base de datos soporta cierto nivel de aislamiento en una transaccin, como la TRANSACTION_SERIALIZABLE, que muchos gestores no soportan. Para esto est otro de los interfaces que proporciona JDBC, DatabaseMetaData, al que es posible interrogar sobre las caractersticas de la base de datos con la que se est trabajando. Es posible obtener un objeto de tipo DatabaseMetaData mediante el mtodo getMetaData() de Connection. DatabaseMetaData proporciona diversa informacin sobre una base de datos, y cuenta con varias docenas de mtodos, a travs de los cuales es posible obtener gran cantidad de informacin acerca de una tabla; por ejemplo, getColumns() devuelve las columnas de una tabla, getPrimaryKeys() devuelve la lista de columnas que forman la clave primaria, getIndexInfo() devuelve informacin acerca de sus ndices, mientras que getExportedKeys() devuelve la lista de todas las claves ajenas que utilizan la clave primaria de esta tabla, y getImportedKeys() las claves ajenas existentes en la tabla. El mtodo getTables() devuelve la lista de todas las tablas en la base de datos, mientras que getProcedures() devuelve la lista de procedimientos almacenados. Muchos de los mtodos de DatabaseMetaData devuelven un objeto de tipo ResultSet que contiene la informacin deseada. El listado que se presenta a continuacin, muestra el cdigo necesario para obtener todas las tablas de una base de datos.
S%rin1 nombreTablas ! 5O5$ 66 Lis%amos %odas las %ablas S%rin1 %ipos23 ! neN S%rin12,3$ 66 Lis%amos s;lo %ablas %ipos2-3 ! 5T>"LE5$ Da%abaseMe%aDa%a dbmd ! *onexion.1e%Me%aDa%a04$ Res/l%Se% %ablas ! dbmd.1e%Tables0 n/ll,n/ll,nombreTablas,%ipos 4$ boolean se1/ir ! %ablas.nex%04$ N:ile0 se1/ir 4 . 66 Mos%ramos s;lo el nombre de las %ablas, 1/ardado 66 en la *ol/mna 5T>"LEPN>ME5 S s%em.o/%.prin%ln0

%ablas.1e%S%rin10 %ablas.8indCol/mn0 5T>"LEPN>ME5 4 4 4$ se1/ir ! %ablas.nex%04$ 9$

Hay todo un grupo de mtodos que permiten averiguar si ciertas caractersticas estn soportadas por la base de datos; entre ellos, destacan supportsGroupBy() indica si se soporta el uso de GROUP BY en un SELECT, mientras que supportsOuterJoins() indica si se pueden llevar a cabo outer-joins. El mtodo supportsTransactions(), comentado antes, indica si cierto tipo de transacciones est soportado o no. Otros mtodos de utilidad son getUserName(), que devuelve el nombre del usuario actual; getURL(), que devuelve el URL de la base de datos actual. DatabaseMetaData proporciona muchos otros mtodos que permiten averiguar cosas tales como el mximo nmero de columnas utilizable en un SELECT, etc. En general, casi cualquier pregunta sobre las capacidades de la base de datos se puede contestar llamando a los distintos mtodos del objeto DatabaseMetaData, que merece la pena que el lector consulte cuando no sepa si cierta caracterstica est soportada. Tipos SQL en Java Muchos de los tipos de datos estndar de SQL 92, no tienen un equivalente nativo en Java. Para superar esta deficiencia, se deben mapear los tipos de datos SQL en Java, utilizando las clases JDBC para acceder a los tipos de datos SQL. Es necesario saber cmo recuperar adecuadamente tipos de datos Java; como int, long, o string, a partir de sus contrapartidas SQL almacenadas en base de datos. Esto puede ser especialmente importante si se est trabajando con datos numricos, que necesiten control decimal con precisin, o con fechas SQL, que tienen un formato muy bien definido. El mapeo de los tipos de datos Java a SQL es realmente sencillo, tal como se muestra en la tabla que acompaa a este prrafo. Observe el lector que los tipos que comienzan por "java" no son tipos bsicos, sino clases que tienen mtodos para trasladar los datos a formatos utilizables, y son necesarias estas clases porque no hay un tipo de datos bsico que mapee directamente su contrapartida SQL. La creacin de estas clases debe hacerse siempre que se necesite almacenar un tipo de dato SQL en un programa Java, para poder utilizar directamente el dato desde la base de datos. Java String boolean byte short int long float SQL VARCHAR BIT TINYINT SMALLINT INTEGER BIGINT REAL

double byte[]-byte array: imagenes, sonidos... java.sql.Date java.sql.Time java.sql.Timestamp java.math.BigDecimal

DOUBLE VARBINARY (BLOBs) DATE TIME TIMESTAMP NUMERIC

El tipo de dato byte[], es un array de bytes de tamao variable. Esta estructura de datos guarda datos binarios, que en SQL son VARBINARY y LONG-VARBINARY. Estos tipos se utilizan para almacenar imgenes, ficheros de documentos, y cosas parecidas. Para almacenar y recuperar este tipo de informacin de la base de datos, se deben utilizarlos mtodos para streams que proporciona JDBC: setBinaryStream() y getBinaryStream(). La conversin de tipos en el sentido contrario puede no estar tan clara, ya que hay tipos SQL cuya tipo Java correspondiente puede no ser evidente, como VARBINARY, o DECIMAL, etc. La tabla siguiente muestra los tipos Java correspondientes a cada tipo SQL. SQL CHAR VARCHAR LONGVARCHAR NUMERIC DECIMAL BIT TINYINT SMALLINT INTEGER BIGINT REAL FLOAT DOUBLE BINARY VARBINARY String String String java.math.BigDecimal java.math.BigDecimal boolean byte short int long float double double byte[] byte[] Java

LONGVARBINARY DATE TIME TIMESTAMP

byte[] java.sql.Date java.sql.Time java.sql.Timestamp

Existe una constante para cada tipo de dato SQL, declarada en java.sql.Types; por ejemplo, el tipo al tipo TIMESTAMP le corresponde la constante java.sql.Types.TIMESTAMP. Adems, JDBC proporciona clases Java nuevas para representar varios tipos de datos SQL: estas son java.sql.Date, java.sql.Time y java.sql.Timestamp. Modelos Anterior | Siguiente Modelo Relacional de Objetos Este modelo intenta fundir la orientacin a objetos con el modelo de base de datos relacional. Como muchos de los lenguajes de programacin actuales, como Java, son orientados a objetos, una estrecha integracin entre los dos podra proporcionar una relativamente sencilla abstraccin a los desarrolladores que programan en lenguajes orientados a objetos y que tambin necesitan programar en SQL. Esta integracin, adems, debera casi eliminar la necesidad de una constante traslacin entre las tablas de la base de datos y las estructuras del lenguaje orientado a objetos, que es una tarea muy ardua. A continuacin se muestra un ejemplo muy simple para presentar la base del Modelo. Supngase que se crea la siguiente Tabla en una base de datos:

Con una relativa facilidad, se puede mapear esta tabla en un objeto Java; que, tal como se muestra en el siguiente trozo de cdigo:
*lass Empleado . in% Cla'e$ S%rin1 Nombre$ S%rin1 >pellido$ S%rin1 Tele8ono$ in% N/mPEmpleado$ Cla'e ! N/mPEmpleado$

Para recuperar esta tabla desde la base de datos a Java, simplemente se asignaran las columnas respectivas al objeto Empleado que se creara previamente a la recuperacin de cada fila, tal como se muestra a continuacin:
Empleado ob&Empleado ! neN Empleado04$ ob&Empleado.Nombre ! res/l%se%.1e%S%rin10 5nombre5 4$ ob&Empleado.>pellido ! res/l%se%.1e%S%rin10 5apellido5 4$ ob&Empleado.Tele8ono ! res/l%se%.1e%S%rin10 5%ele8ono5 4$ ob&Empleado.N/mPEmpleado ! res/l%se%.1e%In%0 5n/mPempleado5 4$

Con una base de datos ms grande, incluso con enlaces entre las tablas, el nmero de problemas se dispara, incluyendo la escalabilidad debida a los mltiples JOINs en el modelo de datos y los enlaces cruzados entre las claves de la tablas. Pero, afortunadamente, ya hay productos disponibles que permiten crear este tipo de puentes entre los modelos relacional y orientado a objetos; es ms, hay varias de estas soluciones que estn siendo desarrolladas para trabajar especficamente con Java. Uno de los ejemplos, para Linux, de este tipo de herramientas es la base de datos PostGres, que es un sistema de base de datos relacional que unse las estructuras clsicas de estos sistemas con los conceptos de programacin orientada a objetos, es decir, se tratara de una base de datos objetorelacional. En PostGres, por ejemplo, las tablas de denominan clases, las filas se denominan instancias y las columnas se denominan atributos. Adems, un concepto que aparece en PostGres y que viene claramente de la programacin orientada a objetos es la Herencia, de forma que cuando se crea una nueva clase heredada de otra, la clase creada adquiere todas las caractersticas de la clase de la que proviene, ms las caractersticas que se definan en la nueva clase. Por poner un ejemplo, si se tiene una tabla creada con la sentencia que se indica a continuacin:
CRE>TE T>"L> %abla, 0 *ampo, %ex% *ampo+ in% 4

A continuacin, se puede crear una segunda tabla con la sentencia SQL a continuacin definida:
CRE>TE T>"L> %abla+ 0 *ampoF in% 4 INCERITS0 %abla, 4

Como resultado de esta sentencia SQL, la nueva tabla tendr los atributos campo1, campo2 y campo3. Modelo de Conexin La conexin a bases de datos relacionales a travs de JDBC realmente es muy simple, tal como ya se ha podido comprobar. No obstante, en este apartado es proporcionar, o intentarlo al menos, una plantilla que se pueda reutilizar y personalizar para aprender a manipular bases de datos con Java. Una vez que el ejemplo sea comprendido por el lector, no habr problemas a la hora de saber qu hacer y cmo hacerlo. Y cuando se necesite ms informacin, la documentacin que proporciona JavaSoft sobre JDBC la tiene.

De todas las cosas que hay que tener en mente, la conexin de Java con la base de datos relacional es la primera de las preocupaciones. En el ejemplo java2102.java se muestra cmo se hace, y establece la conexin. Tambin contiene varios mtodos que procesan sentencias SQL habituales de una forma simple y segura: la conexiones son abiertas y cerradas con cada sentencia SQL. Si el lector est construyendo aplicaciones en las que se prevean grandes flujos de transacciones, tendr que establecer una estrategia ms adecuada; por ejemplo, si se pretenden realizar actualizaciones sobre un registro una vez que se haya accedido a l, probablemente sea mejor mantener abierta la conexin con la base de datos hasta que hayan concluido todas las actualizaciones. Como la conexin a una base de datos es un objeto, se puede mantener en una variable tanto tiempo como se necesite; con lo cual, la aplicacin ser capaz de procesar las actualizaciones mucho ms rpidamente, pero corriendo el riesgo de que otros usuarios tengan bloqueado el acceso hasta que las conexiones que estn bloqueadas se concluyan.
impor% impor% impor% impor% &a'a.io.)$ &a'a.ne%.)$ &a'a./%il.)$ &a'a.s(l.)$

p/bli* *lass &a'a+,-+ ex%ends T:read . p/bli* s%a%i* 8inal in% =EERTO ! LJ--$ Ser'erSo*Qe% so*Qe%Es*/*:a$ p/bli* &a'a+,-+04 . %r . so*Qe%Es*/*:a ! neN Ser'erSo*Qe%0 =EERTO 4$ 9 *a%*:0 IOEx*ep%ion e 4 . S s%em.err.prin%ln0 e 4$ 9 %:is.s%ar%04$ 9 p/bli* 'oid r/n04 . %r . N:ile0 %r/e 4 . So*Qe% so*Qe%Clien%e ! so*Qe%Es*/*:a.a**ep%04$ S@LConexion * ! neN S@LConexion0 so*Qe%Clien%e 4$ 9 9 *a%*:0 IOEx*ep%ion e 4 . S s%em.err.prin%ln0 e 4$ 9 9 p/bli* s%a%i* 'oid main0 S%rin123 ar1' 4 . neN &a'a+,-+04$ 9

*lass S@LConexion ex%ends T:read . pro%e*%ed So*Qe% *lien%e$ pro%e*%ed "/88eredReader in$ pro%e*%ed =rin%S%ream o/%$ pro%e*%ed S%rin1 *ons/l%a$ p/bli* S@LConexion0 So*Qe% so*Qe%Clien%e 4 . *lien%e ! so*Qe%Clien%e$ %r .

in ! neN "/88eredReader0 neN Inp/%S%reamReader0 *lien%e.1e%Inp/%S%ream04 4 4$ o/% ! neN =rin%S%ream0 *lien%e.1e%O/%p/%S%ream04 4$ 9 *a%*:0 IOEx*ep%ion e 4 . S s%em.err.prin%ln0 e 4$ %r . *lien%e.*lose04$ 9 *a%*:0 IOEx*ep%ion e+ 4 .9$ re%/rn$ 9 %:is.s%ar%04$ 9 p/bli* 'oid r/n04 . %r . *ons/l%a ! in.readLine04$ S s%em.o/%.prin%ln0 5Lee la *ons/l%a R5 A *ons/l%a A 5S5 4$ e&e*/%aS@L04$ 9 *a%*:0 IOEx*ep%ion e 4 .9 8inall . %r . *lien%e.*lose04$ 9 *a%*:0 IOEx*ep%ion e 4 .9$ 9 9 p/bli* 'oid e&e*/%aS@L04 . Conne*%ion *onexion$ 66 Ob&e%o de *onexi;n a la S%a%emen% sen%en*ia$ 66 Ob&e%o *on la sen%en*ia Res/l%Se% res/l%ado$ 66 Ob&e%o *on el res/l%ado Res/l%Se%Me%aDa%a res/l%adoMe%a$ boolean mas$ 66 Indi*ador de si :a mTs S%rin1 dri'er ! 5&db*<odb*<T/%orial5$ S%rin1 /s/ario ! 55$ S%rin1 *la'e ! 55$ S%rin1 re1is%ro$ in% n/mCols, i$ %r base de da%os S@L de la *ons/l%a S@L 8ilas

. Class.8orName0 5s/n.&db*.odb*.Jdb*Odb*Dri'er5 4$ *onexion ! Dri'erMana1er.1e%Conne*%ion0 dri'er,/s/ario,*la'e 4$ sen%en*ia ! *onexion.*rea%eS%a%emen%04$ res/l%ado ! sen%en*ia.exe*/%e@/er 0 *ons/l%a 4$ mas ! res/l%ado.nex%04$ i80 Umas 4 . o/%.prin%ln0 5No :a mas 8ilas.5 4$ re%/rn$ 9 res/l%adoMe%a ! res/l%ado.1e%Me%aDa%a04$ n/mCols ! res/l%adoMe%a.1e%Col/mnCo/n%04$ S s%em.o/%.prin%ln0 n/mCols A 5 *ol/mnas en el res/l%ado.54$ N:ile0 mas 4 . 66 Se *ons%r/ e la *adena de resp/es%a re1is%ro ! 55$ 8or0 i!,$ i R! n/mCols$ iAA 4 .

re1is%ro ! re1is%ro.*on*a%0 res/l%ado.1e%S%rin10i4A5 9 o/%.prin%ln0 re1is%ro 4$ S s%em.o/%.prin%ln0 re1is%ro 4$ mas ! res/l%ado.nex%04$ 9 res/l%ado.*lose04$ sen%en*ia.*lose04$ *onexion.*ommi%04$ *onexion.*lose04$ 9 *a%*:0 Ex*ep%ion e 4 . S s%em.o/%.prin%ln0 e.%oS%rin104 4$ 9

5 4$

9 9

El ejemplo, evidentemente, asume que hay una base de datos disponible para usar y su esquema es muy simple, ya que utiliza la base de datos del primer ejemplo del captulo, con solamente tres campos. Mucho del desarrollo de este captulo ha sido desarrollado en Linux utilizando la base de datos PostGres, y luego, exactamente el mismo cdigo, solamente cambiando la conexin a la base de datos, ejecutado utilizando Microsoft Access, para capturar la ejecucin con el API del ltimo JDK. La parte cliente del ejemplo anterior, es la que se ha codificado en el ejemplo java2103.java, implementado como applet, que permite introducir una consulta en el campo de texto, que ser enviada al servidor implementado en el ejemplo anterior, que a su vez, enviar la consulta a la base de datos y devolver el resultado al applet, que mostrar la informacin resultante de su consulta en la parte inferior del applet. En estos dos ejemplos, se muestran los fundamentos de la interaccin con bases de datos, de una forma un poco ms complicada, de tal modo que no desde el mismo programa se ataca a la base de datos; esto proporcionar al lector una visin ms amplia de la capacidad y potencia que se encuentra bajo la conjuncin de Java y las Bases de Datos.
impor% impor% impor% impor% impor% &a'a.io.)$ &a'a.ne%.)$ &a'a.apple%.)$ &a'a.aN%.)$ &a'a.aN%.e'en%.)$

p/bli* *lass &a'a+,-F ex%ends >pple% . s%a%i* 8inal in% p/er%o ! LJ--$ S%rin1 *adCons/l%a ! 5No :a *ons/l%a %oda'ia5$ S%rin1 *adRes/l%ado ! 5No :a res/l%ados5$ "/%%on bo%on$ Tex%>rea %ex%o$ Lis% lis%a$ p/bli* 'oid ini%04 . se%La o/%0 neN ?ridLa o/%0 D,, 4 4$ %ex%o ! neN Tex%>rea0 +-,V- 4$ lis%a ! neN Lis%04$ bo%on ! neN "/%%on0 5E&e*/%ar Cons/l%a5 4$ bo%on.add>*%ionLis%ener0 neN Mi>*%ionLis%ener04 4$ add0 neN Label0 5Es*ribir la *ons/l%a a(/i...5 4 4$

add0 add0 add0 add0

%ex%o 4$ bo%on 4$ neN Label0 5 lis%a 4$

examinar los res/l%ados a(/i5 4 4$

resiMe0 K--,K-- 4$ 9 'oid abreSo*Qe%04 . So*Qe% s ! n/ll$ %r . s ! neN So*Qe%0 1e%Code"ase04.1e%Cos%04,p/er%o 4$ "/88eredReader sins%ream ! neN "/88eredReader0neN Inp/%S%reamReader0s.1e%Inp/%S%ream0444$ =rin%S%ream so/%s%ream ! neN =rin%S%ream0 s.1e%O/%p/%S%ream04 4$ so/%s%ream.prin%ln0 %ex%o.1e%Tex%04 4$ lis%a.remo'e>ll04$ *adRes/l%ado ! sins%ream.readLine04$ N:ile0 *adRes/l%ado U! n/ll 4 . lis%a.add0 *adRes/l%ado 4$ *adRes/l%ado ! sins%ream.readLine04$ 9 9 *a%*:0 IOEx*ep%ion e 4 . S s%em.err.prin%ln0 e 4$ 9 8inall . %r . i80 s U! n/ll 4 s.*lose04$9 *a%*:0 IOEx*ep%ion e 4 .9 9 9 *lass Mi>*%ionLis%ener implemen%s >*%ionLis%ener . p/bli* 'oid a*%ion=er8ormed0 >*%ionE'en% e'% 4 . abreSo*Qe%04$ 9 9

Una vez comprendidas las ideas bsicas que se presentaban en los ejemplos anteriores, el lector podr atreverse ya a escribir programas que manejen esquemas de bases de datos mucho ms complicados. No obstante, si el lector tiene una buena base en el conocimiento de bases de datos relacionales, estar satisfecho con esta simplicidad. El ejemplo java2104.java, es un simple interfaz para atacar a cualquier tipo de base de datos. Solamente se ha codificado el driver JDBC a utilizar, pero a travs de la ventana que se presenta, se puede acceder a cualquier base de datos y cualquier tabla. La figura muestra la ventana, una vez que se ha accedido a la base de datos que se ha estado utilizando.

Y el cdigo completo del ejemplo, que se ha intentado comentar profusamente para que la comprensin sea sencilla es el que se reproduce a continuacin.
impor% impor% impor% impor% &a'a.ne%.ERL$ &a'a.aN%.)$ &a'a.s(l.)$ &a'a.aN%.e'en%.)$

p/bli* *lass &a'a+,-V ex%ends Frame implemen%s Mo/seLis%ener . 66 Se /%iliMa el i%ner8aM Mo/seLis%ener para poder *ap%/rar 66 los pi(/es de ra%;n 66 Es%os son los ob&e%os (/e se 'an a /%iliMar en la apli*a*i;n "/%%on bo%Conexion ! neN "/%%on0 5 Conexi;n a la "ase de Da%os "/%%on bo%Cons/l%a ! neN "/%%on0 5 E&e*/%ar Cons/l%a 5 4$ Tex%Field %x8Cons/l%a ! neN Tex%Field0 V- 4$ Tex%>rea %xaSalida ! neN Tex%>rea0 ,-,JD 4$ Tex%Field %x8Es/ario ! neN Tex%Field0 V- 4$ Tex%Field %x8Cla'e ! neN Tex%Field0 V- 4$ Tex%Field %x8Erl ! neN Tex%Field0 V- 4$ S%rin1 s%rErl ! 55$ S%rin1 s%rEs/ario ! 55$ S%rin1 s%rCla'e ! 55$ 66 El ob&e%o Conne*%ion es par%e del >=I de JD"C, debe ser lo 66 primero (/e se ob%en1a, a (/e represen%a la *onexi;n e8e*%i'a 66 *on la "ase de Da%os Conne*%ion *on$ p/bli* s%a%i* 'oid main0 S%rin1 ar1s23 4 . &a'a+,-V 'en%ana ! neN &a'a+,-V04$ 5 4$

66 Se re*o1e el e'en%o de *ierre de la 'en%ana 'en%ana.addWindoNLis%ener0 neN WindoN>dap%er04 . p/bli* 'oid NindoNClosin10 WindoNE'en% e'% 4 . S s%em.exi%0 - 4$ 9 9 4$ 'en%ana.se%SiMe0 VD-,F-- 4$ 'en%ana.se%Ti%le0 5T/%orial de Ja'a, JD"C5 4$ 'en%ana.pa*Q04$ 'en%ana.se%Bisible0 %r/e 4$ 9 66 Cons%r/*%or de la *lase, (/e es el (/e *ons%r/ e el in%er8aM 66 (/e se 'a a mos%rar en la 'en%ana p/bli* &a'a+,-V04 . 66 Se :a*en %odos los *ampos de %ex%o edi%ables para (/e se 66 p/edan in%rod/*ir da%os, no se permi%e (/e se es*riba en 66 el Trea de %ex%o (/e se 'a a /%iliMar *omo salida de los 66 res/l%ados de las a**iones del /s/ario las resp/es%as (/e 66 se ob%en1an de la base de da%os a las *ons/l%as (/e se 66 reali*en %x8Cons/l%a.se%Edi%able0 %r/e 4$ %x8Es/ario.se%Edi%able0 %r/e 4$ %x8Erl.se%Edi%able0 %r/e 4$ %xaSalida.se%Edi%able0 8alse 4$ 66 Se 'a a /%iliMar el ?rid"a1La o/%, (/e a/n(/e *ompli*ado 66 en s/ /so, %iene la 8lexibilidad (/e se ne*esi%a en es%e 66 *aso *on*re%o ?rid"a1La o/% 1ridba1 ! neN ?rid"a1La o/%04$ ?rid"a1Cons%rain%s 1bCon ! neN ?rid"a1Cons%rain%s04$ 66 Lo 8i&amos *omo el la o/% a /%iliMar se%La o/%0 1ridba1 4$ 66 Se 8i&a el *olor la 8/en%e de *ara*%eres a /sar se%Fon%0 neN Fon%0 5Cel'e%i*a5,Fon%.=L>IN,,+ 4 4$ se%"a*Q1ro/nd0 Color.oran1e 4$ 66 No se :an 8i&ado los se%Cons%rain%s para el Label, para (/e 66 se as/man los de de8e*%o. El *ampo de %ex%o %x8Es/ario es 66 el Wl%imo *omponen%e en s/ 8ila, a %ra'Xs de 1bCon, 66 l/e1o se aYade al in%er8aM de /s/ario 1bCon.Nei1:%x ! ,.-$ 1bCon.Nei1:% ! -.-$ 1bCon.an*:or ! ?rid"a1Cons%rain%s.CENTER$ 1bCon.8ill ! ?rid"a1Cons%rain%s.NONE$ 1bCon.1ridNid%: ! ?rid"a1Cons%rain%s.REM>INDER$ add0 neN Label0 5Es/ario5 4 4$ 1ridba1.se%Cons%rain%s0 %x8Es/ario,1bCon 4$ add0 %x8Es/ario 4$ add0 neN Label0 5Cla'e de >**eso5 4 4$ 1ridba1.se%Cons%rain%s0 %x8Cla'e,1bCon 4$ add0 %x8Cla'e 4$ add0 neN Label0 5ERL de la "ase de Da%os5 4 4$ 1ridba1.se%Cons%rain%s0 %x8Erl,1bCon 4$ add0 %x8Erl 4$ 66 >:ora 'iene la 8ila en (/e es%T el bo%;n de Conexi;n a la

66 base de da%os, 8i&amos los *ons%rain%s para (/e eso sea asZ 66 lo aYadimos 1ridba1.se%Cons%rain%s0 bo%Conexion,1bCon 4$ add0 bo%Conexion 4$ 66 >:ora re1is%ramos el bo%;n para (/e re*iba los e'en%os del 66 ra%on a %ra'Xs del in%er8aM Mo/seLis%ener bo%Conexion.addMo/seLis%ener0 %:is 4$ 66 >:ora 'iene la Mona (/e permi%e in%rod/*ir el %ex%o de la 66 *ons/l%a (/e se (/iere realiMar el bo%;n (/e 'a a permi%ir 66 s/ en'Zo al dri'er JD"C add0 neN Label0 5Cons/l%a S@L5 4 4$ 1ridba1.se%Cons%rain%s0 %x8Cons/l%a,1bCon 4$ add0 %x8Cons/l%a 4$ 1ridba1.se%Cons%rain%s0 bo%Cons/l%a,1bCon 4$ add0 bo%Cons/l%a 4$ bo%Cons/l%a.addMo/seLis%ener0 %:is 4$ 66 >:ora se *olo*a /na e%i(/e%a en s/ propia lZnea para ro%/lar 66 el Trea de %ex%o en la (/e se 'an a presen%ar los res/l%ados 66 de las *ons/l%as (/e se reali*en Label labRes/l%ado ! neN Label0 5Res/l%ado5 4$ labRes/l%ado.se%Fon%0 neN Fon%0 5Cel'e%i*a5,Fon%.=L>IN,,L 4 4$ labRes/l%ado.se%Fore1ro/nd0 Color.bl/e 4$ 1ridba1.se%Cons%rain%s0 labRes/l%ado,1bCon 4$ 1bCon.Nei1:% ! ,.-$ add0 labRes/l%ado 4$ 66 >:ora se *ambia la 8orma de ex%ensi;n de la 'en%ana, para (/e 66 si se a1randa la 'en%ana %en1a la ma or par%e de espa*io 66 posible en la Mona de %ex%o en donde se presen%an los 66 res/l%ados 1ridba1.se%Cons%rain%s0 %xaSalida,1bCon 4$ %xaSalida.se%Fore1ro/nd0 Color.N:i%e 4$ %xaSalida.se%"a*Q1ro/nd0 Color.bla*Q 4$ add0 %xaSalida 4$ 9 p/bli* 'oid mo/seCli*Qed0 Mo/seE'en% e'% 4 . 66 C/ando se p/lsa el bo%;n Cons/l%a, se re*o1e el *on%enido del 66 *ampo de %ex%o %x8Cons/l%a se le pasa al mX%odo Sele*%, (/e 66 es el (/e 'a a realiMar la *ons/l%a de'ol'er el res/l%ado 66 (/e se 'a a presen%ar en la Mona de salida i80 e'%.1e%Componen%04 !! bo%Cons/l%a 4 . S s%em.o/%.prin%ln0 %x8Cons/l%a.1e%Tex%04 4$ %xaSalida.se%Tex%0 Sele*%0 %x8Cons/l%a.1e%Tex%04 4 4$ 9 66 Si se p/lsa el bo%;n de Conexi;n, se in%en%a es%able*er la 66 *onexi;n *on la base de da%os indi*ada en el *ampo de %ex%o 66 *orrespondien%e a ERL, *on el /s/ario *la'e (/e se :a an 66 indi*ado en los *ampos *orrespondien%es i80 e'%.1e%Componen%04 !! bo%Conexion 4 . 66 Se 8i&an las 'ariables 1lobales de /sa/rio, *la'e /rl a 66 los 'alores (/e se :a an in%rod/*ido en los *ampos s%rEs/ario ! %x8Es/ario.1e%Tex%04$ s%rCla'e ! %x8Cla'e.1e%Tex%04$

s%rErl ! %x8Erl.1e%Tex%04$ 66 La *rea*i;n de la *onexi;n *on la base de da%os lanMa /na 66 ex*ep*i;n en *aso de (/e :a a problemas al es%able*er esa 66 *onexi;n *on los aprTme%ros (/e se le indi(/en, por ello 66 es impres*indible *olo*ar el mX%odo 1e%Conne*%ion en /n 66 blo(/e %r 7*a%*:. Si se prod/*e al1Wn problema se lanMa 66 la ex*ep*i;n, apare*erT re8le&ada en la *onsola en el 66 Trea (/e se :a des%inado en la 'en%ana a 'er los res/l%ados %r . 66 >:ora se in%en%a *rear /na n/e'a ins%an*ia del dri'er (/e se 66 'a a /%iliMar. Ca 'arias 8ormas de espe*i8i*ar el dri'er (/e 66 se (/iere, e in*l/so se p/ede de&ar (/e sea el propio 66 Dri'erMana1er de JD"C (/e sele**ione el (/e *onsidere mTs 66 ade*/ado para *one*%arse a /na 8/en%e de da%os de%erminada Class.8orName0 5s/n.&db*.odb*.Jdb*Odb*Dri'er5 4$ 66 La *onexi;n a(/Z se realiMa indi*ando la ERL de la base de 66 da%os el /s/ario *la'e (/e dan a**eso a ella *on ! Dri'erMana1er.1e%Conne*%ion0 s%rErl,s%rEs/ario,s%rCla'e 4$ 66 Si la *onexi;n :a sido sa%is8a*%oria, *ambiamos el r;%/lo 66 del bo%;n de *onexi;n, para (/e indi(/e (/e si se p/lsa lo 66 (/e se realiMa serT la 5Re*onexi;n5 bo%Conexion.se%Label0 5Re*onexi;n a la "ase de Da%os5 4$ %xaSalida.se%Tex%0 5Conexion es%able*ida *on 5As%rErl 4$ 9 *a%*:0 Ex*ep%ion e 4 . 66 Se presen%a la in8orma*i;n *orrespondien%e al error, %an%o 66 en la *onsola *omo en la Mona de salida de la 'en%ana e.prin%S%a*QTra*e04$ %xaSalida.se%Tex%0 e.1e%Messa1e04 4$ 9

9 9

66 Se implemen%an 'a*Zos el res%o de los mX%odos del in%er8aM de 66 e'en%os del ra%;n, Mo/seLis%ener. Si se (/iere e'i%ar, %ambiXn es 66 posible /%iliMar Mo/se>dap%er, (/e %iene implemen%ados, pero sin 66 a**iones asi1nadas, %odos es%os mX%odos p/bli* 'oid mo/seEn%ered0 Mo/seE'en% e'% 4 .9 p/bli* 'oid mo/seExi%ed0 Mo/seE'en% e'% 4 .9 p/bli* 'oid mo/se=ressed0 Mo/seE'en% e'% 4 .9 p/bli* 'oid mo/seReleased0 Mo/seE'en% e'% 4 .9 66 Es%e es el mX%odo (/e realiMa la *ons/l%a p/bli* S%rin1 Sele*%0 S%rin1 *ons/l%a 4 . S%rin1 res/l%ado!55$ in% *ols$ in% pos$ 66 Ca 'arios mX%os (/e se 'an a emplear (/e lanMan ex*ep*iones 66 en *aso de (/e :a a al1Wn problema *on la *ons/l%a, o si se 66 rompe la *onexi;n, e%* %r . 66 En primer l/1ar, se ins%an*ia la *lase S%a%emen%, (/e es 66 ne*esaria para e&e*/%ar la *ons/l%a. La *lase Conne*%ion 66 de'/el'e /n ob&e%o S%a%emen% (/e se enlaMa a la *onexi;n 66 abier%a para pasar de n/e'o el ob&e%o S%a%emen%. >sZ es 66 *omo la ins%an*ia 5sen%en*ia5 se enlaMa a la *onexi;n a*%/al 66 *on la base de da%os

S%a%emen% sen%en*ia ! *on.*rea%eS%a%emen%04$ 66 El ob&e%o res/l%Se% %ambiXn es enlaMado *on la *onexi;n a la 66 base de da%os a %ra'Xs de la *lase S%a%emen%, (/e *on%iene el 66 mX%odo exe*/%e@/er , (/e de'/el'e /n ob&e%o Res/l%Se%. Res/l%Se% rs ! sen%en*ia.exe*/%e@/er 0 *ons/l%a 4$ 66 >:ora se /%iliMa el mX%odo 1e%Me%aDa%a en el res/l%ado para 66 de'ol'er /n ob&e%o Me%aDa%a, (/e *on%iene el mX%odo 1e%Col/mnCo/n% 66 /sado para de%erminar */Tn%as *ol/mnas de da%os es%Tn presen%es 66 en el res/l%ado. *ols ! 0 rs.1e%Me%aDa%a04 4.1e%Col/mnCo/n%04$ 66 >(/Z se /%iliMa el mX%odo nex% de la ins%an*ia 5rs5 de 66 Res/l%Se% para re*orrer %odas las 8ilas, /na a /na. Ca 8ormas 66 mTs op%imiMadas de :a*er es%o, /%iliMando la *ara*%erZs%i*a 66 inp/%S%ream del dri'er JD"C N:ile0 rs.nex%04 4 . 66 Se re*orre a:ora *ada /na de las *ol/mnas de la 8ila, es 66 de*ir, *ada *elda, /na a /na 8or0 pos!,$ pos R! *ols$ posAA 4 . 66 Es%e es el mX%odo 1eneral para obe%ener /n res/l%ado. el 66 mX%odo 1e%S%rin1 in%en%arT moldear el res/l%ado a /n S%rin1. 66 En es%e *aso solamen%e se re*o1e el res/l%ado se le aYade 66 /n espa*io %odo se aYade a la 'ariable 5res/l%ado5 res/l%ado A! rs.1e%S%rin10 pos 4A5 5$ 9 66 =ara *ada 8ila (/e se re'ise, se le aYade /n re%orno de 66 *arro, para (/e la si1/ien%e 8ila empie*e en o%ra lZnea res/l%ado A! 5[n5$ 9 66 Se *ierra la 5sen%en*ia5. En realidad se *ierran %odos los 66 *anales abier%os para la *ons/l%a pero la *onexi;n *on la 66 base de da%os permane*e sen%en*ia.*lose04$ 9 *a%*:0 Ex*ep%ion e 4 . e.prin%S%a*QTra*e04$ res/l%ado ! e.1e%Messa1e04$ 9 66 >n%es de salir, se de'/el'e el res/l%ado ob%enido re%/rn res/l%ado$ 9 9

JDBC y Servlets Anterior | Siguiente En esta parte del captulo dedicado a JDBC, se va a explorar el mundo de los servlets en el contexto de JDBC. Si el lector no est cmodo con el uso de servlets o con los conocimientos que posee, en el Tutorial se trata a fondo este tema, al que puede recurrir y luego regresar a este punto de su lectura. Hasta ahora se ha presentado la parte cliente del uso de JDBC, y en lo que se pretende adentrar al lector

es en el uso de JDBC en el servidor para generar pginas Web a partir de la informacin obtenida de una base de datos. Si el lector est familiarizado con CGI, podr comprobar que los servlets son mucho mejores a la hora de generar pginas Web dinmicamente, por varias razones: velocidad, eficiencia en el uso de recursos, escalabilidad, etc. La arquitectura de los servlets hace que la escritura de aplicaciones que se ejecuten en el servidor sea relativamente sencilla y, eso s, sean aplicaciones muy robustas. La principal ventaja de utilizar servlets es que se puede programar sin dificultad la informacin que va a proporcionar entre peticiones del cliente. Es decir, se puede tener constancia de lo que el usuario ha hecho en peticiones anteriores e implementar funciones de tipo rollback o cancel transaction (suponiendo que el servidor de base de datos las soporte). Adems, cada instancia del servlet se ejecuta dentro de un hilo de ejecucin Java, por lo que se pueden controlar las interacciones entre mltiples instancias; y al utilizar el identificador de sincronizacin, se puede asegurar que los servlets del mismo tipo esperan a que se produzca la misma transaccin, antes de procesar la peticin; esto puede ser especialmente til cuando mucha gente intenta actualizar al mismo tiempo la base de datos, o si hay mucha gente pendiente de consultas a la base de datos cuando sta est en pleno proceso de actualizacin. El ejemplo java2105.java, es un servlet, que junto con la pgina web asociada, java2105.html, y las dos bases de datos que utiliza, conforma un servicio completo de noticias o artculos. Hay un nmero determinado de usuarios que tienen autorizacin para enviar artculos, y otro grupo de usuarios que pueden ver los ltimos artculos. Por supuesto, que tambin se podra almacenar la fecha y la hora en que se colocan los artculos, y posiblemente tambin fuese til la categorizacin, es decir, colocarlos dentro de una categora como deportes, internacional, nacional, local, etc. De este modo, lo que aqu se esboza como la simple gestin de artculos, podra ser la semilla de un verdadero servicio de noticias. Pero el autor no pretende llegar a eso, sino simplemente presentar la forma en que se puede aunar la fuerza de JDBC y los servlets para poder acceder a una base de datos, introduciendo algunas caractersticas como la comprobacin de autorizacin, etc.; por ello, se ha huido conscientemente del uso de la palabra noticias, aunque el lector puede implementar sin demasiada dificultad. Como el lector es una persona lista, seguro que almacenar toda esta informacin en una base de datos de la forma mejor posible; de forma que se podra escribir un servlet que acumulase la informacin que le llegue en ficheros para luego proporcionarla, pero el manejo de todos estos archivos puede resultar engorrosa, y las bsquedas enlentecer el funcionamiento; as que, una base de datos es la mejor de las soluciones. Adems, tambin se quiere almacenar las contraseas para el acceso al sistema de artculos en una base de datos, en vez de en la configuracin del servidor Web. Hay dos razones fundamentales para ello; por una lado, porque es previsible que mucha gente utilice este servicio, y por otro lado, que debe ser posible asociar cada envo con una persona en particular. La inclusin en una base de datos ayudar a manejar gran cantidad de usuarios y adems a controlar quien enva artculos. Una mejora que se puede hacer al sistema es el desarrollo de un applet JDBC que permita aadir y quitar usuarios, o asignar privilegios a quien haya enviado algn artculo al Sistema. Las siguientes lneas de cdigo muestran las sentencias utilizadas en la creacin de las tablas e ndices que se van a utilizar en la aplicacin que se desarrollar para completar el Sistema de Artculos. El programa se ha pensado para atacar una base de datos Access, utilizando el puente JDBC-ODBC, si el

lector desea portarlo a otro driver JDBC, tendra que asegurarse de que las sentencias SQL que se utilizan estn soportadas por l.
CRE>TE T>"LE /s/arios 0 /s/ario B>RCC>R0,L4 NOT NELL, nombre B>RCC>R 0L-4 NOT NELL, empresa B>RCC>R 0L-4 NOT NELL, admi%irEn'io CC>R0,4 NOT NELL, *la'e B>RCC>R 0K4 NOT NELL 4$ CRE>TE INDE\ /s/arioPQe ON /s/arios0/s/ario4 WITC =RIM>R#$ CRE>TE T>"LE ar%i*/los 0 %i%/lo B>RCC>R0+DD4 NOT NELL, /s/ario B>RCC>R0,L4 NOT NELL, */erpo memo 4$ CRE>TE INDE\ ar%i*/loPQe ON ar%i*/los0/s/ario4$ CRE>TE INDE\ %i%/loPQe ON ar%i*/los0%i%/lo,/s/ario4$

Como se puede observar, solamente hay dos tablas. Si se quisiesen implementar las categoras, sera necesario incorporar una nueva tabla, o aadir un campo ms a la tabla de artculos. La clave primaria de la tabla de usuarios es el identificador de cada usuario, y en la tabla de artculos hay un ndice compuesto formado por el ttulo del artculo y el usuario que lo envi. Se usa un tipo MEMO (soportado pro Access, que puede ser BLOB en otros motores), para guardar el cuerpo del artculo. Una mejora, en caso de convertirlo en un sistema de noticias, consistira en aadir la fecha en que se ha enviado la noticia, como ya se ha comentado en un prrafo anterior, guardarla en un campo en la tabla de artculos y aadir el campo al ndice compuesto de esa tabla, con lo cual se podran presentar las noticias correspondientes a una fecha determinada sin aparente dificultad. En la tabla de usuarios se guarda el identificador por el que el sistema va a reconocer al usuario, junto con la contrasea que elija para comprobar su identificacin, ms su nombre completo, la empresa a que pertenece y si ese usuario tiene autorizacin para el envo de artculos al Sistema. Si un usuario no dispone de autorizacin para el envo, solamente podr acceder a la lectura de artculos. Y por supuesto, si alguien no aparece en esta tabla, no tendr acceso alguno al Sistema. Lo primero que hay que desarrollar es la pgina que va a dar acceso al sistema, para ver la forma de procesar los datos que van a llegar. La pgina es muy simple, java2105.html, y a continuacin se reproduce la imagen que presenta en el navegador y el cdigo html utilizado para generarla.

RCTMLS RCE>DS RTITLEST/%orial de Ja'a, JD"CR6TITLES R6CE>DS R"OD#S RFORM >CTION!5:%%p<66breo1an<K-K-6ser'le%6&a'a+,-D5 ENCT#=E!5x7NNN78orm7en*oded5 METCOD!5=OST5S RC+SRCENTERST/%orial de Ja'a, JD"CR6CENTERSR6C+S R=SRCENTERSR"SCon%rol de >r%Z*/losR6"SR6CENTERSR6=S R=SIn%rod/*e el nombre por el (/e %e re*ono*e es%e Sis%ema<R"RS RIN=ET N>ME!5/s/ario5 T#=E!5%ex%5 SIHE!5,L5 M>\LEN?TC!5,L5SR"RS In%rod/*e %/ *on%raseYa<R"RS RIN=ET N>ME!5*la'e5 T#=E!5passNord5 SIHE!5K5 M>\LEN?TC!5K5SR6=S Sele**iona la a**i;n (/e (/ieres realiMar< R=S RIN=ET N>ME!5a**ion5 T#=E!5s/bmi%5 B>LEE!5Leer >r%i*/los5S RIN=ET N>ME!5a**ion5 T#=E!5s/bmi%5 B>LEE!5En'io de >r%i*/los5S R6=S R6FORMS RIS=ara el en'Zo de ar%Z*/los se re(/iere a/%oriMa*i;n espe*ialR6IS R6"OD#S R6CTMLS

Lo primero que se necesita aclarar es cmo se van a procesar los datos del formulario. La pgina no puede ser ms sencilla, tal como se puede ver en la captura de su visualizacin en el navegador, con dos botones para seleccionar la accin a realizar. Si se quiere enviar un artculo, no es necesario introducir el nombre y clave en esta pgina, ya que el servlet enviar una nueva pgina para la introduccin del contenido del artculo, y ya sobre esa s que se establecen las comprobaciones de si el usuario est autorizado o no a enviar artculos al sistema.

La pgina que enva el servlet, es la que reproduce la imagen siguiente. Esta pgina se genera en el mismo momento en que el usuario solicita la insercin de un artculo. En caso de que haya introducido su identificacin en la pagina anterior, el servlet la colocar en su lugar, sino, la dejar en blanco.

La imagen reproduce la pgina ya rellena, lista para la insercin de un nuevo artculo en el sistema. Cuando se pulsa el botn de envo de artculo y el servlet recibe la peticin de insercin del artculo en el sistema, es cuando realiza la comprobacin de autorizacin, por una lado de si es un usuario reconocido para el sistema y, en caso afirmativo, si est autorizado al envo de artculo, o solamente puede leerlos. Debe recordar el lector, que los nombres de los campos de entrada de datos se pueden llamar con getParameter() y recoger la informacin que contienen. Los parmetros nombre y clave en el formulario se mapean en las variables usuario y clave en el servlet, que sern las que se utilicen para realizar las comprobaciones de acceso del usuario. El cdigo completo del servlet est en el fichero java2105.java, que se reproduce a continuacin.
impor% impor% impor% impor% impor% &a'a.io.)$ &a'a.ne%.)$ &a'a.s(l.)$ &a'ax.ser'le%.)$ &a'ax.ser'le%.:%%p.)$

p/bli* *lass &a'a+,-D ex%ends C%%pSer'le% . S%rin1 D"/rl ! 5&db*<odb*<T/%orial5$ S%rin1 /s/ario?e% ! 55$ S%rin1 /s/ario=os% ! 55$ S%rin1 *la'e?e% ! 55$ S%rin1 *la'e=os% ! 55$ Conne*%ion *on$ Da%abaseMe%aDa%a me%aDa%a$ 66 Es%e mX%odo es el (/e se en*ar1a de es%able*er e ini*ialiMar 66 la *onexi;n *on la base de da%os p/bli* 'oid ini%0 Ser'le%Con8i1 *on8 4 %:roNs Ser'le%Ex*ep%ion . S@LWarnin1 N$ s/per.ini%0 *on8 4$ %r . Class.8orName0 5s/n.&db*.odb*.Jdb*Odb*Dri'er5 4$ *on ! Dri'erMana1er.1e%Conne*%ion0 D"/rl,/s/ario=os%,*la'e=os% 4$ i80 0N ! *on.1e%Warnin1s044 U! n/ll 4 . N:ile0 N U! n/ll 4 . lo10 5S@LWarnin1< 5AN.1e%S@LS%a%e04AG[%GA N.1e%Messa1e04AG[%GAN.1e%ErrorCode04AG[%G 4$ N ! N.1e%Nex%Warnin104$ 9 9 9 *a%*:0 ClassNo%Fo/ndEx*ep%ion e 4 . %:roN neN Ser'le%Ex*ep%ion0 5ini%5 4$ 9 *a%*:0 S@LEx*ep%ion e 4 . %r . *on ! Dri'erMana1er.1e%Conne*%ion0 D"/rl,/s/ario?e%,*la'e?e% 4$ 9 *a%*:0 S@LEx*ep%ion ee 4 . ee.prin%S%a*QTra*e04$ N:ile0 e U! n/ll 4 . lo10 5S@LEx*ep%ion< 5Ae.1e%S@LS%a%e04AG[%GA e.1e%Messa1e04AG[%GAe.1e%ErrorCode04 4$ e ! e.1e%Nex%Ex*ep%ion04$ 9 %:roN neN Ser'le%Ex*ep%ion0 5ini%5 4$ 9 9 9 p/bli* 'oid ser'i*e0 C%%pSer'le%Re(/es% re(,C%%pSer'le%Response res 4 %:roNs Ser'le%Ex*ep%ion,IOEx*ep%ion . S%rin1 /s/ario ! re(.1e%=arame%er0 5/s/ario5 4$ S%rin1 a/%oriMado$ S%rin1 a**ion ! re(.1e%=arame%er0 5a**ion5 4$ %r . a/%oriMado ! a/%oriMa*ion0 re( 4$ i80 a**ion.e(/als0 5Leer >r%i*/los5 4 ]] Ua/%oriMado.e(/als0 5>CCESO DENE?>DO5 4 4 . leer>r%i*/lo0 re(,res 4$ 9 else i80 a**ion.e(/als0 5En'iar5 4 ]] a/%oriMado.e(/als0 5=OST5 4 4 . en'iar>r%i*/lo0 re(,res 4$ 9 else i80 a**ion.e(/als05En'io de >r%i*/los5 4 4 . i80 /s/ario !! n/ll 4

/s/ario ! 5 5$ =rin%Wri%er o/% ! neN =rin%Wri%er0 res.1e%O/%p/%S%ream04 4$ o/%.prin%ln0 5RCTMLS5 4$ o/%.prin%ln0 5RCE>DSRTITLESEn'Zo de >r%Z*/losR6TITLESR6CE>DS5 4$ o/%.prin%ln0 5R"OD#S5 4$ o/%.prin%ln0 5RCENTERSRC,SEn'Zo de >r%Z*/losR6C+SR6CENTERS5 4$ o/%.prin%ln0 5RFORM >CTION!:%%p<66breo1an<K-K-6ser'le%6&a'a+,-D5 4$ o/%.prin%ln0 5METCOD!=OSTS5 4$ o/%.prin%ln0 5RC+SEn'Zo de >r%Z*/losR6C+S5 4$ o/%.prin%ln0 5R=S=or es%e nombre %e re*ono*e el Sis%ema< R"RS5 4$ o/%.prin%ln0 5RIN=ET N>ME!/s/ario T#=E!%ex% B>LEE!G5A/s/arioA5G5 4$ o/%.prin%ln0 5SIHE!,L M>\LEN?TC!,LSR"RS5 4$ o/%.prin%ln0 5In%rod/*e %/ *on%raseYa< R"RS5 4$ o/%.prin%ln0 5RIN=ET N>ME!*la'e T#=E!passNord SIHE!K M>\LEN?TC!KS5 4$ o/%.prin%ln0 5R6=S5 4$ o/%.prin%ln0 5RCFSTZ%/lo del >r%Z*/lo a en'iar<R6CFS5 4$ o/%.prin%ln0 5R=SRIN=ET N>ME!%i%/lo T#=E!%ex% SIHE!+D5 4$ o/%.prin%ln0 5M>\LEN?TC!D-SR6=S5 4$ o/%.prin%ln0 5RCFSC/erpo del >r%Z*/loR6CFS5 4$ o/%.prin%ln0 5R=SRTE\T>RE> N>ME!*/erpo ROWS!,- COLS!D-S5 4$ o/%.prin%ln0 5R6TE\T>RE>SR6=S5 4$ o/%.prin%ln0 5R=SRIN=ET N>ME!a**ion T#=E!s/bmi% B>LEE!GEn'iarGS5 4$ o/%.prin%ln0 5R6FORMS5 4$ o/%.prin%ln0 5R6"OD#SR6CTMLS5 4$ o/%.8l/s:04$ 9 else . =rin%Wri%er o/% ! neN =rin%Wri%er0 res.1e%O/%p/%S%ream04 4$ o/%.prin%ln0 5R:%mlS5 4$ o/%.prin%ln0 5R:eadSR%i%leS>**eso Dene1adoR6%i%leSR6:eadS5 4$ o/%.prin%ln0 5Rbod S5 4$ o/%.prin%ln0 5Se :a prod/*ido /n error de a**eso<RbrS5 4$ o/%.prin%ln0 5El /s/ario o *la'e (/e :as in%rod/*ido no 5 4$ o/%.prin%ln0 5son 'Tlidos oRbrS5 4$ o/%.prin%ln0 5no %ienes a**eso a es%a 8/n*ionalidad.5 4$ o/%.prin%ln0 5R6bod SR6:%mlS5 4$ o/%.8l/s:04$ 9 9 *a%*:0 S@LEx*ep%ion e 4 . N:ile0 e U! n/ll 4 . lo10 5S@LEx*ep%ion< 5Ae.1e%S@LS%a%e04AG[%GA e.1e%Messa1e04AG[%GAe.1e%ErrorCode04AG[%G 4$ e ! e.1e%Nex%Ex*ep%ion04$ 9 66 >(/Z :abrZa (/e inser%ar el *;di1o ne*esario para res%able*er la 66 *onexi;n llamando a ini%04 de n/e'o 'ol'iendo a realiMar la 66 llamada al mX%odo ser'i*e0re(,res4 9

66 Se *ierra la *onexi;n *on la base de da%os p/bli* 'oid des%ro 04 . %r . *on.*lose04$ 9 *a%*:0 S@LEx*ep%ion e 4 . N:ile0 e U! n/ll 4 . lo10 5S@LEx*ep%ion< 5Ae.1e%S@LS%a%e04AG[%GA e.1e%Messa1e04AG[%GAe.1e%ErrorCode04AG[%G 4$ e ! e.1e%Nex%Ex*ep%ion04$

9 9 *a%*:0 Ex*ep%ion e 4 . e.prin%S%a*QTra*e04$ 9 9 66 Es%e mX%odo e&e*/%a la *ons/la%a a la base de da%os de'/el'e el 66 res/l%ado, para 8orma%ear la salida presen%ar el res/l%ado de 66 la *ons/l%a de ar%Z*/los al /s/ario p/bli* 'oid leer>r%i*/lo0 C%%pSer'le%Re(/es% re(,C%%pSer'le%Response res 4 %:roNs IOEx*ep%ion,S@LEx*ep%ion . S%a%emen% s%m% ! *on.*rea%eS%a%emen%04$ S%rin1 *ons/l%a$ Res/l%Se% rs$ res.se%S%a%/s0 res.SCPOK 4$ res.se%Con%en%T pe0 5%ex%6:%ml5 4$ *ons/l%a ! 5SELECT ar%i*/los.*/erpo,ar%i*/los.%i%/lo,5 4$ *ons/l%a A! ar%i*/los./s/ario,/s/arios.nombre,/s/arios.empresa 5$ *ons/l%a A! 5FROM ar%i*/los,/s/arios WCERE 5 4$ *ons/l%a A! ar%i*/los./s/ario!/s/arios./s/ario5$ rs ! s%m%.exe*/%e@/er 0 *ons/l%a 4$ =rin%Wri%er o/% ! neN =rin%Wri%er0 res.1e%O/%p/%S%ream04 4$ o/%.prin%ln0 5RCTMLS5 4$ o/%.prin%ln0 5RCE>DSRTITLES>r%Z*/los En'iadosR6TITLESR6CE>DS5 4$ o/%.prin%ln0 5R"OD#S5 4$ N:ile0 rs.nex%04 4 . o/%.prin%ln0 5RC+S5 4$ o/%.prin%ln0 rs.1e%S%rin10,4 4$ o/%.prin%ln0 5R6C+SRpS5 4$ o/%.prin%ln0 5RISEn'iado desde< 5Ars.1e%S%rin10D4A5R6ISR"RS 5 4$ o/%.prin%ln0 5R"S5Ars.1e%S%rin10+4A5R6"S, por 5Ars.1e%S%rin10V4 4$ o/%.prin%ln0 5RCRS5 4$ 9 o/%.prin%ln0 5R6"OD#SR6CTMLS5 4$ o/%.8l/s:04$ rs.*lose04$ s%m%.*lose04$ 9 p/bli* 'oid en'iar>r%i*/lo0 C%%pSer'le%Re(/es% re(,C%%pSer'le%Response res 4 %:roNs IOEx*ep%ion,S@LEx*ep%ion . S%a%emen% s%m% ! *on.*rea%eS%a%emen%04$ S%rin1 *ons/l%a ! 55$ S%rin1 /s/ario ! re(.1e%=arame%er0 5/s/ario5 4$ =rin%Wri%er o/% ! neN =rin%Wri%er0 res.1e%O/%p/%S%ream04 4$ res.se%S%a%/s0 res.SCPOK 4$ res.se%Con%en%T pe0 5%ex%6:%ml5 4$ o/%.prin%ln0 5RCTMLS5 4$ o/%.prin%ln0 5RCE>DSRTITLESEn'Zo RealiMadoR6TITLESR6CE>DS5 4$ o/%.prin%ln0 5R"OD#S5 4$ *ons/l%a ! 5INSERT INTO ar%i*/los B>LEES0 G5$ *ons/l%a A! re(.1e%=arame%er0 5%i%/lo5 4A5G,G5A/s/arioA5G,G5$ *ons/l%a A! re(.1e%=arame%er05*/erpo54A5G45$

in% res/l% ! s%m%.exe*/%eEpda%e0 *ons/l%a 4$ i80 res/l% U! - 4 . o/%.prin%ln0 5T/ ar%Z*/lo :a sido a*ep%ado e inser%ado5 4$ o/%.prin%ln0 5 *orre*%amen%e.5 4$ 9 else . o/%.prin%ln0 5Se :a prod/*ido /n error en la a*ep%a*i;n de %/ 5 4$ o/%.prin%ln0 5ar%Z*/lo.R"RS5 4$ o/%.prin%ln0 5Con%a*%a *on el >dminis%rador de la base de da%os, 5 4$ o/%.prin%ln0 5o *ons/l%aR"RS5 4$ o/%.prin%ln0 5el 8i*:ero RISlo1R6IS del ser'le%.5 4$ 9 o/%.prin%ln0 5R6"OD#SR6CTMLS5 4$ o/%.8l/s:04$ s%m%.*lose04$ 9 66 De'/el'e la in8orma*i;n del Ser'le% p/bli* S%rin1 1e%Ser'le%In8o04 . re%/rn 5Ser'le% JD"C 0T/%orial de Ja'a4, ,IIK5$ 9 p/bli* S%rin1 a/%oriMa*ion0 C%%pSer'le%Re(/es% re( 4 %:roNs S@LEx*ep%ion . S%a%emen% s%m% ! *on.*rea%eS%a%emen%04$ S%rin1 *ons/l%a$ Res/l%Se% rs$ S%rin1 'alido ! 55$ S%rin1 /s/ario ! re(.1e%=arame%er0 5/s/ario5 4$ S%rin1 *la'e ! re(.1e%=arame%er0 5*la'e5 4$ S%rin1 permiso!55$ *ons/l%a ! 5SELECT admi%irEn'io FROM /s/arios WCERE /s/ario ! G5A/s/ario$ *ons/l%a A! 5G >ND *la'e ! G5A*la'eA5G5$ rs ! s%m%.exe*/%e@/er 0 *ons/l%a 4$ N:ile0 rs.nex%04 4 . 'alido ! rs.1e%S%rin10,4$ 9 rs.*lose04$ s%m%.*lose04$ i80 'alido.e(/als0 55 4 4 . permiso ! 5>CCESO DENE?>DO5$ 9 else . 66 =ermiso s;lo para le*%/ra de ar%Z*/los i80 'alido.e(/als0 5N5 4 4 . permiso ! 5?ET5$ 66 =ermiso para le*%/ra en'Zo de ar%Z*/los 9 else i80 'alido.e(/als0 5S5 4 4 . permiso ! 5=OST5$ 9 9 re%/rn permiso$ 9

A continuacin se repasan los trozos de cdigo ms interesantes del servlet, tal como se ha hecho en

muchos de los ejemplos del Tutorial. Una de las primeras cosas que hay que hace es reconocer cuando se ha recibido una peticin correctamente, y para ello se utiliza el cdigo que aparece en la lnea siguiente:
res.se%S%a%/s0 res.SCPOK 4$

La lnea que sigue a sta, es la que indica que el contenido es HTML, porque la intencin del servlet es enviar respuestas en este formato al navegador. Esto se indica en la lnea:
res.se%Con%en%T pe0 5%ex%6:%ml5 4$

Otro trozo de cdigo interesante es el utilizado para saber cual de los botones de la pgina inicial se ha pulsado, en donde se recurre al mtodo getParameter() sobre el nombre del botn (accion), buscando los valores que se han asignado en el cdigo fuente, y procesar el que se haya pulsado de los dos. Las lneas de cdigo siguientes son las que realizan estas acciones.
S%rin1 a**ion ! re(.1e%=arame%er0 5a**ion5 4$ %r . a/%oriMado ! a/%oriMa*ion0 re( 4$ i80 a**ion.e(/als0 5Leer >r%i*/los5 4 ]] Ua/%oriMado.e(/als0 5>CCESO DENE?>DO5 4 4 . leer>r%i*/lo0 re(,res 4$ 9 else i80 a**ion.e(/als0 5En'iar5 4 ]] a/%oriMado.e(/als0 5=OST5 4 4 . en'iar>r%i*/lo0 re(,res 4$ 9 else i80 a**ion.e(/als05En'io de >r%i*/los5 4 4 . . . . 9 9 *a%*:0 S@LEx*ep%ion e 4 . . . . 9

Como se ha especificado en la pgina inicial de acceso un valor para cada uno de los botones, se sabe cuales deben buscarse y qu hacer para procesarlos. Tambin se pueden recoger todos los parmetros que hay en un formulario a travs del mtodo getParameterNames(). Una vez que se sabe el usuario y la clave, hay que comprobar esta informacin contra la base de datos. Para ello se utiliza una consulta para saber si el usuario figura en la base de datos. El cdigo que realiza estas acciones es el que se reproduce en las siguientes lneas.
p/bli* S%rin1 a/%oriMa*ion0 C%%pSer'le%Re(/es% re( 4 %:roNs S@LEx*ep%ion . S%a%emen% s%m% ! *on.*rea%eS%a%emen%04$ S%rin1 *ons/l%a$ Res/l%Se% rs$ S%rin1 'alido ! 55$ S%rin1 /s/ario ! re(.1e%=arame%er0 5/s/ario5 4$ S%rin1 *la'e ! re(.1e%=arame%er0 5*la'e5 4$ S%rin1 permiso!55$ *ons/l%a ! 5SELECT admi%irEn'io FROM /s/arios WCERE /s/ario ! G5A/s/ario$ *ons/l%a A! 5G >ND *la'e ! G5A*la'eA5G5$ rs ! s%m%.exe*/%e@/er 0 *ons/l%a 4$

N:ile0 rs.nex%04 4 . 'alido ! rs.1e%S%rin10,4$ 9 rs.*lose04$ s%m%.*lose04$ i80 'alido.e(/als0 55 4 4 . permiso ! 5>CCESO DENE?>DO5$ 9 else . 66 =ermiso s;lo para le*%/ra de ar%Z*/los i80 'alido.e(/als0 5N5 4 4 . permiso ! 5?ET5$ 66 =ermiso para le*%/ra en'Zo de ar%Z*/los 9 else i80 'alido.e(/als0 5S5 4 4 . permiso ! 5=OST5$ 9 9 re%/rn permiso$ 9

Para realizar las consultas a la base de datos, es necesario crear una conexin con ella. Para hacerlo se utiliza el mtodo init() de la clase HttpServlet, en donde se instancia la conexin con el servidor de base de datos, como se muestra en las lneas de cdigo siguientes.
S%rin1 D"/rl ! 5&db*<odb*<T/%orial5$ . . . %r . Class.8orName0 5s/n.&db*.odb*.Jdb*Odb*Dri'er5 4$ *on ! Dri'erMana1er.1e%Conne*%ion0 D"/rl,/s/ario=os%,*la'e=os% 4$ . . .

Esta es solamente la parte de la conexin, hay ms cdigo implicado, pero ya se han visto bastantes ejemplos. No obstante, hay que tener en cuenta que la conexin se puede romper normalmente por tiempo, es decir, que si no se realizan acciones contra la base de datos en un tiempo determinado, la conexin se rompe. As que, una de las cosas que debe controlar el lector, si va a utilizar este cdigo es introducir la reconexin en la parte de cdigo que trata la excepcin de SQL.. Una vez creada la conexin, hay que realizar consultas para la lectura de datos. El siguiente cdigo hace esto, consultando la base de datos y recogiendo la informacin de todos los artculos. Se puede incorporar fcilmente un nuevo campo con la fecha, para obtener los artculos ordenados por la fecha en que ha sido enviados, o realizar consultas diferentes para obtener los artculos ordenados por usuario, etc.
*ons/l%a ! 5SELECT ar%i*/los.*/erpo,ar%i*/los.%i%/lo,5 4$ *ons/l%a A! ar%i*/los./s/ario,/s/arios.nombre,/s/arios.empresa 5$ *ons/l%a A! 5FROM ar%i*/los,/s/arios WCERE 5 4$ *ons/l%a A! ar%i*/los./s/ario!/s/arios./s/ario5$ rs ! s%m%.exe*/%e@/er 0 *ons/l%a 4$ =rin%Wri%er o/% ! neN =rin%Wri%er0 res.1e%O/%p/%S%ream04 4$ o/%.prin%ln0 5RCTMLS5 4$ o/%.prin%ln0 5RCE>DSRTITLES>r%Z*/los En'iadosR6TITLESR6CE>DS5 4$

o/%.prin%ln0 5R"OD#S5 4$ N:ile0 rs.nex%04 4 . o/%.prin%ln0 5RC+S5 4$ o/%.prin%ln0 rs.1e%S%rin10,4 4$ o/%.prin%ln0 5R6C+SRpS5 4$ o/%.prin%ln0 5RISEn'iado desde< 5Ars.1e%S%rin10D4A5R6ISR"RS 5 4$ o/%.prin%ln0 5R"S5Ars.1e%S%rin10+4A5R6"S, por 5Ars.1e%S%rin10V4 4$ o/%.prin%ln0 5RCRS5 4$ 9 o/%.prin%ln0 5R6"OD#SR6CTMLS5 4$ o/%.8l/s:04$ rs.*lose04$ s%m%.*lose04$ 9

Aqu se llama al mtodo getString() de cada columna de cada fila, ya que cada fila corresponde a un artculo. La figura siguiente muestra el resultado de la ejecucin de una consulta de este tipo.

Otra parte interesante del cdigo es la que se encarga del envo de los artculos y su insercin en la base de datos. Esto se realiza en las lneas que se muestran. Las cuestiones de autorizacin se encargan a otro mtodo, as que en este no hay porqu considerarlas.
*ons/l%a ! 5INSERT INTO ar%i*/los B>LEES0 G5$

*ons/l%a A! re(.1e%=arame%er0 5%i%/lo5 4A5G,G5A/s/arioA5G,G5$ *ons/l%a A! re(.1e%=arame%er05*/erpo54A5G45$ in% res/l% ! s%m%.exe*/%eEpda%e0 *ons/l%a 4$ i80 res/l% U! - 4 . o/%.prin%ln0 5T/ ar%Z*/lo :a sido a*ep%ado e inser%ado5 4$ o/%.prin%ln0 5 *orre*%amen%e.5 4$ 9 else . o/%.prin%ln0 5Se :a prod/*ido /n error en la a*ep%a*i;n de %/ 5 4$ o/%.prin%ln0 5ar%Z*/lo.R"RS5 4$ o/%.prin%ln0 5Con%a*%a *on el >dminis%rador de la base de da%os, 5 4$ o/%.prin%ln0 5o *ons/l%aR"RS5 4$ o/%.prin%ln0 5el 8i*:ero RISlo1R6IS del ser'le%.5 4$ 9 o/%.prin%ln0 5R6"OD#SR6CTMLS5 4$ o/%.8l/s:04$ s%m%.*lose04$ 9

Con esto, se ha presentado al lector un ejemplo en el que se accede a la base de datos desde el servidor, y la parte cliente se limita a utilizar los recursos del servidor Web para acceder a la informacin de la base de datos. El ejemplo es especfico para servlets HTTP, aunque se pueden escribir servlets que devuelvan tipos binarios en lugar de una pgina html; Por ejemplo, se puede fijar el tipo de contenido a image/gif y utilizar el controlador de OutputStream para escribir una imagen gif que se construya en el mismo momento al navegador. De este modo se pueden pasar imgenes que estn almacenadas en la base de datos del servidor a la parte cliente, en este caso, el navegador. Introduccin a SQL Anterior | Siguiente Esta seccin viene a intentar introducir un poco al lector que no conoce SQL, en su mundo y a entender mejor los ejemplos que se han propuesto. No se intenta hacer un manual de SQL, sino simplemente recordar algunas de las caractersticas y comandos de este lenguaje. Como JDBC requiere que los drivers sean compatibles con la versin estndar ANSI SQL-92, esa ser la que se comente, aunque en la actualidad SQL sigue evolucionando y mejorando, pasando de ser un sublenguaje de manejo de datos a un verdadero lenguaje de programacin, pero hay que tener siempre presente que una de las primeras frases que aparece en la especificacin oficial de JDBC es: "In order to pass JDBC compliance tests and to be called JDBC compliant, we require that a driver support at least ANSI SQL-92 Entry Level" Lo cual es claramente imposible de cumplir con drivers para sistemas de manejo de bases de datos antiguos (DBMs) y para algunas versiones de SQL particularizadas por los fabricantes de algunos de los sistemas de bases de datos ms evolucionados. El Modelo Relacional Aunque SQL est basado en el modelo relacional, no representa una implementacin excesivamente rgida. En l, las unidades bsicas son tablas, columnas y filas. Si se habla estrictamente en trminos

relacionales, la relacin es mapeada en una tabla y proporciona una forma de relacionar los datos dentro de una tabla de forma simple. Una columna representa un dato presente en la tabla, mientras que una fila representa un registro, o entrada, de la tabla. Cada fila contiene un valor determinado para cada una de las columnas (un valor puede estar vaco, o indefinido, y ser considerado vlido). La tabla se puede visualizar como una matriz, con las columnas en vertical y las filas en horizontal. La tabla siguiente Empleados, por ejemplo, se podra utilizar para almacenar los empleados de una empresa.

Unas cuantas reglas sintcticas bsicas de SQL, sobre las que el lector debe prestar especial atencin, o tener cuidado, son:

SQL no es sensible a los espacios en blanco. Los retornos de carro, tabuladores y espacios en blanco no tienen ningn significado especial a la hora de la ejecucin de sentencias. Las palabras clave y comandos estn delimitados por comas (,), cuando es necesario, y se utilizan parntesis para agruparlos. Cuando se realizan mltiples consultas a un mismo tiempo, se debe utilizar el punto y coma (;) para separar cada una de las consultas. Las consultas no son sensibles a maysculas o minsculas. Sin embargo, hay que prestar mucha atencin, porque aunque en las palabras clave no importe el que estn en maysculas o minsculas, en las cadenas que se almacenen en las tablas como valores s que permanece el que se hayan introducido en maysculas o minsculas; y hay que tener esto presente, sobre todo a la hora de hacer comparaciones.

Aunque se pueden tener todos los datos en una sola tabla, no es habitual que esto sirva para todos los casos. Por ejemplo, si en la tabla anterior de Empleados, se quisiera ahora aadir informacin sobre los departamentos de la empresa y en cules estn adscritos los empleados, se podra aadir a esa misma tabla; sin embargo, el propsito de la tabla Empleados es almacenar datos sobre los empleados, no sobre la empresa. La solucin consiste en crear otra tabla, Departamentos, en donde guardar la informacin especfica de los departamentos de la empresa. Para asociar un empleado con un departamento, solamente habra que aadir una columna a la tabla Empleados para guardar el nombre o nmero del departamento. Ahora que ya estn colocados los empleados en cada departamento, se puede incorporar otra tabla para guardar informacin de los Proyectos en que estn involucrados.

Ahora est ms claro cmo estn separados lgicamente los datos. Este proceso es el que ms tiempo requiere en el desarrollo de una base de datos, y representa el primer nivel en donde se declara el esquema de las relaciones. El esquema de la bases de datos es el contenedor de ms alto nivel que la define como una coleccin de tablas, en donde cada tabla cae dentro de un esquema. Del mismo modo, un catlogo es una entidad que puede englobar a varios esquemas. Esta abstraccin es precisamente la parte ms necesaria dentro de un robusto sistema relacional de bases de datos (RDBMs). La razn principal de una base de datos es el acceso a la informacin, es decir, facilitar que se pueda leer una tabla, que se pueda cambiar la informacin que contiene, y tambin que se puedan crear y destruir tablas. Adems, permite que se establezcan niveles de seguridad, pro ejemplo, se puede incorporar otra tabla, llamada Condifencial, para guardar la direccin, telfono y sueldo de cada empleado, que tendr que estar colocada en un esquema separado para que solamente el departamento de tesorera pueda acceder a esos datos. Si se observan las tablas anteriores, las tres se encuentran enlazadas. La tabla Empleados contiene una columna que contiene el nmero del departamento al que pertenece cada empleado. Este nmero de departamento tambin aparece en la tabla Departamentos, que describe cada departamento de la empresa. Las tablas Empleados y la nueva Confidencial, estn relacionadas, pero todava se necesita incorporar una entrada en una de las tablas que permita acceder a la otra, para hacer una distincin con el nmero de empleado. El enlace que se ha establecido, entre nmero de empleado y nmero de departamento, se conoce como ndice (key). Un ndice se utiliza para identificar informacin dentro de una tabla. Cada empleado individual o departamento, deberan tener un nico ndice para facilitar posteriores acciones sobre las tablas. Segn el modelo relacional, el ndice se supone nico dentro de una tabla, ninguna otra entrada en la tabla debe tener el mismo ndice primario, o clave primaria. Una sola columna suele ser suficiente para identificar inequvocamente a una fila o entrada. Sin embargo, tambin se puede usar una combinacin de filas para componer un ndice primario. Por

ejemplo, se puede utilizar una combinacin del departamento y sede de ese departamento para componen su clave primaria. En SQL, las columnas definidas como claves primarias, deben estar definidas, no pueden ser nulas. Lo mejor es, pues, repartir los datos en tablas donde se encuentren lgicamente asociados; aunque, puede ser que haya datos que deban estar en ms de una tabla, como es en este caso el nmero de empleado, que debe estar en la tabla Empleados y en la tabla Confidencial. Se puede necesitar tener la seguridad de que si una fila existe en una tabla, es necesario que exista la correspondiente fila en la tabla relacionada; en el ejemplo, se puede decir que por cada entrada en la tabla de Empleados debe haber otra entrada en la tabla Confidencial. Esta asociacin se puede solidificar con el uso de claves ajenas, donde una columna determinada en una tabla depende de otra columna en la tabla padre. En esencia, se est construyendo una columna virtual en una tabla, en base a una columna real de otra tabla. En el ejemplo, se ha enlazado la columna con el nmero del empleado de la tabla Confidencial al nmero de empleado de la tabla Empleados; se est indicando que el nmero de empleado es un ndice en la tabla Confidencial, de ah el trmino de clave ajena. Una clave primaria tambin puede contener una clave ajena si es necesario. La forma en que se modelan los datos y las tcnicas que se utilizan para construir claves primarias y ajenas, caen dentro del diseo de bases de datos, que esta pequea introduccin a SQL no puede abordar. Creacin de Tablas La sentencia CREATE TABLE es la que se usa para crear una tabla. Es una operacin importante pero muy sencilla. Hay algunas fuentes de datos que solamente admiten en las tablas elementos muy simples, como por ejemplo, las fuente de texto accedidas a travs de ODBC. El formato de la sentencia es:
CRE>TE T>"LE Rnombre %ablaS 0Relemen%o *ol/mnaS 2,Relemen%o *ol/mna3...4

El elemento columna se declara de la forma:


Rnombre *ol/mnaS R%ipo de da%oS 2DEF>ELT Rexpresi;nS3 2R*ons%an%e *ol/mnaS 2,R*ons%an%e *ol/mna3...3

Siendo constante columna quien indica la forma o caracterstica de la columna, que puede ser:
NOT NELL ^ ENI@EE ^ =RIM>R# KE#

Siguiendo con el ejemplo, en este caso lo nico que hay que tener presente es que es necesario definir la tabla de referencia, en este caso Empleados, antes de definir la tabla que hace referencia a ella, en este caso Confidencial. La tabla Empleados se creara de la siguiente forma:
CRE>TE T>"LE Empleados 0 empleado CC>R0D4 =RIM>R# KE#, apellido B>RCC>R0+-4 NOT NELL, nombre B>RCC>R0+-4 NOT NELL, *a%e1oria B>RCC>R0+-4 NOT NELL,

depar%men%o B>RCC>R0+-4 4$

En la creacin de la tabla se utilizan dos tipos de datos para especificar cadenas: CHAR y VARCHAR. El sistema de base de datos utiliza exactamente la cantidad de espacio que se indique cuando se utiliza un tipo de datos CHAR; en caso de que se indique que una entrada es de tipo CHAR(n) y se rellene con una cena de tamao inferior a n, los caracteres que resten se rellenan con espacios. Con VARCHAR, se almacena exactamente la cadena que se indique, el tamao que se indica en la creacin solamente sirve para fijar el tamao mximo del valor que se puede almacenar. Tambin se utiliza la directiva NOT NULL que hace que se compruebe cada una de las entradas en la columna. La creacin de la tabla Confidencial es igualmente sencilla, la nica diferencia es la incorporacin de la palabra clave REFERENCES para que esta tabla pueda utilizar el atributo correspondiente al nmero de empleado de la tabla Empleados como su clave primaria.
CRE>TE T>"LE Con8iden*ial 0 empleado CC>R0D4 =RIM>R# KE#, dire**ion B>RCC>R0D-4, %ele8ono B>RCC>R0,+4, s/eldo DECIM>L, FOREI?N KE#0 empleado 4 REFERENCES Empleados0 empleado 4 4$

La sentencia para eliminar una tabla es DROP TABLE, que es igual de sencilla que la sentencia de creacin, y su forma es:
DRO= T>"LE Rnombre %ablaS

Recuperar Informacin La sentencia SELECT es la que se utiliza cuando se quieren recuperar datos de la informacin almacenada en un conjunto de columnas. Las columnas pueden pertenecer a una o varias tablas y se puede indicar el criterio que deben seguir las filas de informacin que se extraigan. Muchas de las clusulas que permite esta sentencia son simples, aunque se pueden conseguir capacidades muy complejas a base de una gramtica ms complicada. Desde luego, la mejor forma de entender el proceso de consulta a la base de datos y el uso de las clusulas que modifican al comando SELECT, es pensar en trminos de conjuntos matemticos. SQL, al igual que todos los lenguajes de cuarta generacin est diseado para responder a cuestiones de tipo Qu quiero hacer?, al contrario que los otros lenguajes de programacin, como Java y C++, que intentan resolver cuestiones del tipo Cmo lo hago?. El dominio de las consultas SQL no es una tarea sencilla, pero con un poco de sentido comn y algo de intuicin se pueden conseguir resultados muy eficientes, gracias al modelo relacional en el que se base SQL. La sintaxis de la sentencia es:
SELECT 2>LL ^ DISTINCT3 Rsele**ionS FROM R%ablasS WCERE R*ondi*iones de sele**ionS

2ORDER "# R*ol/mnaS 2>SC ^ DESC3 2,R*ol/mnaS 2>SC ^ DESC33...3

La seleccion contiene normalmente una lista de columnas separadas por coma (,), o un asterisco (*) para seleccionarlas todas. Un ejemplo ejecutado contra una de las tablas creadas anteriormente podra ser:
SELECT ) FROM Empleados$

Que devolvera el contenido completo de la tabla. Si solamente se quieren conocer los empleados del departamento 022, la consulta sera:
SELECT ) FROM Empleados WCERE depar%amen%o ! G-++G$

Para ordenar la lista resultante por apellidos, por ejemplo, se usara la directiva ORDER BY:
SELECT ) FROM Empleados WCERE depar%amen%o ! G-++G ORDER "# apellido$

Si lo que se quiere, adems de que la lista est ordenada por apellido, es ver solamente el nmero de empleado, se consultara de la forma:
SELECT empleado FROM Empleados WCERE depar%amen%o ! G-++G ORDER "# apellido$

Si se quieren resultados de dos tablas a la vez, tampoco hay problema en ello, tal como se muestra en la siguiente sentencia:
SELECT Empleados.), Con8iden*ial.) FROM Empleados, Con8iden*ial$

Tambin se pueden realizar consultas ms complicadas; por ejemplo, mostrar el sueldo de los empleados del departamento 022. Segn las tablas, la informacin del sueldo se encuentra en la tabla Confidencial, y el departamento al que est adscrito un empleado se encuentra en la tabla Empleados. Para asociar una comparacin de una tabla con otra, se puede utilizar las referencia la nmero de empleado en la tabla Confidencial desde la tabla Empleados. Se pueden especificar los empleados que pertenecen a un departamento y utilizar los nmeros de empleados resultantes para obtener la informacin sobre su sueldo desde la tabla Confidencial.
SELECT *.s/eldo FROM Empleados >S e, Con8iden*ial >S * WCERE e.depar%men%o ! G-++G >ND *.empleado ! e.empleado$

Aqu se ha declarado algo parecido a una variable con la clusula AS. Ahora se pueden hacer referencias a campos especficos de la tabla utilizando un punto (.), como si se tratase de un objeto. Se puede, por ejemplo, determinar cuntos empleados de la empresa tienen un sueldo por encima de los

1200 euros.
SELECT salar FROM Con8iden*ial WCERE s/eldo S ,+--$

Y tambin se pueden conocer los empleados del departamento 022 que cobran ms de los 1200 euros.
SELECT *.s/eldo FROM Empleados >S e, Con8iden*ial >S * WCERE e.depar%men%o ! G-++G >ND *.empleado ! e.empleado >ND *.s/eldo S ,+--$

Tambin se pueden realizar un cierto nmero de funciones en SQL, incluyendo algunos clculos matemticos y estadsticos. Por ejemplo, se puede saber la media de sueldo de los empleados del departamento 022 de la siguiente forma:
SELECT >B?0 *.s/eldo 4 FROM Empleados as e, Con8iden*ial as * WCERE e.depar%men%o ! G-++G >ND *.empleado ! e.empleado$

Desde luego, las posibilidades que ofrece SQL exceden en mucho el alcance de este captulo y los pocos ejemplos que se han presentado. Adems, como el inters del autor es introducir a JDBC, tampoco es necesario el uso de ejemplos complejos. Si el lector tiene inters en aprender ms sobre SQL, debera recurrir a uno de los muchos y buenos libros que hay publicados sobre ello. Almacenar Informacin La sentencia INSERT se utiliza cuando se quieren insertar filas de informacin en las columnas. Aqu tambin se pueden presentar diferentes capacidades, dependiendo del nivel de complejidad soportado. La sintaxis de la sentencia es:
INSERT INTO Rnombre %ablaS 20Rnombre *ol/mnaS 2,Rnombre *ol/mna3...43 B>LEES 0RexpresionS 2,RexpresionS3...4

Por ejemplo, en la tabla de los Empleados se podra ingresar uno nuevo con la siguiente informacin:
INSERT INTO Empleados B>LEES 0 _---LL_, _?arrido_, _J/an_, _In1eniero_ , _-++_ 4$

Si la gramtica del driver utilizado lo soporta, se puede utilizar una clusula SELECT para cargar varias columnas a la vez. La sentencia DELETE es la que se emplea cuando se quieren eliminar filas de las columnas, y su gramtica tambin es muy simple:
DELETE FROM Rnombre %ablaS WCERE R*ondi*ion b/s(/edaS

Si no se especifica la clusula WHERE, se eliminar el contenido de la tabla completamente, sin eliminar la tabla, por ejemplo:
DELETE FROM Empleados$

Vaciar completamente la tabla, dejndola sin ningn dato en las columnas, es decir, esencialmente lo que hace es borrar todas las columnas de la tabla. Especificando la clusula WHERE, se puede introducir un criterio de seleccin para el borrado, por ejemplo:
DELETE FROM Empleados WCERE empleado!_----,_$

Tambin se pueden borrar mltiples filas en esta operacin, siempre que la clusula WHERE permita seleccionar ms de una fila, todas ellas sern eliminadas. Para actualizar filas ya existentes en las columnas, se utiliza la sentencia UPDATE, cuya gramtica es mnima:
E=D>TE Rnombre %ablaS SET Rnombre *ol/mna ! 0 RexpresionS ^ NELL 4 2, Rnombre *ol/mna ! 0 RexpresionS ^ NELL 43... WCERE R*ondi*ion b/s(/edaS

Este comando permite cambiar uno o ms campos existentes en una fila. Por ejemplo, para cambiar el nombre de un empleado en la tabla de Empleados, se hara:
E=D>TE Empleados SET nombre ! G=edro J/anG WCERE empleado!G---,+G$

Cdigo Independiente y Portable De nuevo, tenga el lector presente que lo que a continuacin se refleja son simples opiniones y sugerencias, que solamente estn destinadas a que los problemas que se presenten sean los menos posibles, cuando se intente programar con Java, y en este caso, con JDBC. Uno de los objetivos fundamentales a la hora de disear JDBC fue obtener la mxima portabilidad posible entre distintos Sistemas de Gestin de Bases de Datos. Distintos gestores tienden a utilizar distinta sintaxis para las mismas cosas, como por ejemplo para especificar una fecha, ejecutar un procedimiento almacenado, etc. JDBC proporciona una serie de clusulas de escape de modo que se pueda escribir una fecha, etc., de forma portable: ser luego el driver el que se encargue de convertir la informacin al formato que requiere la base de datos. Todas las clusulas de escape se escriben siempre entre llaves, "{...}". Una fecha se especifica utilizando el formato {d 'aaaa-mm-dd'}, donde d indica que se est hablando de una fecha, y aaaa sern los cuatro dgitos correspondientes a un ao, mm los dos dgitos del mes, y dd los dos dgitos del da. Una hora se escribir utilizando el formato {t 'hh:mm:ss'}, donde se usa hh para la hora, mm para los minutos, y ss para los segundos. Para un valor de fecha/hora se utilizar {ts 'aaaa-mm-dd hh:mm:ss.f . . .'}, donde f, la parte fraccionaria de los segundos, es optativo.

No slo se utilizan clusulas de escape para las constantes de fecha y hora, tambin para llamar a un procedimiento almacenado hay una sintaxis especial que permite aislarse de la sintaxis concreta de cada base de datos: el formato ser {call nombre_proc[(?, ?, . . .)]}, donde call indica que se est invocando un procedimiento almacenado, nombre_proc ser su nombre, y los distintos parmetros, si los hay, se indicarn mediante una serie de caracteres de interrogacin, ?, encerrados entre parntesis. Tambin para invocar una funcin SQL existe una clusula de escape, con la sintaxis {fn upper( "Texto")}, donde fn indica que estamos llamando a una funcin, de nombre upper, y a la que se le pasa el argumento "Texto". Tambin hay clusulas de escape para las composiciones externas (outer-joins), utilizando la sintaxis {oj outer-join}, donde outer-join tiene la forma :
%abla LEFT OETER JOIN .%abla ^ o/%er7&oin9 ON *ondi*i;nPdePbWs(/eda

A la hora de utilizar dentro de un SELECT la palabra reservada LIKE se pueden usar dos caracteres como comodn, (_) y (%). Para buscar en la base de datos un texto en que aparezcan estos dos caracteres, basta con poner delante de ellos un carcter especial que indique que en ese lugar se utilizan como cualquier otro carcter, no como comodines. Para ello, se debe indicar cul es dicho carcter especial utilizando la sintaxis {escape 'carcter'}, por ejemplo
SELECT nombre FROM Empleados WCERE nombre LIKE G`PG .es*ape G`G9

En este ejemplo, se indica que el carcter especial de escape es @, por lo que la cadena LIKE '@_' indica que se deben buscar todos los nombre que comiencen por '_', en lugar de usarlo como comodn. Si se quiere escribir cdigo JDBC para que sea portable e independiente de la mquina y motor de base de datos que se va a atacar, deberan, adems de tener en cuenta las recomendaciones anteriores, seguirse unas sencillas reglas a la hora de escribir cdigo. Algunas de ellas son las que se recogen en los siguientes prrafos.

Presrvese siempre el uso de maysculas y minsculas de la salida de los mtodos getTables() y getColumns() Llamar al mtodo getIdentifierQuoteString() y utilizar la cadena que devuelva para delimitar los identificadores Tener en cuenta que no todos los sistemas soportan SQL 92 estrictamente Utilcese setNull()
=reparedS%a%emen% s%m% ! *on.prepareS%a%emen%0 5/pda%e nombre se% depar%amen%o ! a N:ere empleado ! ---,+5 4$ s%m%.se%S%rin10 ,,55 4$ 66 Err;neoUU s%m%.se%N/ll0 , 4$ s%m%.exe*/%eEpda%e04$

Comprobar los lmites de la sesin con getMaxStatements() y getMaxConnections(). Por ejemplo, Microsoft SQL restringe a una sola sentencia activa y hay algunos drivers que limitan las conexiones a una sola

Utilizar las comillas ...pero no en todas partes Las pseudo-columnas nunca deben ir entre comillas. Por ejemplo, filaid, regid, usuario, empleado Tener cuidado con algunas cosas de SQL 92:
5sele*% ) 8rom Empleados N:ere empleado ! NELL5 66 n/n*a de'/el'e 8ilasU 5sele*% ) 8rom Empleados N:ere empleado is NELL5 66 p/ede de'ol'er 8ilas 5sele*% ) 8rom Empleados N:ere empleado ! a5 66 /sar se%N/ll para el parTme%ro 66 n/n*a de'ol'erT 8ilas

Tener cuidado con los Nombres, si supportSchemasInDataManipulation() indica que s se pueden soportar esquemas, utilizar siempre un punto (.) entre el nombre del esquema y el nombre de la tabla. No olvidar las comillas! A la hora de crear una tabla usar getTypeInfo() y buscar entre el resultado las mejores opciones. Por ejemplo, si se quiere crear una columna DECIMAL(8,0), buscar un SQL DECIMAL o SQL NUMERIC, luego SQL INTEGER, luego SQL DOUBLE o SQL FLOAT, luego SQL CHAR o SQL VARCHAR; e ignorar tipos que no coincidan con los requerimientos: moneda, autoincremento, etc. Utilizar parmetros en lugar de constantes en las sentencias SQL Algunas bases de datos no soportan constantes cadena para columnas LONG Usar setObject(), que reduce la complejidad del programa. Por ejemplo, si se usan buffers de cadenas, entonces es necesario setObject() Para parmetros de salida, no olvidarse de utilizar registerOutParameter()

También podría gustarte