Está en la página 1de 48

1. INTRODUCCION.................................................................................................................

4
1.1Qu es JDBC?................................................................................................................ 4
1.1.1 Qu hace JDBC?......................................................................................................5
1.1.2 JDBC es un API de bajo nivel y una base a!a API"s de al#o nivel......................... 5
1.1.$ JDBC %!en#e a &DBC y o#!os API"s......................................................................... '
1.1.5 (Q) Con%o!*e......................................................................................................... +
1.2 Productos JDBC............................................................................................................ 9
1.2.1 Java(o%# ,!a*e-o!................................................................................................1/
1.2.2 0ios de d!ive!s JDBC........................................................................................... 11
2. CONEXIN....................................................................................................................... 12
2.1 Vista Preliminar.......................................................................................................... 12
2.1.1 Ae!#u!a de una cone1i2n.......................................................................................12
2.1.2 3so 4ene!al de 35)"s............................................................................................ 12
2.1.$ JDBC y 35)"s....................................................................................................... 1$
2.1.6 7l sub!o#ocolo 8odbc9.......................................................................................... 15
2.1.5 5e4is#!o de sub!o#ocolos...................................................................................... 15
2.1.' 7nv:o de (en#encias (Q)....................................................................................... 1'
2.1.; 0!ansacciones......................................................................................................... 1;
2.1.+ <iveles de aisla*ien#o de #!ansacciones................................................................ 1+
3. LA CLASE DriverManager............................................................................................... 19
3.1 Vista preliminar...........................................................................................................19
$.1.1 =an#eni*ien#o de la lis#a de d!ive!s disonibles................................................... 1>
$.1.2 7s#ablece! una cone1i2n......................................................................................... 2/
4. LA CLASE Statement........................................................................................................ 22
4.1 Vista Preliminar.......................................................................................................... 22
6.1.1 C!eaci2n de obje#os (#a#e*en#............................................................................... 22
6.1.2 7jecuci2n de sen#encias usando obje#os (#a#e*en#................................................ 2$
6.1.$ 5eali?aci2n de (#a#e*en#....................................................................................... 26
6.1.6 Ce!!a! obje#os (#a#e*en#........................................................................................ 26
6.1.5 (in#a1is de 7scae (Q) en obje#os (#a#e*en#....................................................... 26
6.1.' 3so del *#odo e1ecu#e......................................................................................... 2;
. LA CLASE Re!"#tSet......................................................................................................... 3$
.1 Vista Preliminar.......................................................................................................... 3!
5.1.1 ,ilas y Cu!so!es...................................................................................................... $/
5.1.2 Colu*nas................................................................................................................$1
5.1.$ 0ios de da#os y conve!siones................................................................................ $2
3nicode.......................................................................................................................... $5
3nicode es un es@ue*a de codi%icaci2n de ca!ac#e!es @ue u#ili?a 2 by#es o! cada
ca!Ac#e!. I(& BIn#e!na#ional (#anda!ds &!4ani?a#ionC de%ine un nD*e!o den#!o del
in#e!valo / a '5.5$5 B21' E 1C o! cada ca!Ac#e! y s:*bolo de cada idio*a B*As al4unos
2
esacios vac:os a!a %u#u!as a*liacionesC. 7n #odas las ve!siones de $2 bi#s de
Findo-sG el =odelo de obje#os co*onen#es BC&=CG @ue es la base de las #ecnolo4:as
&)7 y Ac#iveHG u#ili?a 3nicode. 3nicode es #o#al*en#e co*a#ible con Findo-s <0.
Aun@ue 3nicode y DBC( #ienen ca!ac#e!es de doble by#eG los es@ue*as de codi%icaci2n
son co*le#a*en#e di%e!en#es. ........................................................................................ $5
5.1.5 Ialo!es !esul#ado <3))........................................................................................ $'
5.1.' 5esul# se#s ocionales o *Dl#iles..........................................................................$'
%. LA CLASE &re'are(Statement......................................................................................... 3)
".1 Vista Preliminar.......................................................................................................... 3#
'.1.1 C!eaci2n de obje#os P!ea!ed(#a#e*en#................................................................. $;
'.1.2 Pasa! a!A*e#!os I<.............................................................................................. $+
'.1.6 3sa! se#&bjec#........................................................................................................ $>
'.1.5 7nv:o de JDBC <3)) co*o un a!A*e#!o I<...................................................... 6/
'.1.' 7nvio de a!A*e#!os I< *uy 4!andes.................................................................... 6/
). LA CLASE Ca##a*#eStatement........................................................................................... 41
#.1 Vista Preliminar.......................................................................................................... 41
;.1.1 C!ea! obje#os Callable(#a#e*en#............................................................................ 62
;.1.2 Pa!A*e#!os I< y &30.............................................................................................62
;.1.$ Pa!A*e#!os I<&30.................................................................................................6$
;.1.6 5ecue!a! a!A*e#!os &30 desus de !esul#ados................................................ 66
;.1.5 5ecue!a! valo!es <3)) en a!A*e#!os &30....................................................... 66
9. E+EM&LO DE CODI,O....................................................................................................4
$
JDBC.
1. INTRODUCCION
Java Database Connectivity (JDBC) es una interfase de acceso a bases de datos
estndar SQL que proporciona un acceso uniforme a una gran variedad de bases
de datos relacionales JDBC tambi!n proporciona una base com"n para la
construcci#n de $erramientas y utilidades de alto nivel
%l paquete actual de JD& incluye JDBC y el puente JDBC'(DBC %stos paquetes
son para su uso con JD& )*
Drivers JDBC
+ara usar JDBC con un sistema gestor de base de datos en particular, es necesario
disponer del driver JDBC apropiado que $aga de intermediario entre !sta y JDBC
Dependiendo de varios factores, este driver puede estar escrito en Java puro, o ser
una me-cla de Java y m!todos nativos J./ (Java .ative /nterface)
1.1 Qu es JDBC?
JDBC es el 0+/ para la e1ecuci#n de sentencias SQL (Como punto de inter!s
JDBC es una marca registrada y no un acr#nimo, no obstante a menudo es
conocido como 2Java Database Connectivity3) Consiste en un con1unto de clases e
interfases escritas en el lengua1e de programaci#n Java JDBC suministra un 0+/
estndar para los desarrolladores y $ace posible escribir aplicaciones de base de
datos usando un 0+/ puro Java
4sando JDBC es fcil enviar sentencias SQL virtualmente a cualquier sistema de
base de datos %n otras palabras, con el 0+/ JDBC, no es necesario escribir un
programa que acceda a una base de datos Sybase, otro para acceder a (racle y
otro para acceder a /nformi5 4n "nico programa escrito usando el 0+/ JDBC y el
programa ser capa- de enviar sentencias SQL a la base de datos apropiada 6,
con una aplicaci#n escrita en el lengua1e de programaci#n Java, tampoco es
necesario escribir diferentes aplicaciones para e1ecutar en diferentes plataformas
La combinaci#n de Java y JDBC permite al programador escribir una sola ve- y
e1ecutarlo en cualquier entorno
Java, siendo robusto, seguro, fcil de usar, fcil de entender, y descargable
automticamente desde la red, es un lengua1e base e5celente para aplicaciones de
base de datos
6
JDBC e5pande las posibilidades de Java +or e1emplo, con Java y JDBC 0+/, es
posible publicar una pgina 7eb que contenga un applet que usa informaci#n
obtenida de una base de datos remota ( una empresa puede usar JDBC para
conectar a todos sus empleados (incluso si usan un conglomerado de mquinas
8indo7s, 9acintos$ y 4./:) a una base de datos interna v;a intranet Con cada
ve- ms y ms programadores desarrollando en lengua1e Java, la necesidad de
acceso fcil a base de datos desde Java contin"a creciendo
1.1.1 Qu hace JDBC?
Simplemente JDBC $ace posible estas tres cosas<
%stablece una cone5i#n con la base de datos
%nv;a sentencias SQL
+rocesa los resultados
%l siguiente fragmento de c#digo nos muestra un e1emplo bsico de estas tres
cosas<
Connection con = DriverManager.getConnection (
"jdbc:odbc:wombat", "login", "password");
Statement stmt = con.createStatement();
es!ltSet rs = stmt.e"ec!te#!er$("S%&%C' a, b, c ()M 'able*");
w+ile (rs.ne"t()) ,
int " = rs.get-nt("a");
String s = rs.getString("b");
.loat . = rs.get(loat("c");
/
1.1.2 JDBC es un API de a!" nive# $ una ase %ara API&s de a#'" nive#.
JDBC es una interfase de ba1o nivel, lo que quiere decir que se usa para =invocar> o
llamar a comandos SQL directamente %n esta funci#n traba1a muy bien y es ms
fcil de usar que otros 0+/>s de cone5i#n a bases de datos, pero est dise?ado de
forma que tambi!n sea la base sobre la cual construir interfaces y $erramientas de
alto nivel 4na interfase de alto nivel es =amigable>, usa un 0+/ mas entendible o
ms conveniente que luego se traduce en la interfase de ba1o nivel tal como JDBC
5
1.1.( JDBC )ren'e a ODBC $ "'r"s API&s
%n este punto, el (DBC de 9icrosoft ((pen Database Connectvity), es
probablemente el 0+/ ms e5tendido para el acceso a bases de datos relacionales
(frece la posibilidad de conectar a la mayor;a de las bases de datos en casi todas
las plataformas @+or qu! no usar, entonces, (DBC, desde JavaA
La respuesta es que se puede usar (DBC desde Java, pero es preferible $acerlo
con la ayuda de JDBC mediante el puente JDBC'(DBC La pregunta es a$ora @por
qu! necesito JDBCA Bay varias respuestas a estas preguntas<
)' (DBC no es apropiado para su uso directo con Java porque usa una interface
C Las llamadas desde Java a c#digo nativo C tienen un n"mero de
inconvenientes en la seguridad, la implementaci#n, la robuste- y en la
portabilidad automtica de las aplicaciones
C' 4na traducci#n literal del 0+/ C de (DBC en el 0+/ Java podr;a no ser
deseable +or e1emplo, Java no tiene punteros, y (DBC $ace un uso copioso
de ellos, incluyendo el notoriamente propenso a errores 2void D 2 Se puede
pensar en JDBC como un (DBC traducido a una interfase orientada a ob1eto
que es el natural para programadores Java
E (DBC es dif;cil de aprender 9e-cla caracter;sticas simples y avan-adas 1untas,
y sus opciones son comple1as para =querys> simples JDBC por otro lado, $a
sido dise?ado para mantener las cosas sencillas mientras que permite las
caracter;sticas avan-adas cuando !stas son necesarias
F 4n 0+/ Java como JDBC es necesario en orden a permitir una soluci#n Java
2pura3 Cuando se usa (DBC, el gestor de drivers de (DBC y los drivers
deben instalarse manualmente en cada mquina cliente Como el driver JDBC
esta completamente escrito en Java, el c#digo JDBC es automticamente
instalable, portable y seguro en todas las plataformas Java
%n resumen, el 0+/ JDBC es el interfase natural de Java para las abstracciones y
conceptos bsicos de SQL JDBC retiene las caracter;sticas bsicas de dise?o de
(DBCG de $ec$o, ambos interfaces estn basados en el :H(pen SQL CL/ (Call
Level /nterface)
9s recientemente 9icrosoft $a introducido nuevas 0+/ detrs de (DBC ID(,
0D( y (L% DB %stos dise?os se mueven en la misma direcci#n que JDBC en
muc$as maneras, puesto que se les da una orientaci#n a ob1eto basndose en
clases que se implementan sobre (DBC
'
1.1.* +"de#"s en d"s $ 'res %is"s.
%l 0+/ JDBC soporta los modelos en dos y tres pisos de acceso a base de datos
%n el modelo de dos'pisos, un applet Java o una aplicaci#n $abla directamente con
la base de datos %sto requiere un driver JDBC que pueda comunicar con el gestor
de base de datos particular al que se pretende acceder Las sentencias SQL de
usuario se env;an a la base de datos, y el resultado de estas sentencias se env;an
al usuario La base de datos puede estar locali-ada en otra mquina a la que el
usuario se conecta mediante la red %sta es una configuraci#n Cliente/Servidor en
la que la mquina del usuario es el cliente y la mquina que $ospeda a la base de
datos es el servidor La red puede ser una intranet, por e1emplo, que conecta a los
empleados dentro de la corporaci#n, o puede ser /nternet
%n el modelo de tres'pisos, los comandos se env;an a un =piso intermedio> de
servicios, que env;a las sentencias SQL a la base de datos La base de datos
procesa las sentencias SQL y devuelve los resultados a el =piso intermedio>, que a
su ve- lo env;a al usuario Los directores de /S encuentran este modelo muy
atractivo por que el =piso intermedio> $ace posible mantener el control sobre los
datos y los tipos de actuali-aciones que pueden $acerse en los datos corporativos
(tra venta1a es que el usuario puede emplear un 0+/ de alto nivel ms sencillo que
es traducido por el =piso intermedio> en las llamadas de ba1o nivel apropiadas
Jinalmente en muc$os casos la arquitectura de tres niveles puede proporcionar
venta1as de rendimiento
Basta a$ora, este nivel intermedio $a sido escrito en lengua1es como C # CKK, que
ofrecen un rendimiento ms rpido De cualquier modo, con la introducci#n de
compiladores optimi-adores que traducen el bytecode en c#digo mquina eficiente,
se est convirtiendo en prctico desarrollar este nivel intermedio en Java
;
0plicacion
Java
JDBC
DB9S
+rotocolo propietario DB9S
9quina cliente
Servidor de BD
%sta es una gran venta1a al $acer posible aprovec$ar las caracter;sticas de
robuste-, multiproceso y seguridad de Java
1.1., -Q. C"n)"r/e
SQL es el lengua1e estndar para el acceso a las bases de datos relacionales 4na
de las reas de dificultad es que aunque muc$as DB9S>s (Data Base 9anagement
Systems) usan un formato estndar de SQL para la funcionalidad bsica, estos no
conforman la sinta5is ms recientemente definidas o semnticas para
funcionalidades ms avan-adas +or e1emplo, no todas las bases de datos soportan
procedimientos almacenados o 1oins de salida, y aquellas que lo $acen no son
consistentes con otras %s de esperar que la porci#n de SQL que es
verdaderamente estndar se e5pandir para incluir ms y ms funcionalidad
%ntretanto, de cualquier modo, el 0+/ de JDBC debe soportar SQL tal como es
4na forma en que el 0+/ JDBC trata este problema es permitir que cualquier
cadena de b"squeda se pase al driver subyacente del DB9S %sto quiere decir que
una aplicaci#n es libre de usar la sentencia SQL tal como quiera, pero se corre el
riesgo de recibir un error en el DB9S De $ec$o una consulta de una aplicaci#n
incluso no tiene por que ser SQL, o puede ser una derivaci#n especiali-ada de SQL
+
0plicacion
Java
DB9S
9quina cliente
Servidor de BD
0plicacion
Servidora
(Java)
JDBC
llamadas BLL+, I9L # C(IB0
Servidor (L#gica de negocio)
+rotocolo propietario del DB9S
dise?ada para especificas DB9S (para consultas a imgenes o documentos por
e1emplo)
4na segunda forma en que JDBC trata este problema es proveer clusulas de
escape al estilo de (DBC , que se discutirn en el F)M 3Sinta5is de escape en
Sentencias (b1etos3
La sinta5is de escape provee una sinta5is JDBC estndar para varias de las reas
ms comunes de divergencia SQL +or e1emplo, a$; escapes para literales de fec$a
o procedimientos almacenados
+ara aplicaciones comple1as, JDBC trata la conformidad SQL de una tercera
manera 6 es proveer informaci#n descriptiva sobre el DB9S por medio de la
interfase DatabaseMetaData por la que las aplicaciones pueden adaptarse a los
requerimientos y posibilidades de cada DB9S<
Como el 0+/ JDBC se usar como base para el desarrollo de $erramientas de
acceso y 0+/>s de alto nivel , direccionar el problema de la conformidad a
cualquiera de estas La designaci#n 2JDBC C(9+L/0.L3 se cre# para situar un
nivel estndar de funcionalidad JDBC en la que los usuarios puedan confiar %n
orden a usar esta designaci#n, un driver debe soportar al menos el nivel de entrada
0.S/ SQL'C %ntry Level Los desarrolladores de drivers pueden cerciorarse que
sus drivers cumplan estas especificaciones mediante la suite de test disponible en
el 0+/ JDBC
La designaci#n 2JDBC C(9+L/0.L3 indica que la implementaci#n JDBC de un
vendedor $a pasado los tests de conformidad suministrados por JavaSoft %stas
pruebas de conformidad c$equean la e5istencia de todas las clases y m!todos
definidos en el 0+/ JDBC, y c$equean tanto como es posible que la funcionalidad
SQL %ntry Level est! disponible Lales tests no son e5$austivos, por supuesto, y
JavaSoft no esta distribuyendo implementaciones de vendedores, pero esta
definici#n de compliance tiene alg"n grado de seguridad en una implementaci#n
JDBC Con la mayor aceptaci#n de JDBC por parte de vendedores de bases de
datos, de servicios de /nternet y desarrolladores, JDBC se est convirtiendo en el
estndar de acceso a bases de datos
1.2 Pr"duc'"s JDBC.
%5isten una serie de productos basados en JDBC que ya $an sido desarrollados
+or supuesto la informaci#n de este apartado ser rpidamente obsoleta
+ttp:00java.s!n.com0prod!cts0jdbc
>
1.2.1 Java-")' 0ra/e1"r2
JavaSoft suministra tres componentes JDBC como parte del JD&
%l gestor de drivers JDBC
La suite de testeo de drivers JDBC
%l puente JDBC'(DBC
%l gestor de drivers es la espina dorsal de la arquitectura JDBC 0ctualmente es
bastante peque?a y simpleG su funci#n principal es conectar las aplicaciones Java al
driver JDBC correcto y despu!s soltarlo
La suite de testeo JDB:C suministra seguridad y confian-a en los drivers JDBC que
se e1ecutarn en el programa Solo los drivers que pasan el test pueden ser
designados JDBC C(9+L/0.L
%l puente JDBC'(DBC permite a los drivers (DBC usarse como drivers JDBC Jue
implementado como una forma de llegar rpidamente al fondo de JDBC y para
proveer de acceso a los DB9S menos populares si no e5isten drivers JDBC para
ellos
1/
1.2.2 Ti%"s de drivers JDBC
Los drivers que son susceptibles de clasificarse en una de estas cuatro categor;as
)' puente JDBC-ODBC ms driver ODBC< %l producto de JavaSoft suministra
acceso v;a drivers (DBC .#tese que el c#digo binario (DBC, y en muc$os casos
el c#digo cliente de base de datos, debe cargarse en cada mquina cliente que use
este driver Como resultado, este tipo de driver es el ms apropiado en un red
corporativa donde las instalaciones clientes no son un problema mayor, o para una
aplicaci#n en el servidor escrito en Java en una arquitectura en tres'niveles
C' driver Java parcialmente .ativo %ste tipo de driver convierte llamadas JDBC en
llamadas del 0+/ cliente para (racle, Sybase, /nformi5, DBC y otros DB9S .#tese
que como el driver puente, este estilo de driver requiere que cierto c#digo binario
sea cargado en cada mquina cliente
E' driver Java nativo JDBC'.et %ste driver traduce llamadas JDBC al protocolo de
red independiente del DB9S que despu!s es traducido en el protocolo DB9S por el
servidor %ste middle7are en el servidor de red es capa- de conectar a los clientes
puros Java a muc$as bases de datos diferentes %l protocolo espec;fico usado
depender del vendedor %n general esta es la alternativa ms fle5ible
F' driver puro Java y nativo'protocolo %ste tipo de driver convierte llamadas JDBC
en el protocolo de la red usado por DB9S directamente %sto permite llamadas
directas desde la mquina cliente al servidor DB9S y es la soluci#n ms prctica
para accesos en intranets Dado que muc$os de estos protocolos son propietarios,
los fabricantes de bases de datos sern los principales suministradores
%speramos que las alternativas E y F sean las formas preferidas de acceder a las
bases de datos desde JDBC Las categor;as ) y C son soluciones interinas cuando
no estn disponibles drivers directos puros Java
11
2. CON34I5N
2.1 6is'a Pre#i/inar
4n ob1eto Connection representa una cone5i#n con una base de datos 4na
sesi#n de cone5i#n incluye las sentencias SQL que se e1ecutan y los resultados que
son devueltos despu!s de la cone5i#n 4na "nica aplicaci#n puede tener una o ms
cone5iones con una "nica base de datos, o puede tener varias cone5iones con
varias bases de datos diferentes
2.1.1 A%er'ura de una c"ne7i8n
La forma estndar de establecer una cone5i#n a la base de datos es mediante la
llamada al m!todo DriverManager.getConnection %ste m!todo toma una
cadena que contiene una 4IL La clase DriverManager, referida como la capa
de gesti#n JDBC, intenta locali-ar un driver que pueda conectar con la base de
datos representada por la 4IL La clase DriverManager mantiene una lista de
clases Driver registradas y cuando se llama al m!todo getConnection, se
c$equea con cada driver de la lista $asta que encuentra uno que pueda conectar
con la base de datos especificada en la 4IL %l m!todo connect de Driver usa
esta 4IL para establecer la cone5i#n
4n usuario puede evitar la capa de gesti#n de JDBC y llamar a los m!todos de
Driver directamente %sto puede ser "til en el caso raro que dos drivers puedan
conectar con la base de datos y el usuario quiera seleccionar uno e5pl;citamente
.ormalmente, de cualquier modo, es muc$o ms fcil de1ar que la clase
DriverManager mane1e la apertura de la cone5i#n
%l siguiente c#digo muestra como e1emplo una cone5i#n a la base de datos
locali-ada en la 4IL 1jdbc:odbc:wombat3 con un user /D de 2obo$3 y pass7ord
2*2java3
String !rl = "jdbc:odbc:wombat";
Connection con = DriverManager.getConnection(!rl, "obo$", "*23ava");
2.1.2 Us" 9enera# de UR.&s
Dado que 4IL>s causan a menudo cierta confusi#n, daremos primero una breve
e5plicaci#n de 4IL en general y luego entraremos en una discusi#n sobre 4IL>s de
JDBC
12
4na 4IL (4niform Iesource Locator) da informaci#n para locali-ar un recurso en
/nternet +uede pensarse en ella como una direcci#n
La primera parte de una 4IL especifica el protocolo usado para acceder a la
informaci#n y va siempre seguida por dos puntos 0lgunos protocolos comunes son
.tp, que especifica 2file transfer protocol3 y +ttp que especifica 2$yperte5t transfer
protocol3 Si el protocolo es 2.ile3 indica que el recurso est en un sistema de
fic$eros local me1or que en /nternet < veamos unos e1emplos<
ftp:00javaso.t.com0docs03D45*6apidocs.7ip
http:00java.s!n.com0prod!cts0jd80C!rrentelease
file:0+ome0+aroldw0docs0boo8s0t!torial0s!mmar$.+tml
%l resto de la 4IL, todo despu!s de los dos puntos, da informaci#n sobre donde se
encuentra la fuente de los datos Si el protocolo es file, el resto de la 4IL es el pat$
al fic$ero +ara los protocolos .tp y +ttp, el resto de la 4IL identifica el $ost y
puede opcionalmente dar un pat$ ms espec;fico al sitio +or e1emplo, el siguiente
es la 4IL para la $ome page de JavaSoft %sta 4IL identifica solo al $ost<
+ttp:00java.s!n.com
2.1.( JDBC $ UR.&s
4na 4IL JDBC suministra una forma de identificar una base de datos para que el
driver apropiado pueda reconocerla y establecer la cone5i#n con ella Los
desarrolladores de drivers son los que determinan actualmente que JDBC 4IL
identifica su driver particular Los usuarios no tienen por que preocuparse sobre
como se forma una 4IL JDBCG ellos simplemente usan la 4IL suministrada con el
driver que usan %l rol de JDBC es recomendar algunas convenciones a los
fabricantes de drivers para su uso
Dado que los JDBC 4IL se usan con varios tipos de drivers, las convenciones son
necesariamente muy fle5ibles +rimero, permiten a diferentes drivers usar diferentes
esquemas para nombrar las bases de datos %L subprotocolo odbc, por e1emplo,
permite que las 4IL contengan valores de atributos (pero no los requieren)
Segundo, las 4IL>s JDBC permiten a los desarrolladores de drivers codificar toda la
informaci#n de la cone5i#n dentro de ella %sto $ace posible, por e1emplo, para un
applet que quiera $ablar con una base de datos dada el abrir la cone5i#n sin
necesitar que el usuario realice ninguna tarea de administraci#n de sistemas
Lercero, las 4IL>s JDBC permiten un nivel de indirecci#n %sto quiere decir que la
4IL JDBC puede referirse a una base de datos l#gica o un $ost l#gico que se
traduce dinmicamente al nombre actual por el sistema de nombramiento de la red
1$
%sto permite a los administradores de sistemas evitar dar especificaciones de sus
$osts como parte del nombre JDBC Bay una variedad de servicios de
nomenclatura de red diferentes (tales como D.S, ./S y DC%), y no $ay restricci#n
acerca de cual usar
La sinta5is para las 4IL>s JDBC que se muestra a continuaci#n tiene tres partes
separadas por dos puntos<
jdbc:<subprotocol>:<subname>
Las tres partes se descomponen como sigue<
1 jdbc N el protocolo %l protocolo en una 4IL JDBC es siempre jdbc
2 ' 9s!bprotocol: ' el nombre del driver o el nombre del mecanismo de
conectividad con la base de datos, que puede estar soportado por uno o ms
drivers 4n e1emplo sobresaliente de un subprotocolo es 2odbc3, que $a sido
reservado para 4IL>s que especifican nombres de fuentes de datos estilo
(DBC +or e1emplo para acceder a la base de datos a trav!s del puente
JDBC'(DBC, la 4IL a usar podr;a ser algo as; como lo siguiente<
jdbc:odbc:.red
%n este e1emplo, el subprotocolo es 2odbc3 y el subnombre 2fred3 es el
nombre de la fuente de datos (DBC local
Si se quiere usar un servicio de nombre de la red (ya que el nombre de la
base de datos en la 4IL JDBC no tiene por que ser su nombre act"al), el
servicio de nombre puede ser el subprotocolo +or tanto, para el e1emplo,
podr;a tener una 4IL como <
jdbc:dcenaming:acco!nts5pa$able
%n este e1emplo, la 4IL especifica que el servicio local DC% resolver el
nombre de la base de datos 2accounts'payable3 para poder conectar con la
base de datos real
E :suna/e; ' una forma de identificar la base de datos %l subnombre puede
variar dependiendo del subprotocolo, y puede tener un subnombre con
cualquier sinta5is interna que el fabricante del driver $aya escogido %l punto
de un subnombre es para dar informaci#n suficiente para locali-ar la base de
datos %n el e1emplo anterior 2fred3 es suficiente porque (DBC suministra la
informaci#n restante 4na base de datos en un servidor remoto requiere ms
informaci#n Si la base de datos va a ser accesible a trav!s de /nternet, por
e1emplo, la direcci#n de red deber;a incluirse en la 4IL JDBC como parte del
16
subnombre y deber;a seguir a la convenci#n estndar de nomenclatura de 4IL
//hostname:port/subsubname
Suponiendo que 2dbnet3 es un protocolo para conectar a un $ost, la 4IL JDBC
deber;a parecerse a algo como<
jdbc:dbnet:00wombat:;<=0.red
2.1.* 3# su%r"'"c"#" <"dc=
%l subprotocolo 2odbc3 es un caso especial Ba sido reservado para 4IL>s que
especifican el estilo (DBC de nombres de fuentes de datos y que tiene la
caracter;stica de permitir especificar cualquier n"mero de valores de atributos
despu!s del subnombre (el nombre de la fuente de datos) La sinta5is completa para
el protocolo 2odbc3 es<
jdbc:odbc:9data5so!rce5name:>;9attrib!te5name:=9attrib!te5val!e:?@
Lodos los siguientes son nombres vlidos 1dbc<odbc
jdbc:odbc:AeorB
jdbc:odbc:wombat
jdbc:odbc:wombat;Cac+eSi7e=2C;%"tensionCase=&)D%
jdbc:odbc:Aeora;E-D=8g+;FDD=.ooe$
2.1., Re9is'r" de su%r"'"c"#"s
4n desarrollador de drivers puede reservar un nombre para usar como el
subprotocolo en una 4IL JDBC Cuando la clase DriverManager presenta este
nombre a su lista de drivers registrados, el driver para el que este nombre est
reservado deber;a reconocerlo y establecer una cone5i#n a la base de datos que lo
identifica +or e1emplo odbc est reservado para el puente JDBC'(DBC Si fuera,
por poner otro e1emplo, 9iracle Corporation, y quisiera registrar 2miracle3 como el
subprotocolo para el driver JDBC que conecte a su DB9S 9iracle no tiene que usar
sino ese nombre
15
2.1.> 3nv?" de -en'encias -Q.
4na ve- que la cone5i#n se $aya establecido, se usa para pasar sentencias SQL a
la base de datos subyacente JDBC no pone ninguna restricci#n sobre los tipos de
sentencias que pueden enviarse< esto da un alto grado de fle5ibilidad, permitiendo
el uso de sentencias espec;ficas de la base de datos o incluso sentencias no SQL
Se requiere de cualquier modo, que el usuario sea responsable de asegurarse que
la base de datos subyacente sea capa- de procesar las sentencias SQL que le
estn siendo enviadas y soportar las consecuencias si no es as; +or e1emplo, una
aplicaci#n que intenta enviar una llamada a un procedimiento almacenado a una
DB9S que no soporta procedimientos almacenados no tendr !5ito y generar una
e5cepci#n JDBC requiere que un driver cumpla al menos 0.S/ SQL'C %ntry Level
para ser designado JDBC C(9+L/0.L %sto significa que los usuarios pueden
contar al menos con este nivel de funcionalidad
JDBC suministra tres clases para el env;o de sentencias SQL y tres m!todos en la
interfa- Connection para crear instancias de estas tres clases %stas clases y
m!todos son los siguientes<
)' Statement G creada por el m!todo createStatement 4n ob1eto
Statement se usa para enviar sentencias SQL simples
C' PreparedStatement N creada por el m!todo prepareStatement' 4n ob1eto
FreparedStatement se usa para sentencias SQL que toman uno o ms
parmetros como argumentos de entrada (parmetros /.) FreparedStatement
tiene un grupo de m!todos que fi1an los valores de los parmetros /., los cuales
son enviados a la base de datos cuando se procesa la sentencia SQL /nstancias de
FreparedStatement e5tienden Statement y por tanto $eredan los m!todos de
Statement 4n ob1eto FreparedStatement es potencialmente ms eficiente que
un ob1eto Statement porque este $a sido precompilado y almacenado para su uso
futuro
E' CallableStatement N creado por el m!todo prepareCall Los ob1etos
CallableStatement se usan para e1ecutar procedimientos almacenados SQL N
un grupo de sentencias SQL que son llamados mediante un nombre, algo parecido
a una funci#n ' 4n ob1eto CallableStatement $ereda m!todos para el mane1o
de los parmetros /. de FreparedStatement, y a?ade m!todos para el mane1o
de los parmetros (4L e /.(4L
La lista siguiente da una forma rpida de determinar que m!todo Connection es el
apropiado para crear los diferentes tipos de sentencias SQL
1'
%l m!todo createStatement se usa para<
Sentencias SQL simples (sin parmetros)
%l m!todo prepareStatement se usa para<
Sentencias SQL con uno # ms parmetros /.
Sentencias SQL simples que se e1ecutan frecuentemente
%l m!todo prepareCall se usa para<
Llamar a procedimientos almacenados
2.1.@ Transacci"nes
4na transacci#n consiste en una o ms sentencias que $an sido e1ecutadas,
completas y, o bien se $a $ec$o commit o bien roll'bacO Cuando se llama al
m!todo commit o rollbac8 , la transacci#n act"al finali-a y comien-a otra
4na cone5i#n nueva se abre por defecto en modo auto'commit, y esto significa que
cuando se completa se llama automticamente al m!todo commit %n este caso,
cada sentencia es =commitada> individualmente, por tanto una transacci#n se
compone de una "nica sentencia Si el modo auto'commit es desactivado, la
transacci#n no terminar $asta que se llame al m!todo commit o al m!todo
rollbac8 e5pl;citamente, por lo tanto incluir todas las sentencias que $an sido
e1ecutadas desde la "ltima invocaci#n a uno de los m!todos commit o rollbacO %n
este segundo caso, todas las sentencias de la transacci#n son 2commitadas> o
des$ec$as en grupo
%l m!todo commit $ace permanente cualquier cambio que una sentencia SQL
reali-a en la base de datos, y libera cualquier bloqueo mantenido por la transacci#n
%l m!todo rollbacO descarta estos cambios
0 veces un usuario no quiere que tenga efecto un determinado cambio a menos
que se efectu! otro %sto puede $acerse desactivando el modo auto'commit y
agrupando ambas actuali-aciones en una transacci#n Si ambas actuali-aciones
tienen !5ito se llama al m!todo commit $aciendo estos cambios permanentes, si
uno o los dos fallan, se llama al m!todo rollbacO, restaurando los valores e5istentes
l inicio de la transacci#n 9uc$os drivers JDBC soportan transacciones De $ec$o,
un driver JDBC'compliant debe soportar transacciones Database9etaData
suministra informaci#n que describe el nivel de transacci#n soportado por el DB9S
1;
2.1.A Nive#es de ais#a/ien'" de 'ransacci"nes
Si un DB9S soporta el proceso de transacciones, tendr que mane1ar de alguna
forma los potenciales conflictos que puedan surgir cuando dos transacciones estn
operando sobre una base de datos concurrentemente %l usuario puede especificar
un nivel de aislamiento para indicar que nivel de precauci#n deber;a e1ercitar el
DB9S para la resoluci#n de estos conflictos +or e1emplo, @que ocurrir cuando
una transacci#n cambia un valor y una segunda transacci#n lee el valor antes de
que el cambio $aya sido =commitado> o descartadoA @Deber;a permitirse, dado que
el valor cambiado le;do por la segunda transacci#n ser invalido si la primera
transacci#n $a $ec$o rollbacOA 4n usuario JDBC puede instruir a la DB9S para
que un valor que $a sido le;do antes del =commit> (2dirty reads3) con el siguiente
c#digo donde con es el ob1eto de la actual cone5i#n<
con.set'ransaction-solation('HISHC'-)I6%HD6EIC)MM-''%D);
%l nivel de aislamiento ms alto, el que ms cuidado toma para evitar conflictos La
interfase Connection define cinco niveles de aislamiento con el nivel ms ba1o que
especifica que no soporte transacciones $asta el ms alto que especifica que
mientras una transacci#n est! abierta ninguna otra transacci#n puede reali-ar
cambios en los datos le;dos por esa transacci#n .ormalmente, el nivel de
transacci#n ms alto es el ms lento en la e1ecuci#n de la aplicaci#n(debido a que
se incrementan los bloqueos y se disminuye la concurrencia de los usuarios) %l
desarrollador debe balancear la necesidad de rendimiento con la necesidad de la
consistencia de los datos al tomar la decisi#n del nivel de aislamiento a usar +or
supuesto, el nivel de aislamiento que pueda soportarse depende de las
posibilidades de la base de datos subyacente
Cuando se crea un nuevo ob1eto Connection, su nivel de aislamiento depende del
driver, pero normalmente por defecto es el de la DB9S subyacente 4n usuario
puede llamar al m!todo set-solation&evel para cambiar el nivel de aislamiento
de la transacci#n, y este nuevo nivel estar efectivo durante la sesi#n de cone5i#n
+ara cambiar el nivel de aislamiento solo para una transacci#n, es necesario fi1ar
este antes de la transacci#n comience y volverlo a situar en su valor anterior una
ve- que la transacci#n $aya terminado .o se recomienda cambiar el nivel de
aislamiento de transacci#n en medio de una puesto que lan-ar una llamada
inmediata al m!todo commit, provocando que los cambios $asta ese punto se
$agan permanentes en la base de datos
1+
(. .A C.A-3 Driver+ana9er
(.1 6is'a %re#i/inar
La clase DriverManager implementa la capa de gesti#n de JDBC, y traba1a como
intermediaria entre el usuario y los drivers Puarda la lista de los drivers que estn
disponibles y establece la cone5i#n entre la base de datos y el driver apropiado
0dems la clase DriverManager se ocupa de cosas c#mo gestionar los l;mites de
tiempo de =login> en el driver y de la salida de los mensa1es de tra-a y log
+ara aplicaciones simples, el "nico m!todo en esta clase que necesita un
programador general para su uso directamente es
DriverManager.getConnection Como su nombre indica, este m!todo
establece una cone5i#n con la base de datos JDBC permite al usuario llamar a los
m!todos de DriverManager getDriver, getDrivers y registerDriver as;
como al m!todo de Driver connect, pero en la mayor;a de los casos es preferible
de1ar que la clase Driver9anager gestione los detalles al establecer la cone5i#n
(.1.1 +an'eni/ien'" de #a #is'a de drivers dis%"ni#es.
La clase DriverManager mantiene una lista de clases disponibles que $an sido
registrados mediante el m!todo DriverManager.registerDriver Lodas las
clases Driver deben escribirse con una secci#n esttica que cree una instancia de
la clase y luego la registre en la clase DriverManager cuando se cargue 0dems
el usuario normalmente no deber;a llamar a DriverManager.registerDriver
directamenteG deber;a llamarse automticamente por el driver cuando est! se
carga, 4na clase Driver se carga, y por tanto se registra, de dos formas
diferentes<
1 9ediante una llamada al m!todo C#ass.)"rNa/e %ste carga e5pl;citamente la
clase driver Dado que no depende de ning"n =setup> e5terno, esta forma de
cargar drivers es la recomendada %l siguiente c#digo carga la clase
acme.db.Driver:
Class..orIame("acme.db.Driver");
Si acme.db.Driver se $a escrito para que al cargar produ-ca una instancia
y llame al m!todo DriverManager.registerDriver con esta instancia
como argumento (es lo que deber;a $acer), entonces este estar en la lista
de drivers disponibles para efectuar la cone5i#n
1>
2 9ediante la adici#n del driver a la propiedad 1dbcdrivers de 1avalangSystem'
%sta es una lista de nombres de clases de drivers, separadas por dos puntos,
que es la que carga la clase Driver9anager Cuando la clase Driver9anager
se iniciali-a, mira en la propiedad 1dbcdrivers, y si el usuario $a introducido
uno o ms drivers, la clase Driver9anager intenta cargarlos %l siguiente
c#digo ilutsra como un programador deber;a introducir estas tres clases en
J0.+otjava0properties
jdbc.drivers=.oo.ba+.Driver:wombat.sAl.Driver:bad.test.o!rDriver;
La primera llamada a el m!todo DriverManager $ar que estos drivers se
carguen automticamente
.otese que en esta segunda manera de cargar los drivers es necesario una
preparaci#n del entorno que es persistente Si e5iste alguna duda sobre esto es
preferible y ms seguro llamar al m!todo Class..orIame para cargar
e5plicitamente cada driver %ste es tambi!n el m!todo que se usa para traer un
driver particular puesto que una ve- que la clase DriverManager $a sido
iniciali-ada no c$equear la lista de propiedades 1dbcdrivers
%n ambos casos, es responsabilidad de la clase Driver reci!n cargada registrarse
a si misma mediante una llamada a DriverManager.registerDriver Como
se $a mencionado anteriormente, esto deber;a $acerse automticamente al cargar
la clase
+or ra-ones de seguridad, la capa de gesti#n de JDBC guardar tra-a de que
clases de cargadores provee cada driver %ntonces cuando la clase Driver9anager
abre una cone5i#n solo usar los drivers que vienen desde el sistema de fic$eros
local o desde las mismas clases cargadoras como el c#digo que solicita la cone5i#n
(.1.2 3s'a#ecer una c"ne7i8n
4na ve- que la clase Driver $a sido cargada y registrada con la clase
Driver9anager, se est en condiciones de establecer la cone5i#n con la base de
datos La solicitud de la cone5i#n se reali-a mediante una llamada al m!todo
Driver9anagergetConnection, y Driver9anager testea los drivers regsitrados para
ver si puede establecer la cone5i#n
0 veces puede darse el caso de que ms de un driver JDBC pueda establecer la
cone5i#n para una 4IL dada +or e1emplo, cuando conectamos con una base de
datos remota, podr;a ser posible usar un driver puente JDBC'(DBC, o un driver
JDBC de protocolo gen!rico de red, o un driver suministrado por el vendedor
2/
%n tales casos, el orden en que los driver son testeados es significante porque
DriverManager usar el primer driver que encuentre que pueda conectar con
!5ito a la base de datos
+rimero Driver9anager intenta usar cada driver en el orden en que $a sido
registrado ( los drivers listados en la propiedad 1dbcdrivers son siempre los
registrados primero) Saltar cualquier driver con c#digo =untrusted>, a menos que se
cargue desde el mismo c#digo fuente que el c#digo que intenta abrir la cone5i#n
Lestea los drivers mediante la llamada al m!todo Driver.connect cada uno por
turno, pasndole como argumento la 4IL que el usuario $a pasado originalmente al
m!todo DriverManager.getConnection %l primer driver que recono-ca la
4IL reali-a la cone5i#n
4na primera o1eda puede parecer insuficiente, pero son necesarias solo unas pocas
llamadas a procedimientos y comparaciones de cadena por cone5i#n puesto que no
es probable que $aya docenas de drivers se carguen concurrentemente
%l siguiente c#digo es un e1emplo de todo lo necesario normalmente para
establecer una cone5i#n con un driver puente JDBC'(DBC<
Class..orIame("s!n.jdbc.odbc.3dbc)dbcDriver"); 00loads t+e driver
String !rl = "jdbc:odbc:.red";
DriverManager.getConnection(!rl, "!ser-D", "passwd");

21
*. .A C.A-3 -'a'e/en'
*.1 6is'a Pre#i/inar
4n ob1eto Statement se usa para enviar sentencias SQL a la base de datos
0ctualmente $ay tres tipos de ob1etos Statement, todos los cuales act"an como
contenedores para la e1ecuci#n de sentencias en una cone5i#n dada< Statement,
FreparedStatement que $ereda de Statement y CallableStatement que
$ereda de FreparedStatement %stas estQn especiali-adas para enviar tipos
particulares de sentencias SQL, 4n ob1eto Statement se usa para e1ecutar una
sentencia SQL simple sin parmetros 4n ob1eto FreparedStatement se usa para
e1ecutar sentencias SQL precompiladas con o sin parmetros /.G y un ob1eto
CallableStatement se usa para e1ecutar un procedimieno de base de datos
almacenado
La interfase Statement suminstra m!todos bsicos para e1ecutar sentencias y
devolver resultados La interfase FreparedStatement a?ade m!todos para
traba1at con los parmetros /.G y la interfase CallableStatement a?ade
m!todos para traba1ar con parameters (4L
*.1.1 Creaci8n de "!e'"s -'a'e/en'
4na ve- establecida la cone5i#n con una base de datos particular, esta cone5i#n
puede usarse para enviar sentencias SQL 4n ob1eto Statement se crea mediante
el m!todo de Connection createStatement, como podemos ver en el siguiente
fragmento de c#digo
Connection con = DriverManager.getConnection(!rl, "s!nn$", "");
Statement stmt = con.createStatement();
La sentencia SQL que ser enviada a la base de datos es alimentada como un
argumento a uno de los m!todos de e1ecuci#n del ob1eto Statement +or e1emplo<
es!ltSet rs = stmt.e"ec!te#!er$("S%&%C' a, b, c ()M 'able2");
22
*.1.2 3!ecuci8n de sen'encias usand" "!e'"s -'a'e/en'.
La interfase Statement nos suministra tres m!todos diferentes para e1ecutar
sentencias SQL, e"ec!te#!er$, e"ec!teEpdate y e"ec!te %l m!todo a usar
esta determinado por el producto de la sentencia SQL
%l m!todo e"ec!te#!er$ esta dise?ado para sentencias que producen como
resultado un "nico result set tal como las sentencias S%&%C'
%l m!todo e"ec!teEpdate se usa para e1ecutar sentencias -IS%', EFDH'% #
D%&%'% as; como sentencias SQL DDL (Data Definition Language) como C%H'%
'HK&% o D)F 'HK&% %l efecto de una sentencia -IS%', EFDH'% o D%&%'% es
una modificaci#n de una o ms columnas en cero o ms filas de una tabla %l valor
devuelto de e"ec!teEpdate es un entero que indica el n"mero de filas que $an
sido afectadas (referido como update count) +ara sentencias tales como C%H'%
'HK&% o D)F 'HK&%, que no operan sobre filas, le valor devuelto por
e"ec!teEpdate es siempre cero
%l m!todo e"ec!te se usa para e1ecutar sentencias que devuelven ms de un
result set, ms que un update count o una combinaci#n de ambos Como es esta
una caracter;stica avan-ada que muc$os programadores no necesitar?an nunca se
ver en su propia secci#n
Lodos los m!todos que e1ecutan sentencias cierran los ob1etos es!ltset abiertos
como resultado de las llamadas a Statement %sto quiere decir que es necesario
completar el proceso con el actual ob1eto es!lset antes de ree1ecutar una
sentencia Statement
Debe notarse que la interfase FreparedStatement, que $ereda los m!todos de la
interfase Statement, tiene sus propias versiones de los m!todos e"ec!te#!er$,
e"ec!teEpdate y e"ec!te Los ob1etos Statement en si mismos no contienen
una sentencia SQL, por tanto debe suministrarse como un argumento a los m!todos
Statemente"ec!te Los ob1etos FreparedStatement no suministran una
sentencia SQL como argumento a estos m!todos puesto que ya tienen la sentencia
precompilada Los ob1etos CallableStatement $eredan las formas de estos
m!todos de FreparedStatement 4sar un parametro de query con las versiones
de los m!todos de FreparedStatement o CallableStatement produciri una
S#&%"ception,
2$
*.1.( Rea#iBaci8n de -'a'e/en'
Cuando una cone5i#n est en modo auto'commit, las sentencias e1ecutadas son
=comitadas> o rec$a-adas cuando se completan 4n sentencia se considera
completa cuando $a sido e1ecutada y se $an devuelto todos los resultados +are el
m!todo e"ec!te#!er$, que devuelve un "nico result set, la sentencia se completa
cuando todas las filas del ob1eto es!ltSet se $an devuelto +ara el m!todo
e"ec!teEpdate, un sentencia se completa cuando se e1ecuta %n los raros casos
en que se llama al m!todo e"ec!te, de cualquier modo, no se completa $asta que
los result sets o update counts que se generan $an sido devueltos
0lgunos DB9S tratan cada sentencia en un procedimiento almacenado como
sentencias separadas (tros tratan el procedimiento entero como una sentencia
compuesta %sta diferencia se convierte en importante cuando est activo el modo
auto'commit porque afecta cuando se llama al m!todo commit %n el primer caso,
cada sentencia individual es commitada %n el segundo, se commiten todas 1untas
*.1.* Cerrar "!e'"s -'a'e/en'.
Los ob1etos Statement se cerrarn automticamente por el colector de basura de
Java (garbage collector) .o obstante se recomienda como una buena prctica de
programaci#n que se cierren e5plicitamente cuando no sean ya necesarios %sto
libera recursos DB9S inmediatamente y ayuda a evitar potenciales problemas de
memoria
*.1., -in'a7is de 3sca%e -Q. en "!e'"s -'a'e/en'
Los ob1etos Statement pueden contener sentencias SQL que usen sinta5is de
escape SQL La sinta5is de escape se?ala al driver que el c#digo que lleva debe ser
tratado diferentemente %l driver buscar por cualquier sinta5is de escape y lo
traducir en c#digo que entiende la base de datos en particular %sto $ace que la
sinta5is de escape sea independiente de la DB9S y permite al programador usar
caracter;sticas que de otro modo no estar;an disponibles
4na clausula de escape se enmarca entre llaves y tiene una palabra clave<
,8e$word . . . parameters . . . /
26
La palabra clave (Oey7ord) indica el tipo de clausula de escape, seg"n se muestra<
escape para caracteres L/&%
Los caracteres 2R3 y 2S3 traba1an como 7ildcards en la clausula SQL L/&%
(2R3 significa cero o ms caracteres y 2S3 significa e5actamente un carcter3
%n orden a interpretarlos literalmente, pueden estar precedidos por un
bacOslas$ (=T>), que es un carcter de escape especial en cadenas Se puede
especificar un carcter que se use como carcter de escape por la inclusi#n
de la sinta5is siguiente al final de la consulta
,escape Lescape5c+aracterL/
+or e1emplo, la siguiente query, usando bacOslas$ como caracter de escape,
encuentra nombres de identificador que comiencen con =S>
stmt.e"ec!te#!er$("S%&%C' name ()M -denti.iers
DM%% -d &-4% NO6PL ,escape NOL/;
.n para funciones escalares
Casi todas las DB9S tienen funciones numUricas, de cadena, de fec$a y
conversi#n sobre valores escalares 4na de estas funciones puede usarse
colocndola en la sinta5is de escape con la clave .n seguida del nombre de
la funci#n deseada y sus argumentos +or e1emplo, para llamar a la funci#n
concat con dos argumentos que sern concatenados<
,.n concat("Mot", "3ava")/;
%l nombre del usuario actual de la base de datos puede obtenerse mediante<
,.n !ser()/;
Las funciones escalares pueden estar soportadas por diferentes DB9S con
ligeras diferencias de sinta5is, y pueden no estar disponibles en todos los
drivers Varios m!todos de DatabaseMetaData nos listarn las funciones
que estn soportadas +or e1emplo, el m!todo get.umericJunctions devuelve
una lista de los nombres de las funciones num!ricas separadas por comas, el
m!todo getStringJunction nos devuelve los nombres de las funciones de
cadena, y as; var;as ms
%L driver o bien mapear la llamada a la funci#n =escapada> en su propia
sinta5is o implementar la funci#n el mismo
25
d, t y ts para literales de fec$a y tiempo
Las DB9S difieren en la sinta5is que usan para los literales de fec$a, tiempo
y timestamp JDBC soporta un formato estndar /S( para estos literales y
usa una clausula de escape que el driver debe traducir a la representaci#n
del DB9S
+or e1emplo, una fec$a se especifica en SQL JDBC mediante la sinta5is<
,d N$$$$5mm5ddL/
%n esta sinta5is, $$$$ es el a?o, mm es el mes y dd es el dia %l driver
reempla-ar la clausula de escape por la representaciWn propia equivalente
de la DB9S +or e1emplo, el driver reempla-ar;a ,d *QQQ5C252R/ por S2R5
(%K5QQS si este es el formato apropiado para la base subyacente
Bay clausulas de escape anlogas para '-M% $ '-M%S'HMF
,t N++:mm:ssL/
,ts N$$$$5mm5dd ++:mm:ss.. . . .L/
La parte fraccional de los segundos (.. . . .) del '-M%S'HMF puede
omitirse
call # T = call para procedimientos almacenados
Si una database soporta procedimientos almacenados, estos pueden ser
invocados desde JDBC mediante<
Jcall !ocedu!eKna*eLB?G ?G . . .CMN
o, cuando el procedimiento devuelve como resultado un parmetro
,T = call proced!re6name>(T, T, . . .)?/
Los corc$etes indican que el material encerrado en ellos es opcional %stos
no forman parte de la sinta5is
Los argumentos de entrada pueden ser bien literales, bien parmetros Ver la
secci#n X 2CallableStatement3 de esta gu;a
Se puede llamar al m!todo
DatabaseMetaData.s!pportsStoredFroced!res para ver si la base de
datos soporta procedimientos almacenados
2'
oj para 1oins de salida
La sinta5is para un outer 1oin es<
,oj o!ter5join/
donde outer'1oin es de la forma<
table &%(' )E'% 3)-I ,table U o!ter5join/ )I searc+5condition
Las (uter 1oins son una caracter;stica avan-ada, y solo puede c$equearse la
gramtica SQL mediente una e5plicaci#n de ella JDBC provee tres m!todos
de Database9etaData para determinar que tipos de outer 1oins soporta un
driver< s!pports)!ter3oins, s!pports(!ll)!ter3oins, $
s!pports&imited)!ter3oins.
%l m!todo Statement.set%scapeFrocessing activa o desactiva el
procesamiento de escape +or defecto la caracter;stica se encuentra activada 4n
programador deber;a desactivar esta caracter;stica en tiempo de e1ecuci#n cuando
el rendimiento $a de ser m5imo, pero normalmente debe estar activado Deber;a
notarse que set%scapeFrocesing no traba1a con ob1etos FreparedStatement
por que la sentencia ya est preparada para enviar a la base de datos antes de
poder ser llamada
*.1.> Us" de# /'"d" e7ecu'e
%l m!todo e5ecute deber;a usarse solamente cuando es posible que una sentencia
nos devuelva ms de un ob1eto es!ltset, mas de un update count o una
combinaci#n de ambos %stas m"ltiples posibilidades para resultados, aunque
raras, son posibles cuando se e1ecutan ciertos procedimientos almacenados o por
la e1ecuci#n dinmica de una string SQL desconocida (esto es, desconocida para el
programador de la aplicaci#n en tiempo de compilaci#n) +or e1emplo, una usuario
podr;a e1ecutar un procedimiento almacenado (usando una ob1eto
CallableStatement y este procedimiento podr;a e1ecutar una actuali-aci#n,
despu!s una select, luego una actuali-aci#n, despu!s una select y as;
.ormalmente, alguien que usa un procedimiento almacenado sabr que se le va a
devolver
+orque el m!todo e5ecute mane1a los casos que se salen de lo ordinario, no
sorprende que los resultados devueltos requieren algun mane1o especial +or
e1emplo, supongamos que se sabe que el procedimiento devuelve dos result sets
2;
Despu!s de usar el m!todo e"ec!te para e1ecutar el procedimiento, se debe
llamar al m!todo getes!ltSet para conseguir el primer result set y despu!s los
m!todos apropiados getVVV para recuperar los valores de !l +ara conseguir el
segundo result set, se necesita llamar al m!todo getMorees!lts y y despues a
getes!ltSet de nuevo Si se sabe que el procedimiento devuelve dos upadte
counts, se llama primero al m!todo getEpdateCo!nt, seguido de
getMorees!lts y de nuevo getEpdateCo!nt
0quellos casos en los que no se conoce que devolver se nos presenta una
situaci#n ms comple1a %l m!todo e5ecute devuelve tr!e si el resultado es un
ob1eto es!ltSet y .alse si es un int Java Si devuelve un int, esto quiere
decir que el resultado o bien es un update count o que la sentencia que $a
e1ecutado es un comando DDL Lo primero que $ay que $acer despu!s de llamar
e5ecute es llmar o bien a getes!ltSet o getEpdateCo!nt 0l m!todo
getes!ltSet se le llama para conseguir el primero de los dos o ms ob1etos
es!ltSet y al m!todo getEpdateCo!nt para conseguir el primero de dos o ms
update counts
Cuando el resultado de una sentencia SQL no es un result set, el m!todo
getes!ltSet devolver n!ll %sto quiere decir que el resultado es un update
count o que no $ay ms resultados La "nica manera de encontrar que significa el
valor n!ll en este caso es llamar al m!todo getEpdateCo!nt, que devolver un
entero %ste entero ser el n"mero de filas afectadas por la sentencia e1ecutada o
N) para indicar o bien que el resultado es un result set o bien que no $ay ms
resultados Si el m!todo getes!ltSet ya $a devuelto null, el resultado no puede
ser un ob1eto es!ltSet, por lo que el valor devuelto de N) tiene que ser que no
$ay ms resultados %n otras palabras, no $ay ms resultados cuando lo siguiente
es cierto<
((stmt.getes!ltSet() == n!ll) WW (stmt.getEpdateCo!nt() == 5*))
Si se $a llamado al m!todo getes!ltSet y se $a procesado el ob1eto
es!ltSet devuelto, es necesario llamar al m!todo getMorees!lts para ver si
$ay ms result sets o update counts Si getMorees!lts devuelve true,
entonces es necesario llamar de nuevo a getes!ltSet para recuperar el
siguiente result set Como ya se $a indicado anteriormente, si getes!ltset
devuelve n!ll $ay que llamar a XetEpdateCo!nt para buscar que significa ese
n!ll si un update count o que no $ay ms resultados
Cuando get9oreIesults devuelve false quiere decir que la sentencia SQL $a
devuelto un update count o que no $ay ms resultados +or tanto es necesario
llamar al m!todo get4pdateCount para encontrar cual es el caso %n esta situaci#n,
no $abr ms resultados cuando lo siguiente es cierto<
2+
BBs#*#.4e#=o!e5esul#sBC OO %alseC PP Bs#*#.4e#3da#eCoun#BC OO Q1CC
%l siguiente c#digo muestra una forma de asegurarse que se $a accedido a todos
los result sets y update counts de una llamada al m!todo e5ecute<
stmt.e"ec!te(A!er$StringDit+En8nownes!lts);
w+ile (tr!e) ,
int rowCo!nt = stmt.getEpdateCo!nt();
i. (rowCo!nt : C) , 00 t+is is an !pdate co!nt
S$stem.o!t.println("ows c+anged = " Y co!nt);
stmt.getMorees!lts();
contin!e;
/
i. (rowCo!nt == C) , 00 DD& command or C !pdates
S$stem.o!t.println(" Io rows c+anged or statement was DD&
command");
stmt.getMorees!lts();
contin!e;
/

00 i. we +ave gotten t+is .ar, we +ave eit+er a res!lt set
00 or no more res!lts

es!ltSet rs = stmt.getes!ltSet;
i. (rs Z= n!ll) ,
. . . 00 !se metadata to get in.o abo!t res!lt set col!mns
w+ile (rs.ne"t()) ,
. . . 00 process res!lts
stmt.getMorees!lts();
contin!e;
/
brea8; 00 t+ere are no more res!lts
2>
,. .A C.A-3 Resu#'-e'
,.1 6is'a Pre#i/inar
4n IesultSet contiene todas las filas que satisfacen las condiciones de una
sentencia SQL y proporciona el acceso a los datos de estas filas mediante un
con1unto de m!todos get que permiten el acceso a las diferentes columnas de la
filas %l m!todo IesultSetne5t se usa para moverse a la siguiente fila del result
set, convirtiendo a !sta en la fila act"al
%l formato general de un result set es una tabla con cabeceras de columna y los
valores correspondientes devueltos por la =query> +or e1emplo, si la =query> es
S%&%C' a, b, c ()M 'able*, el resultado tendr una forma seme1ante a <
a b c
55555555 555555555 55555555
*2;[< C!pertino CH
R;[B2 edmond DH
R;[Q2 Koston MH
%l siguiente fragmento de c#digo es un e1emplo de la e1ecuci#n de una sentencia
SQL que devolver una colecci#n de filas, con la columna ) como un int, la
columna C como una String y la columna E como un array de bytes<
java.sAl.Statement stmt = conn.createStatement();
es!ltSet r = stmt.e"ec!te#!er$("S%&%C' a, b, c ()M 'able*");
w+ile (r.ne"t())
,
00 print t+e val!es .or t+e c!rrent row.
int i = r.get-nt("a");
String s = r.getString("b");
.loat . = r.get(loat("c");
S$stem.o!t.println(")D = " Y i Y " " Y s Y " " Y .);
/
,.1.1 0i#as $ Curs"res
4n es!ltSet mantiene un cursor que apunta a la fila act"al de datos %l cursor se
mueve una fila $acia aba1o cada ve- que se llama al m!todo ne"t /ncialmente se
sit"a antes de la primera fila, por lo que $ay que llamar al m!todo ne"t para
situarlo en la primera fila conviertiendola en la fila act"al Las filas de es!ltSet
se recuperan en secuencia desde la fila ms alta a la ms ba1a
4n cursor se mantiene vlido $asta que el ob1eto Iesultset o su ob1eto padre
Statement se cierra
$/
%n SQL, el cursor resultado para una tabla tiene nombre Si una base de datos
permite upadtes posicionados o deletes posicionados, el nombre del cursor es
necesario y debe ser proporcionado como un parmetro del comando update o
delete %l nombre del cursor puede obtenerse mediante una llamada al m!todo
getC!rsorIame
.o todas las bases de datos soportan updates o deletes posicionados Los m!todos
DatabaseMetaData.s!pportsFositionedDelete y
DatabaseMetaData.s!pportsFositionedEpdate nos permiten descubrir si
estas operaciones estn soportadas en una cone5i#n dada Cuando lo estn, el
driver o la DB9S deben asegurarse que las filas seleccionadas estn
apropiadamente bloquedas y por tanto que estas operaciones no provoquen
actuali-aciones anomalas ni otros problemas de concurrencia
,.1.2 C"#u/nas
Los m!todos get::: suministran los medios para recuperar los valores de las
columnas de la fila act"al Dentro de cada fila, los valores de las columnas pueden
recuperarse en cualquier orden, pero para asegurar la m5ima portabilidad,
deber;an e5traerse las columnas de i-quierda a derec$a y leer los valores de las
columnas una "nica ve-
+uede usarse o bien el nombre de la columna o el n"mero de columna para
referirse a esta +or e1emplo< si la columna segunda de un ob1eto ecordSet rs se
denomina 2title3 y almacena valores de cadena, cualquiera de los dos e1emplos
siguientes nos devolver el valor almacenado en la columna
String s = rs.getString("title");
String s = rs.getString(2);
.#tese que las columnas se numeran de i-quierda a derec$a comen-ando con la
columna ) 0dems los nombres usados como input en los m!todos getVVV son
insensibles a las may"sculas
La opci#n de usar el nombre de columna fue provista para que el usuario que
especifica nombres de columnas en una =query> pueda usar esos nombres como
argumentos de los m!todos getVVV Si, por otro lado, la sentencia select no
especifica nombres de columnas (tal como en 2select @ .rom table*\ o en
casos donde una columna es derivada), deben usarse los n"meros de columna %n
estas situaciones , no $ay forma de que el usuario sepa con seguridad cuales son
los nombres de las columnas
$1
%n algunos casos, es posible para una query SQL devolver un result set con ms de
una columna con el mismo nombre Si se usa el nombre de columna como
argumento en un m!todo getVVV, !ste devolver el valor de la primera columna
que coincida con el nombre +or eso, si $ay m"ltiples columnas con el mismo
nombre, se necesita usar un ;ndice de columna para asegurarse que se recupera el
valor de la columna correcta %sto puede ser ligeramente ms eficiente que usar los
n"meros de columna
/nformaci#n acerca de las columnas en un es!ltSet es accesible mediante el
m!todo es!ltSet.getMetaData %l ob1eto es!ltSetMetaData devuelto nos
da el numero, tipo y propiedades de las columnas de los ob1etos es!ltSet
Si se conoce el nombre de una columna, pero no su indice, puede usarse el m!todo
.indCol!mn para encontrar el n"mero de columna
,.1.( Ti%"s de da'"s $ c"nversi"nes.
+ara los m!todos get:::, el driver JDBC intenta convertir los datos subyacentes a
tipos de datos Java +or e1emplo, si el m!todo get::: es getString y los tipos de
datos de la base de datos en la base subyacente es V0ICB0I, el driver JDBC
convertir V0ICB0I en String de Java %l valor devuelto por getString ser un
ob1eto Java de tipo String
La siguiente tabla muestra que tipos JDBC est permitido devolver para un m!todo
get::: y que tipos JDBC (tipos gen!ricos de SQL) se recomiendan para
recuperarlos 4na 5 indica un m!todo get::: legal para un tipo de dato particular
+or e1emplo, cualquier m!todo get::: e5cepto getBytes o getBinaryStream puede
usarse para recuperar valores de tipo L(.PV0ICB0I, pero se recomienda usar
get0sciiStream o get4nicodeStream, dependiendo de que tipo de dato se devuelve
%l m!todo get(b1ect devolver cualquier tipo de dato como un (b1ect Java y es util
cuando los tipos de datos de la DB9S subyacente son abstractos espec;ficos de
!sta o cuando una aplicaci#n gen!rica necesita aceptar cualquier tipo de datos
%l uso de los m!todos IesultSetget::: recuperan tipos de datos comunes JDBC
4na 253 indica que el m!todo get::: puede legalmente usarse para recuperar el
tipo JDBC dado
4na 243 indica que el m!todo get::: es el recomendado para recuperar el tipo de
dato dado
$2
,.1.* Us" de -'rea/s va#"res /u$ 9randes de )i#as
IesultSet $ace posible el recuperar datos arbitrariamente grandes de tipo
L(.PV0IB/.0I6 o L(.PV0ICB0I Los m!todos getBytes y getString
devuelven valores grandes ($asta los l;mites impuestos por el valor devuelto por
Statementget9a5JieldSi-e)

$
%
&
'
%
&
$
(
)
*
+
+
%
&
$
%
&
$
,
-
,
.
B
%
-
&
$
.
,
*
+
/
+
0
*
$
D
0
1
B
+
,
D
,
C
%
)
*
+
&
1
)
,
.
%
C
B
%
$
C
2
*
.
V
*
.
C
2
*
.
+
0
&
-
V
*
.
C
2
*
.
B
%
&
*
.
'
V
*
.
B
%
&
*
.
'
+
0
&
-
V
*
.
B
%
&
*
.
'
D
*
$
,
$
%
)
,
$
%
)
,
(
$
*
)
P
4e#By#e 3 1 1 1 1 1 1 1 1 1 1 1 1
4e#(ho!# 1 3 1 1 1 1 1 1 1 1 1 1 1
4e#In# 1 1 3 1 1 1 1 1 1 1 1 1 1
4e#)on4 1 1 1 3 1 1 1 1 1 1 1 1 1
4e#,loa# 1 1 1 1 3 1 1 1 1 1 1 1 1
4e#Double 1 1 1 1 1 3 3 1 1 1 1 1 1
4e#Bi4Deci*al 1 1 1 1 1 1 1 3 3 1 1 1 1
4e#Boolean 1 1 1 1 1 1 1 1 1 3 1 1 1
4e#(#!in4 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1
4e#By#es 3 3 1
4e#Da#e 1 1 1 3 1
$$
4e#0i*e 1 1 1 3 1
4e#0i*es#a* 1 1 1 1 3
4e#Ascii(#!ea* 1 1 3 1 1 1
4e#3nicode(#!ea* 1 1 3 1 1 1
4e#Bina!y(#!ea* 1 1 3
4e#&bjec# 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
$6
De todos modos, puede ser conveniente recuperar datos muy grandes en =peda-os>
de tama?o fi1o %sto se $ace mediante la clase es!ltSet que devuelve =streams>
1avaio/nput desde los cuales los datos pueden ser leidos en =peda-os> .Wtese que
estas corrientes deben ser accedidas inmediatamente porque se cierran
automticamente con la llamada al siguiente m!todo getVVV de es!ltSet (%ste
comportamiento est impuesto por las restricciones de implementaci#n de acceso a
grandes blob)
%l 0+/ JDBC tiene tres m!todos diferentes para recuperar streams, cada uno con
un valor diferente de retorno
getKinar$Stream devuelve una corriente que simplemente suminiistra
bytes en =bruto> desde la base de datos sin ninguna conversi#n
getHsciiStream devuelve una corriente con caracteres 0SC//
getEnicodeStream devuelve una corriente con caracteres 4nicode
)
de C
bytes
.otar que esto difiere de las corrientes Java que devuelven bytes sn tipo y pueden
(por e1emplo) usarse para ambos caracteres 0SC// y 4nicode
0 continuaci#n veamos un e1emplo del uso de get0sciiStream<
java.sAl.Statement stmt = con.createStatement();
es!ltSet r = stmt.e"ec!te#!er$("S%&%C' " ()M 'able2");
00 Iow retrieve t+e col!mn * res!lts in [ 4 c+!n8s:
b$te b!.. = new b$te>[CQ=?;
w+ile (r.ne"t()) ,
3ava.io.-np!tStream .in = r.getHsciiStream(*);
.or (;;) ,
int si7e = .in.read(b!..);
i. (si7e == 5*) , 00 at end o. stream
brea8;
/
00 Send t+e newl$5.illed b!..er to some HSC-- o!tp!t stream:
1
Unic"de
4nicode es un esquema de codificaci#n de caracteres que utili-a C bytes por cada carcter /S(
(/nternational Standards (rgani-ation) define un n"mero dentro del intervalo * a YMMEM (C
)Y
N )) por
cada carcter y s;mbolo de cada idioma (ms algunos espacios vac;os para futuras ampliaciones) %n
todas las versiones de EC bits de 8indo7s, el 9odelo de ob1etos componentes (C(9), que es la
base de las tecnolog;as (L% y 0ctive:, utili-a 4nicode 4nicode es totalmente compatible con
$5
o!tp!t.write(b!.., C, si7e);
/
/
,.1., 6a#"res resu#'ad" NU..
+ara determinar si un valor resultado dado es JDBC .4LL, primero debe intentarse
leer la columna y usar el m!todo es!ltSet.wasI!ll para descubrir si el valor
devuelto es JDBC .4LL
Cuando se $a leido un JDBC .4LL usando uno de los m!todos
es!ltSet.getVVV, el m!todo wasI!ll devuelve algo de lo siguiente<
4n valor null de Java para aquellos m!todos get::: que devuelven ob1etos
Java (tales como getString, getKigDecimal, getK$tes, getDate,
get'ime, get'imestamp, getHsciiStream, getEnicodeStream,
getKinar$Stream, get)bject)
4n valor cero para getK$te, getS+ort, get-nt, get&ong,
get(loat $ getDo!ble
4n valor false para getKoolean
,.1.> Resu#' se's "%ci"na#es " /C#'i%#es.
.ormalmente cuando se e1ecuta una sentencia SQL o bien se usa e"c!te#!er$
(que devuelve un "nico es!ltSet) o bien e"ec!teEpdate (que puede usarse
para cualquier tipo de sentencia de modificaci#n de la base de datos y que devuelve
un contador de las filas que $an sido afectadas De cualquier modo, ba1o ciertas
circunstancias una aplicaci#n puede no saber si una sentencia devolver un result
set $asta que !sta no $aya sido e1ecutada 0dems, ciertos procedimientos
almacenados pueden devolver varios result sets yHo update counts
+ara acomodarse a estas situaciones, JDBC provee de un mecanismo por el cual
una aplicaci#n puede e1ecutar una sentencia y luego procesar una colecci#n
arbitraria de result sets y update counts %ste mecanismo se basa en una primera
llamada a un m!todo general e"ec!te y luego llamar a otros tres m!todos
getes!ltSet, getEpdateCo!nt y getMorees!lts %stos m!todos permiten
a una aplicaci#n e5plorar los resultados de las sentencias y determinar si dan como
resultado un result set o un update count
$'
.o se necesita $acer nada para cerrar un IesultSet Se cierra automticamente
cuando por la Statement que la crea cuando se cierra esta, y se reutili-a cuando
cuando se recupera el pr#5imo resultado de una secuencia de m"ltiples resultados
>. .A C.A-3 Pre%ared-'a'e/en'
>.1 6is'a Pre#i/inar
La interfase +reparedStatement $ereda de Statement y difiere de esta en dos
maneras
Las instancias de FreparedStatement contienen una sentencia SQL que
ya $a sido compilada %sto es lo que $ace que se le llame =preparada>
La sentencia SQL contenida en un ob1eto FreparedStatement pueden
tener uno o ms parmetros -I 4n parmetro -I es aquel cuyo valor no se
especifica en la sentencia SQL cuando se crea %n ve- de ello la sentencia
tiene un interrogante (=A>) como un =enca1e> para cada parmetro -I Debe
suministrarse un valor para cada interrogante mediante el m!todo apropiado
setVVV antes de e1ecutar la sentencia
Como los ob1etos FreparedStatement estn precompilados, su e1ecuci#n es ms
rpida que los ob1etos Statement Consecuentemente, una sentencia SQL que se
e1ecute muc$as veces a menudo se crea como FreparedStatement para
incrementar su eficacia
Siendo una subclase de Statement, FreparedStatement $ereda toda la
funcionalidad de Statement 0dems , se a?ade un set completo de m!todos
necesarios para fi1ar los valores que van a ser enviados a la base de datos en el
lugar de los =enca1es> para los parmetros /. Lambi!n se modifican los tres
m!todos e"ec!te, e"ec!te#!er$ y e"ec!teEpdate de tal forma que no toman
argumentos Los formatos de Statement de estos m!todos (los formatos que toman
una sentencia SQL como argumento) no deber;an usarse nunca con ob1etos
+reparedStatement
>.1.1 Creaci8n de "!e'"s Pre%ared-'a'e/en'
%l siguiente e1emplo, donde con es un ob1eto Connection, crea un ob1eto
+reparedStatement conteniendo una sentencia SQL con dos =enca1es> para
parmetros /.
FreparedStatement pstmt = con.prepareStatement(
"EFDH'% table[ S%' m = T DM%% " = T");
$;
%l ob1eto pstmt contiene a$ora la sentencia 2EFDH'% table[ S%' m= T DM%%
" = T 2, que ya $a sido enviada a la base de datos y $a sido preparada para su
e1ecuci#n
>.1.2 Pasar %arD/e'r"s IN
0ntes de que un ob1eto FreparedStatement sea e1ecutado debe fi1arse el valor
de cada enca1e =A> Se $ace esto mediante la llamada a un m!todo setVVV, donde
::: es el tipo apropiado para el parmetro +or e1emplo, si el parmetro tiene un
tipo Java long, el m!todo a usar ser set&ong %l primero de los argumentos del
m!todo setVVV es la posici#n ordinal del parmetro a fi1ar, y el segundo
argumento es el valor que queremos que adquiera el parmetro +or e1emplo, lo
siguiente fi1a el primer parmetro a )CEFMYXZ[ y el segundo a )*******
pstmt.set&ong(*, *2;[<=BRQ);
pstmt.set&ong(2, *CCCCCCCC);
4na ve- que el valor $a sido fi1ado para una sentencia dada, puede usarse para
m"ltiples e1ecuciones de esa sentencia $asta que se limpie mediante el m!todo
Clear+arameters
%n el modo por defecto para una cone5i#n (modo auto'commit activo), cada
sentencia es conmitada o rec$a-ada automticamente cuando se completa
%l mismo ob1eto FreparedStatement puede e1ecutarse m"ltiples veces si la base
de datos subyacente y el driver guardan las sentencias abiertas despu!s que $ayan
sido =conmitadas> 0 menos que se de este caso, no $ay un punto en el que intentar
me1orar el rendimiento mediante el uso de ob1etos FreparedStatement en lugar
de ob1etos Statement
4sando pstmt, el ob1eto FreparedStatement creado anteriormente, el siguiente
e1emplo ilustra como fi1ar los parmetros de los dos =enca1es> y e1ecutar pstmt )*
veces Como se $a mencionado anteriormente, la base de datos no debe cerrar
pstmt %n este e1emplo, el primer parmetro se fi1a a 2Bi3 y permanece constante
%l segundo parmetro se fi1a a un valor diferente en cada e1ecuci#n mediante el
bucle for comen-ando en * y terminando en [
pstmt.setString(*, "Mi");
.or (int i = C; i 9 *C; iYY) ,
pstmt.set-nt(2, i);
int rowCo!nt = pstmt.e"ec!teEpdate();
/
$+
>.1.( C"n)"r/idad de 'i%"s de da'"s en %arD/e'r"s IN
%l ::: en los m!todos setVVV son tipos Java %stos son los tipos impl;citos de
JDBC (tipos gen!ricos SQL) porque el driver mapear el tipo Java en su
correspondiente tipo JDBC (ver la secci#n Z para ms informaci#n sobre el mapeo
de tipos), y env;an ese tipo JDBC a la base de datos %l siguiente e1emplo fi1a el
segundo parmetro del ob1eto FreparedStatement pstmt a FF con un tipo Java
s+ort
pstmt.setS+ort(2, [[);
%l driver enviar FF a la base de datos como un JDBC S90LL/.L que es el mapeo
estndar para un s$ort Java
%s responsabilidad del programador asegurarse que el tipo Java en cada parmetro
/. mapeado a un tipo de JDBC es compatible con el tipo de dato JDBC esperado
por la base de datos Consideremos el caso en el que la base de datos espera un
tipo de datos S90LL/.L S/ se usa el m!todo setByte , el driver enviar un JDBC
L/.6/.L a la base de datos %sto probablemente funcionar porque muc$as bases
de datos convierten un tipo relacionado en otro, y, generalmente, un tipo L/.6/.L
puede ser usado donde un S90LL/.L De cualquier modo, una aplicaci#n que
traba1e para la mayor;a de bases de datos posibles, es preferible que use tipos Java
que se correspondan con el tipo e5acto JDBC esperado por la base de datos Si el
tipo esperado es S90LL/.L, usar setS$ort en ve- de setByte y esto $ar la
aplicaci#n ms portable
>.1.* Usar se'O!ec'
4n programador puede convertir e5plicitamente un parmetro de entrada en un tipo
particular JDBC mediante el uso de set)bject %ste m!todo puede tomar un
tercer argumento que especifica el tipo JDBC ob1etivo %L driver convertir el
)bject Java al tipo especificado JDBC anten de enviarlo a la base de datos
Si no se da el tipo JDBC, el driver simplemente mapear el )bject Java a su tipo
JDBC por defecto (usando la tabla de la secci#n Z) y lo enviar a la base de datos
%sto es similar a lo que ocurre con los m!todos setVVV regulares %n ambos
casos, el driver mapea el tipo Java del valor al tipo JDBC apropiado antes de
enviarlo a la base de datos La diferencia est en que los m!todos setVVV usan el
mapeo estndar de los tipos Java a tipos JDBC, mientras que el m!todo usa el
mapeo desde typos (b1ect de Java a tipos JDBC (ver la tabla en la secci#n ZYF)
$>
La capacidad de el m!todo set)bject para aceptar cualquier ob1eto Java permite
a una aplicaci#n ser gen!rica y aceptar entradas para un parmetro en tiempo de
e1ecuci#n %n esta situaci#n el tipo de entrada no es conocido cuando la aplicaci#n
es compilada 9ediante el uso de set)bject, la aplicaci#n puede aceptar
cualquier tipo de ob1eto Java como entrada al tipo JDBC esperado por la base de
datos La tabla de la secci#n ZYM muestra todas las posibles conversiones qiue
set)bject puede reali-ar
>.1., 3nv?" de JDBC NU.. c"/" un %arD/e'r" IN
%l m!todo setI!ll permite a los programadores enviar valores JDBC .4LL a la
base de datos como un parmetro -I .otese de cualquier modo, que debe
especificarse el tipo del parmetro
Lambi!n se enviar un JDBC .4LL a la base de datos cuando un valor Java n!ll
se pasa mediante un m!todo setVVV (si los acepta los ob1etos Java como
argumentos) %l m!todo set)bject, en cualquier caso, puede tomar un valor null
"nicamente si se $a especificado el tipo JDBC
>.1.> 3nvi" de %arD/e'r"s IN /u$ 9randes.
Los m!todos setK$tes y setString son capaces de enviar cantidades ilimitadas
de datos De cualquier forma, a veces los programadores prefiern pasar los grandes
blobs de datos en peque?os =peda-os> %sto puede reali-arse fi1ando un parmetro
/. a una corriente Java Cuando se e1ecuta la sentencia, el driver JDBC reali-ar
repetidas llamadas a esta corriente de entrada, leyendo sus contenidos y
transmitiendo estos contenidos con los datos actuales de los parmetros
JDBC suministra tres m!todos para fi1ar parmetros /. a corrientes de entrada
setKinar$Stream para corrientes que contienen bytes, setHsciiStream para
corrientes que contienen caracteres 0SC// y setEnicodeStream para corrientes
que contienen caracteres 4nicode %stos m!todos toman un argumento mas que
los otros m!todos set::: porque debe especificarse la longitud de la corriente
%sto es necesario porque algunas bases de datos necesitan conocer el tama?o total
de los datos a transferir antes de enviarlos
%l siguiente e1emplo ilustra el uso de una corriente para enviar el contenido de un
fic$ero en un parmetro /.
6/
java.io.(ile .ile = new java.io.(ile("0tmp0data");
int .ile&engt+ = .ile.lengt+();
java.io.-np!tStream .in = new java.io.(ile-np!tStream(.ile);
java.sAl.FreparedStatement pstmt = con.prepareStatement(
"EFDH'% 'able< S%' st!.. = T DM%% inde" = [");
pstmt.setKinar$Stream (*, .in, .ile&engt+);
pstmt.e"ec!teEpdate();
Cuando la sentencia se e1ecuta, la corriente de entrada fin ser llamada
repetidamente $asta completar los datos
@. .A C.A-3 Ca##a#e-'a'e/en'
@.1 6is'a Pre#i/inar
4n ob1eto CallableStatement provee de una forma estndar de llamar a
procedimientos almacenados de la base de datos 4n procedimiento almacenado
se encuentra en la base de datos La llamada al procedimiento es lo que contiene el
ob1eto CallableStatement %sta llamada se escribe en una sinta5is de escape que
puede tomar una de dos formas< una formato con un parmetro resultado y el otro
sin el (Ver la secci#n F para mas informaci#n sobre la sinta5is de escape) 4n
parmetro resultado, un tipo de parmetro (4L, es el valor devuelto por el
procedimiento almacenado 0mbos formatos pueden tener un n"mero variable de
parmetros de entrada (parmetros /.), de salida (parmetros (4L) o mbos
(parmetros /.(4L) 4n interrogante sirve como =ancla1e> para cada parmetro
La sinta5is para invocar un procedimiento almacenado en JDBC se muestra a
continuaci#n< .otar que los corc$etes indican que lo que se encuenta contenido en
ellos es opcional, no ofroma parte de la sinta5is
,call proced!re6name>(T, T, ...)?/
La sinta5is para un procedimiento que devuelve un resultado es<
,T = call proced!re6name>(T, T, ...)?/
La sinta5is para un procedimiento almacenado sin parmetros se parece a algo
como<
,call proced!re6name/
.ormalmente, alquien que crea un ob1eto CallableStatement deber;a saber ya
si la DB9S que est usando soporta o no procedimientos almacenados y que son
estos Si alguien necesita c$equearlo de cualquier modo, e5isten varios m!todos de
DatabaseMetaData que suministran tal informaci#n +or e1emplo, el m!todo
s!pportsStoredFroced!res devolver tr!e si la DB9S soporta llamadas a
61
procedimientos almacenados y el m!todo getFroced!res devolver una
descripci#n de los procedimientos almacenados disponibles
CallableStatement $ereda los m!todos de Statement, los cuales tratan
sentencias SQL en general, y tambi!n $ereda los m!todos de
FreparedStatement, que tratan los parmetros /. Lodos los m!todos definidos
para CallableStatement tratan los parmetros (4L o los aspectos de salida de
los parmetros /.(4L< registro de los tipos JDBC (tipos gen!ricos SQL) de los
parmetros (4L, recuperaci#n de valores desde ellos o c$equear si el valor
devuelto es un JDBC .4LL
@.1.1 Crear "!e'"s Ca##a#e-'a'e/en'
Los ob1etos CallableStatement se crean con el m!todo prepareCall de
Connection %l siguiente e1emplo crea una instancia de CallableStatement
que contiene una llamada al procedimiento almacenado get'estData, con dos
argumentos y no devuelve resultados
CallableStatement cstmt = con.prepareCall(
",call get'estData(T, T)/");
donde los enca1es =A> son parmetros /., (4L # /.(4L dependiendo del
procedimiento get'estData
@.1.2 ParD/e'r"s IN $ OUT
%l paso de valor para cualquier parmetro /. de un ob1eto CallableStatement
se reali-a mediante los m!todos setVVV $eredados de FreparedStatement %l
tipo de el valor a pasar se determina por el m!todo setVVV a usar (set(loat para
pasar un valor .loat, y as;)
Si el procedimiento almacenado devuelve parmetros (4L, el tipo JDBC de cada
parmetro (4L debe ser registrado antes de que el ob1eto CallableStatement
sea e1ecutado (%sto es necesario porque algunas DB9S necesitan el tipo JDBC) %l
registro del tipo JDBC se reali-a mediante el m!todo register)!tFarameters
Despu!s que la sentencia $a sido e1ecutada, los m!todos getVVV de
CallableStatement recuperan los valores de los parmetros %l m!todo correcto
getVVV a usar es el tipo Java que corresponde al tipo JDBC registrado para el
parmetro (%l mapeo estndar para los tipos JDBC a tipos Java se muestra en la
tabla de la secci#n ZY)) %n otras palabras register)!tFarameter usa un tipo
62
JDBC (por tanto coincide con el tipo con el tipo JDBC que la base de datos
devolver) y getVVV =casts> este a un tipo Java
+ara ilustrar esto, el siguiente e1emplo registra los parmetros (4L, e1ecuta el
procedimiento almacenado llamado por cstmt y recupera los valores devueltos en
los parmetros (4L %l m!todo getK$te recupera un byte Java de el primer
parmetro, y getKigDecimal recupera un ob1eto KigDecimal (con tres d;gitos
despu!s del punto decimal) del segundo parmetro (4L<
CallableStatement cstmt = con.prepareCall(
",call get'estData(T, T)/");
cstmt.register)!tFarameter(*, java.sAl.'$pes.'-I]-I');
cstmt.register)!tFarameter(2, java.sAl.'$pes.D%C-MH&, ;);
cstmt.e"ec!te#!er$();
b$te " = cstmt.getK$te(*);
java.mat+.KigDecimal n = cstmt.getKigDecimal(2, ;);
De modo distinto a IesultSet, CallableStatement no tiene un mecanismo especial
para recuperar grandes valores (4L incrementalmente
@.1.( ParD/e'r"s INOUT
Son parmetros que suminstran entradas as; como aceptan salidas %stos
requieren llamar a los m!todos apropiados setVVV ($eredados de
FreparedStatement) adems de llamar al m!todo register)!tFarameter
Los m!todos setVVV fi1an los valores como parmetros de entrada y
register)!tFarameter registra sus tipos JDBC como parmetros de salida %l
m!todo setVVV suminstra un valor Java que el driver convierte en un valor JDBC
antes de enviarlo a la base de datos
%l tipo JDBC del valor /. y el tipo JDBC para suminstrado al m!todo
register)!tFarameter debe ser el mismo Luego, para recuperar el valor de
salida, se usa el m!todo apropiado getVVV +or e1emplo, un parmetro cuyo tipo
Java es b$te deber;a usar el m!todo setK$te para asignar el valor de entrada,
deber;a suplir un L/.6/.L como tipo JDBC para register)!tFarameter, y
deber;a usar getK$te para recuperar el valor de salida (Seccion Z, da ms
informaciWn y contiene tablas de tipos mapeados)
%l siguiente e1emplo asume que e5iste un procedimiento almacenado
revise'otal con un "nico parmetro /.(4L %l m!todo setK$te fi1a el valor del
parmetro a CM que es el que el driver enviar a la base de datos como un JDBC
L/.6/.L Despu!s register)!tFarameter registrar el parmetro como un
JDBC L/.6/.L Luego que el procedimiento sea e1ecutado se devolver un nuevo
JDBC L/.6/.L y el m!todo getK$te lo recuperar como un nuevo valor b$te
Java
6$
CallableStatement cstmt = con.prepareCall(
",call revise'otal(T)/");
cstmt.setK$te(*, 2<);
cstmt.register)!tFarameter(*, java.sAl.'$pes.'-I]-I');
cstmt.e"ec!teEpdate();
b$te " = cstmt.getK$te(*);
@.1.* Recu%erar %arD/e'r"s OUT des%us de resu#'ad"s
Dadas las limitaciones impuestas pro algunas DB9S, se recomienda en aras de la
m5ima portabilidad, que todos los resultados generados por la e1ecuci#n de un
ob1eto CallableStatement deber;an recuperarse antes que los parmetros (4L
usando los m!todos CallableStatementgetVVV
Si un ob1eto CallableStatement devuelve m"ltiples ob1etos es!ltSet
(mediante una llamada al m!todo e"ec!te), todos los resultados deben
recuperarse antes que los parmetros (4L %n este caso, debe asegurarse de que
todos los resultados $an sido accedidos, los m!todos de Statement
getes!ltSet, getEpdateCo!nt y getMorees!lts necesitan ser llamados
$asta que no $aya ms resultados
Despu!s de $ec$o esto, los valores de los parmetros (4L pueden ser
recuperados mediante los m!todos CallableStatement.getVVV
@.1., Recu%erar va#"res NU.. en %arD/e'r"s OUT
%l valor devuelto en un parmetro (4L puede ser JDBC .4LL Cuando esto ocurre,
le valor JDBC .4LL se convertir de forma que el valor devuelto por el m!todo
getVVV sea null, * o false dependiendo del tipo del m!todo getVVV usadoComo
con los ob1etos es!ltSet, la "nica manera de saber si un valor de * o false fue
originalmente .4LL JDBC es testear el m!todo wasI!ll, que devuelve true si el
"ltimo valor le;do por un m!todo get::: fue JDBC .4LL y false en caso contrario
La secci#n M contiene ms informaci#n al respecto
66
E. 3J3+P.O D3 CODIFO
00 '+e .ollowing code can be !sed as a template. Simpl$
00 s!bstit!te t+e appropriate !rl, login, and password, and t+en
s!bstit!te t+e
00 S#& statement $o! want to send to t+e database.
005555555555555555555555555555555555555555555555555555555555555555555
555555555
00
00 Mod!le: SimpleSelect.java
00
00 Description: 'est program .or )DKC HF- inter.ace. '+is java
application
00 will connect to a 3DKC driver, iss!e a select statement
00 and displa$ all res!lt col!mns and rows
00
00 Frod!ct: 3DKC to )DKC Kridge
00
00 H!t+or: 4arl Moss
00
00 Date: (ebr!ar$, *QQ=
00
00 Cop$rig+t: *QQC5*QQ= -I'%S)&^, -nc.
00 '+is so.tware contains con.idential and proprietar$
00 in.ormation o. -I'%S)&^, -nc.
005555555555555555555555555555555555555555555555555555555555555555555
555555555
import java.net.E&;
import java.sAl.@;
class SimpleSelect ,
p!blic static void main (String args>?) ,
String !rl = "jdbc:odbc:m$5dsn";
String A!er$ = "S%&%C' @ ()M emp";
tr$ ,
00 &oad t+e jdbc5odbc bridge driver
Class..orIame ("s!n.jdbc.odbc.3dbc)dbcDriver");
DriverManager.set&ogStream(S$stem.o!t);
00 Httempt to connect to a driver. %ac+ one
00 o. t+e registered drivers will be loaded !ntil
00 one is .o!nd t+at can process t+is E&
Connection con = DriverManager.getConnection (
!rl, "m$5!ser", "m$5passwd");
65
00 -. we were !nable to connect, an e"ception
00 wo!ld +ave been t+rown. So, i. we get +ere,
00 we are s!ccess.!ll$ connected to t+e E&
00 C+ec8 .or, and displa$ and warnings generated
00 b$ t+e connect.
c+ec8(orDarning (con.getDarnings ());
00 Xet t+e DatabaseMetaData object and displa$
00 some in.ormation abo!t t+e connection
DatabaseMetaData dma = con.getMetaData ();
S$stem.o!t.println("OnConnected to " Y dma.getE&());
S$stem.o!t.println("Driver " Y
dma.getDriverIame());
S$stem.o!t.println("^ersion " Y
dma.getDriver^ersion());
S$stem.o!t.println("");
00 Create a Statement object so we can s!bmit
00 S#& statements to t+e driver
Statement stmt = con.createStatement ();
00 S!bmit a A!er$, creating a es!ltSet object
es!ltSet rs = stmt.e"ec!te#!er$ (A!er$);
00 Displa$ all col!mns and rows .rom t+e res!lt set
dispes!ltSet (rs);
00 Close t+e res!lt set
rs.close();
00 Close t+e statement
stmt.close();
00 Close t+e connection
con.close();
/
catc+ (S#&%"ception e") ,
00 H S#&%"ception was generated. Catc+ it and
00 displa$ t+e error in.ormation. Iote t+at t+ere
00 co!ld be m!ltiple error objects c+ained
00 toget+er
6'
S$stem.o!t.println ("On@@@ S#&%"ception ca!g+t @@@On");
w+ile (e" Z= n!ll) ,
S$stem.o!t.println ("S#&State: " Y
e".getS#&State ());
S$stem.o!t.println ("Message: " Y e".getMessage ());
S$stem.o!t.println ("^endor: " Y
e".get%rrorCode ());
e" = e".getIe"t%"ception ();
S$stem.o!t.println ("");
/
/
catc+ (java.lang.%"ception e") ,
00 Xot some ot+er t$pe o. e"ception. D!mp it.
e".printStac8'race ();
/
/
005555555555555555555555555555555555555555555555555555555555555555555
00 c+ec8(orDarning
00 C+ec8s .or and displa$s warnings. et!rns tr!e i. a warning
00 e"isted
005555555555555555555555555555555555555555555555555555555555555555555
private static boolean c+ec8(orDarning (S#&Darning warn)
t+rows S#&%"ception ,
boolean rc = .alse;
00 -. a S#&Darning object was given, displa$ t+e
00 warning messages. Iote t+at t+ere co!ld be
00 m!ltiple warnings c+ained toget+er
i. (warn Z= n!ll) ,
S$stem.o!t.println ("On @@@ Darning @@@On");
rc = tr!e;
w+ile (warn Z= n!ll) ,
S$stem.o!t.println ("S#&State: " Y
warn.getS#&State ());
S$stem.o!t.println ("Message: " Y
warn.getMessage ());
S$stem.o!t.println ("^endor: " Y
warn.get%rrorCode ());
S$stem.o!t.println ("");
warn = warn.getIe"tDarning ();
/
/
ret!rn rc;
/
6;
005555555555555555555555555555555555555555555555555555555555555555555
00 dispes!ltSet
00 Displa$s all col!mns and rows in t+e given res!lt set
005555555555555555555555555555555555555555555555555555555555555555555
private static void dispes!ltSet (es!ltSet rs)
t+rows S#&%"ception
,
int i;
00 Xet t+e es!ltSetMetaData. '+is will be !sed .or
00 t+e col!mn +eadings
es!ltSetMetaData rsmd = rs.getMetaData ();
00 Xet t+e n!mber o. col!mns in t+e res!lt set
int n!mCols = rsmd.getCol!mnCo!nt ();
00 Displa$ col!mn +eadings
.or (i=*; i9=n!mCols; iYY) ,
i. (i : *) S$stem.o!t.print(",");
S$stem.o!t.print(rsmd.getCol!mn&abel(i));
/
S$stem.o!t.println("");
00 Displa$ data, .etc+ing !ntil end o. t+e res!lt set
boolean more = rs.ne"t ();
w+ile (more) ,
00 &oop t+ro!g+ eac+ col!mn, getting t+e
00 col!mn data and displa$ing
.or (i=*; i9=n!mCols; iYY) ,
i. (i : *) S$stem.o!t.print(",");
S$stem.o!t.print(rs.getString(i));
/
S$stem.o!t.println("");
00 (etc+ t+e ne"t res!lt set row
more = rs.ne"t ();
/
/
/
6+

También podría gustarte