101
  2008-II Camilo Andrés Ferrer Bustos Hogar 2008II ACCESO A DATOS CON JAVA: NOTAS DE CLASE

Notas de Clase Acceso a Datos Con Java

  • Upload
    dyanbrs

  • View
    1.895

  • Download
    1

Embed Size (px)

Citation preview

2008IIACCESOADATOSCONJAVA: NOTASDECLASE

CamiloAndrsFerrerBustosHogar 2008II

Tabladecontenido

CaptuloI.................................................................................................................................4 INTRODUCCIONALASBASESDEDATOSRELACIONALES.......................................................4 OBJETOSBASICOS...............................................................................................................4 Tabla................................................................................................................................4 Fila...................................................................................................................................5 Columna..........................................................................................................................5 Clave................................................................................................................................5 MODELORELACIONAL........................................................................................................5 Aspectosadicionalesacercadelasclaves.......................................................................6 Relaciones...........................................................................................................................6 Relacionesentretablas...................................................................................................7 ReglasdeintegridadyRestricciones...................................................................................7 Claveprimaria(PK)..........................................................................................................7 Valoresnicos.................................................................................................................7 Clavesforneas(FK)........................................................................................................7 CAMPOSNULOS..............................................................................................................8 Normalizacin.....................................................................................................................8 FormasNormales............................................................................................................8 Primeraformanormal1FN .............................................................................................9 . Segundaformanormal2FN ..........................................................................................10 . Tercerformanormal3FN..............................................................................................10 EjemplodeNormalizacin. ...........................................................................................12 . CAPITULO2...........................................................................................................................15 LENGUAJEDECONSULTAESTRUCTURADOSQL...................................................................15 DefinicindeunabasededatosatravsdeSQL.............................................................16 TiposdedatosenSQL...................................................................................................16 Crearunatabla..............................................................................................................17 ModificarUnaTabla......................................................................................................19 IntegridadReferencial...................................................................................................21 Aadirelementosaunatabla.......................................................................................21 ConsultasSQL....................................................................................................................23 ConsultasSimples..........................................................................................................23 Operadoreslgicos........................................................................................................26 FuncionesenSQL..........................................................................................................30 AgruparyOrdenarDatos...............................................................................................35 MANIPULACIONDEDATOS...............................................................................................39 Actualizacinderegistros..............................................................................................39 BorrarRegistrosdeunaTabla.......................................................................................40 ConsultasComplejas.........................................................................................................41 UNIONESOJOINS..........................................................................................................41 Consultasanidadas...........................................................................................................50 Actualizacinyborradodefilasatravsdeconsultasanidadas..................................53 CAPITULO3...........................................................................................................................56 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA.................................................56 Introduccin......................................................................................................................56 ConceptosPreliminares....................................................................................................57 Driver.............................................................................................................................57 DNS................................................................................................................................57 ConfiguracindeunDriverODBC.................................................................................58 JDBC...................................................................................................................................61

Introduccin..................................................................................................................61 ConexinalaBasededatos..........................................................................................61 Consultandolabasededatos.......................................................................................63 PreparedStatement.......................................................................................................69 ActualizandoLaBaseDeDatos.........................................................................................72 JTable.............................................................................................................................76 TipoDeDatoBLOB............................................................................................................83 LeyendounBLOBmediantelaaplicacinJAVA............................................................83 EscribiendounBLOBalaBDmediantelaaplicacinJAVA..........................................85 RESULTSET.........................................................................................................................88 PropiedadesdelResultSet.............................................................................................88 FECHASENJAVA ...............................................................................................................95 . Calendar.........................................................................................................................95 OtrasClasesparaelmanejodeFecha...........................................................................98 ConversinDeFechas...................................................................................................99

2008II 2

ACCESOADATOSCONJAVA:NOTA ASDECLASE

Ca aptuloI IN NTRODUCC CION A LAS BAS SES DE D DA SRELA ONALE ATOS ACIO ES

Elobjetivof E finaldelas basesde datosesalmacenarlainformaci n,exactam mente igualquelosar rchivos;per roextiendenelsentido odeestos porqueno soloalmac cenan los d datos, sino que tambin como e estn estruc cturados, o organizando la informacin o segnunciertomodelo. Este modelo de datos, define las estructuras bsicas d informac E o , de cin y relaciones que entre ellas existen. El modelo queda totalm l mente claro al crear la base de datos o a abstr rayendo la caracter as rsticas de cada ent tidad de d datos y la relacion as nes y depe endenciasquehayentr relosdatos sdelamism ma. El E citado es squema se almacena con la pro opia base de datos, de manera que a cualq quier progr rama que la utilice e encontrara en su est tructura fsica, entre otras infor rmaciones, los nombr de cada uno de los elementos de dat y el tip de res a tos po infor rmacinque econtienen n.

OBJ JETOSBA ASICOS.Lasbasesde L edatos,ind dependiente ementede culessean nlosmecan nismosutiliz zados para almacenar ryobtener lainformac cin,estar ncompues stasfundam mentalmentepor tabla as. Tabla a Una U tabla e una cole es eccin de e elementos de informacin agrupados por filas y d f colum mnas.Latablaalmacenalainform macinsobr reunaentid daddiferen nciada,comopor ejem mplo,unempleado,unlibro,etc.

Las bases de datos acaba con L nstituyndo ose como una colec ccin de tablas t relac cionadasentresi. 4 INTRO ODUCCIONALASBASESD DEDATOSRE ELACIONALES S

CAMIL LOANDRSF FERRERBUST TOS

EAM E

Fila Cadafila,or C registro,rep presentaun nejemplard delobjetoq queabstrae elatabla.De euna tabla aquerepre esentelosd datosdeun nosemplead dos,unafila,espues, unregistro oque repre esentaune empleadodetodoslosalmacenad dosendicha atabla.Una atablaresul ltade unac coleccindefilasoreg gistros. Columna. Lascolumna L asdelatabl laseconoce encomocampos.Losc camposdes scribencada auno de lo atributos o caracte os s ersticas de los objetos que repre esentan los registros de la s tabla a.Cadacolu umnaalmac cenainform macindelm mismotipo.

Clave e.

Es E aconsejable, aunque no impre e escindible, que cada re q egistro pos una ser de sea rie atrib butos que lo identifiquen de ma anera inequ uvoca en el conjunto de datos Por o s. ejem mplo, en u una tabla de emplea ados el campo cedula permit tir sealar sin ambigedad cada registro de la tabla ya que no hay dos empleado con la misma o n s os m cedu ula.Aestecamposelellamaclave eollaveprin ncipal.

MO ODELOR RELACIO ONAL.En E el modelo relaciona los vncu al, ulos entre las entidad de dato se establecen des os mediante la ab bstraccin d relacione entre las distintas tablas. Estas relaciones se de es obtie enendeunanlisisdelanaturalez zaintrnsecadelosdat tos. Una U relacin consiste en la ligaz que pue establec n n ede cerse entre dos tablas que e s pose een algunos campos con valore idnticos. Existen ciertas reg s es glas que deben d respe etarsealah horadecrearlasbases sdedatosrelacionales. L Lasfilasson nindependi ientes:ning gunafiladeunatablap puededepe enderdeotr rafila delamisma d atabla. L Lasfilasdeb benserni icas:dosfila asdeunam mismatabla adebendiferirenalm menos uncampoocolumnadelamisma. u . L Lascolumna assoninde ependientes s:lascolum mnasnoposeenningn nordenyelvalor deunacolum d mnanopue ededepend derdeotrac columna. L valores de las colu Los umnas son unitarios: dentrode unadeterm minadafila, cada columnacon c ntendrunnicovalor r,nuncauna afilaolistadeellos. MODEL LORELACION NAL./Fila 5

2008II 2

ACCESOADATOSCONJAVA:NOTA ASDECLASE

Aspe ectosadic cionalesac cercadela asclaves.Haytrestipo H osdeclaves sdistintas: Claves P Primarias: c comoyase dijoantes, ,unaclave ollaveprim mariaesaq quella que tien valores d ne diferentes e todas la filas de l tabla a f de ident en as la fin tificar inequvo ocamenteunregistrod delamisma a.Unaclave eprimarian nopuedequ uedar vaca. Claves c candidatas: en alguna ocasione la tablas poseen ot as es tras column o nas campos quesonn nicosentod dalatabla. .Aestasco olumnasse lesllamac claves candidat tas. Ajenasofor rneas:una aclaveajen naesunaco olumna,campoogrup pode ClavesA columna asdeunata ablaqueco ontienevalo oresquecasanconunaclaveprin ncipal en otra tabla. Estas claves aje enas son la que perm as miten estab blecer relac ciones entreotrastablas.

Relaciones s Unarelacin U nestcomp puestapor atributose endistintas tablasconidnticova alory signif ficadoqueseusanpar raestablece erunparen ntescoentre edichastab blas.Parailu ustrar loan nteriorvaseelsiguienteejemplo.

La L tabla VENTAS posee la colum NCLI en la cual hay unos n mna n meros, si estos nmerossecom mparanconlosnmero osdeNCLIe enlatablaCLIENTESse epuedeconcluir que son los mismos y ade ems tienen el mismo significado, ya que N o NCLI en clientes indic caelcdigodelclienteyNCLIenv ventasindic caelcdigodelclientealquesele ehizo la ve enta. Se ve clarament que hay una relaci directa entre las t te n tablas VENT y TAS CLIEN NTES. 6 INTRO ODUCCIONALASBASESD DEDATOSRE ELACIONALES S

CAMILOANDRSFERRERBUSTOS

EAM

Relacionesentretablas.Sepuedendefinirtrestiposderelacionesentretablasdeunabasededatos: Unoauno(1:1):unoyunsoloregistrodelatabladependientesehallaligadoa unregistrodelatablaprimaria.Sonrelativamenteinfrecuentes. Uno a Muchos (1: n): permiten que varios registros en tablas dependientes estn ligados a un registro en una tabla primaria. Son las relaciones ms comunes. Muchosauno(n:1):variosregistrosdelatablaprimariaestaligadosaunsolo registrodelatabladependiente. Muchos a muchos (n:n): varios registros de la tabla primaria esta ligados a variosregistrodelatabladependiente. Ladefinicincorrectadelasrelacionesentrelasentidadesqueseexpresanenlas tablaseslabasedeundiseoeficientedeunabasededatosrelacional.

ReglasdeintegridadyRestriccionesLasreglasdeintegridadsonusadasparagarantizarlaprecisinylaconsistenciade losdatosenunmodelorelacional.

Claveprimaria(PK)Laclaveprimariaestambinllamadallaveprincipalycomosedijoanteriormente esaquellacolumnaquegarantizaqueunafiladelatablaseanica.Comoloserael cdigodeunestudianteenunatabladeestudiantes,laceduladelclienteenunatabla declientes,etc.CabeaclararqueunaClaveprincipalpuedeestarconstituidadeunao mscolumnassiestogarantizalaunicidaddelosregistrosdelatabla,aunqueeluso de claves de este tipo dificulta el realizar consultas y establecer relaciones entre las tablas.

Valoresnicos.Un valor nico en una tabla es muy similar a una clave primaria, la diferencia es quelaclaveprimariaseusapararelacionarlastablasyrealizarlasconsultas,elvalor nicoesunarestriccinenuncampoquenosepuederepetirenotrafiladelatabla. UnejemplodeestoseraqueenunatablaESTUDIANTEsetuvieracomoclaveprimaria elcdigodelalumnoycomovalornicolacedula,yaqueambosnoserepitenenotra filaperosuusosipuedeserdiferenteenelmodelorelacional.

Clavesforneas(FK)Una clave fornea es un campo en una tabla que permite relacionarla con otra tabla. La clave fornea es usada para referenciar una columna definida como clave principalenotratabla.EnlafiguraanteriorenlatablaVENTA,sevequeestaposee unacolumnaNCLIquehacereferenciaalnmerodelclienteenlatablaCLIENTE.NCLIE enlatablaCLIENTEeslaclaveprincipalyenlatablaVENTAeslaclaveollavefornea./Relacionesentretablas. 7

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

CAMPOSNULOSSoncolumnasdeunafilaqueporsuimportanciaalmomentodecrearelregistroo lafilanopuedendejarsevacios.

NormalizacinLa normalizacin es el proceso mediante el cual toda la informacin referente a una basededatossedivideunidadeslgicasllamadastablas.Esteeselprocesoqueusan losdiseadoresdelasbasesdedatosparaquelainformacinqueestasalmacenansea de fcil organizacin y mantenimiento, y as, asegurar la integridad y precisin de la informacinenlabasededatos El proceso de normalizacin reduce la redundancia de la informacin y se usa en el diseoyrediseodelabasededatos.Lanormalizacinesunaseriedepasos,aestos pasosselesdenominaformasnormales

FormasNormales.Antesderealizarelprocesodenormalizacindelabasededatossedebeteneruna relacindetalladadetodalainformacinqueenellasevaaalmacenar,aestosele denominaeldiccionariodedatos.Supngasequesequieredisearunabasededatos referenteaunafactura:

Yeldiccionariodedatosdeestafacturaeselsiguiente:

8 INTRODUCCIONALASBASESDEDATOSRELACIONALES

CAMILOANDRSFERRERBUSTOS

EAM

Primeraformanormal1FNElobjetivodelaprimeroformanormalessepararenunanuevatablaloselementos repetitivosdeldiccionariodedatos tabla1 Cod_Fac Fec_Fac Dir_Cli Ced_cli Ciu_Cli Tel_Cli tabla2 Cat_Pro Cod_Pro Des_Pro Val_pro Can_Pro

Delafacturasepuedeverqueloscamposdelatabla2serepitenvariasveces Segnlasrestriccionesdelmodelorelacionalcadatabladebetenerunallaveprincipal queseanicaenlatotalidaddedichatabla,siseobservalatabla2,elcod_prodpodra satisfacerestacondicin,perosienunafacturadiferenteseregistralacompradeotro monitor (68989) no habra unicidad en este valor por lo que una solucin a este impase seria indicar a que factura pertenece el producto relacionado, asi, la tabla 2 tendriacomollaveprincipala(cod_proycod_fac)yquedaradelasiguienteforma.Tabla1 Cod_Fac Fec_Fac Dir_Cli Ced_cli Ciu_Cli Tel_Cli Tabla2 Cod_Fac Cat_Pro Cod_Pro Des_Pro Val_pro Can_Pro

Normalizacin/

9

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

Segundaformanormal2FNElobjetivodelasegundaformanormalessepararenunanuevatablaloscamposde lastablasdela1FNquenodependanenteramentedesullaveprincipal.Cuandohay tablasconllavescombinadassoloseobservandichastablas.Sianalizalatabla2: Tabla2 Cod_Fac Cat_Pro Cod_Pro Des_Pro Val_pro Can_Pro Los campos de val_pro, cat_pro, des_pro no depende de la llave principal (cod_fac,cod_pro),solodependendelcod_proyaquesonlosdatosdelproductoensi yesonodependedequeestnonoenlafactura.Estosdatosseseparanenunatabla aparte:tabla3. tabla1 tabla2 tabla3 Cod_Fac Cod_Fac Cod_Pro Fec_Fac Cod_Pro Des_Pro Dir_Cli Can_Pro Val_pro Ced_cli Cat_Pro Ciu_Cli Tel_Cli

Tercerformanormal3FNElobjetivodela3FNesremoverdelastablasresultantesdela2FNlosatributosque nodependandelasllavesprincipalesdedichastablas. Siseobservalatabla1losdatosreferentesalcliente(dir_cli,ciu_cli,tel_cli) nodependendecod_fac,estospodraniraunanuevatabla:tabla4. tabla1 tabla2 tabla3 tabla4 Cod_Fac Cod_Fac Cod_Pro Dir_Cli Fec_Fac Can_Pro Des_Pro Ced_cli Cod_Pro Val_pro Ciu_Cli Tel_Cli 10 INTRODUCCIONALASBASESDEDATOSRELACIONALES

CAMIL LOANDRSF FERRERBUST TOS

EAM E

Perosilatabla1 1debealmacenarlain nformacin delafactu ura,debere elacionarde equ clienteesdichafactura,esporesoquelatabla1quedaas: _Fac Tabla_Item_ T _fac Tabla_prod T Tabla a_Cli Tabla_ Cod_F Fac Cod_Fac C Cod_Pro C Dir_C Cli Fec_Fa ac Can_Pro C Des_Pro D Ced_ _cli Ced_cli Cod_Pro C Val_pro V Ciu_C Cli Tel_C Cli Dond deentabla_ _fac,ced_cliseriaunallaveforne ea. Sino osenormalizaralatab bla1setend dranqueingresarlos sdatosdel clientecadavez ques secreeunanuevafact turaloquea aaderedundanciaala abasededatos. En e esta altura del proceso se pued observa que en cada grup se encuentra de ar po infor rmacin de manera organizada. Un cliente con sus datos, un pr roducto con sus datos,unaorde enconsus datosmnim mos,porej jemplosise eoobserva Tabla_Item m_fac enla a3FNcone elcd_prop podramosaveriguarq queproduct tosecompr ro,cuantov valey dems, con cod d_fac, podr ramos aver riguar cuan y la ced ndo dula de quien lo compro y esta asuvezno osdiraelte elfono,la direcciny demsdat tosdelclien nte.Seven unas clara asyeficientesrelacione esentrelastablas. Esta figura nos muest las rela E tra aciones entre las tab blas luego del proces de so norm malizacin.

Normaliz zacin/Terce erformanormal3FN

11

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

EjemplodeNormalizacin. AContinuacinunnuevoejerciciodenormalizacin. Unaempresaesconformadadelossiguientesdatos:

Diccionariodedatos.emp_id Nom_emp Tel_emp Dir_emp correo_emp ciudad_emp apellido_emp nom_puesto frec_pago bonificacion_puesto fecha_ingreso salario cedula_cliente nombre_cliente telefono_cliente direccion_cliente ciudad_cliente prod_id descripcion_prod costo_prod cdigodelempleado nombredelempleado telfonodelempleado direccindeempleado correodelempleado ciudaddelempleado apellidodelempleado puestodelempleado frecuenciadepago(quincenal,semanal,mensual) bonificacinqueganaelempleadodeunpuesto fechaenelqueelempleadoingresoalaempresa salariopagadoauntipodepuesto ceduladelcliente nombredelcliente telfonodelcliente direccindelcliente ciudaddonderesideelcliente cdigodelproducto descripcindelproducto costodelproducto

12 INTRODUCCIONALASBASESDEDATOSRELACIONALES

CAMILOANDRSFERRERBUSTOS

EAM

Primeraformanorma Como se dijo anteriormente, la primera forma normal es separar los elementos repetitivos del diccionario de datos, en este diccionario de datos no hay elementos repetitivosentoncesseprocedeaagruparlosdatossegnsurelacin. Sepuedenobservar3grupos. Empleado Producto emp_id prod_id Nom_emp descripcion_prod Tel_emp costo_prod Dir_emp correo_emp ciudad_emp apellido_emp Cliente fecha_ingreso cedula_cliente frec_pago nombre_cliente puesto telefono_cliente bonificacion_puesto direccion_cliente salario ciudad_cliente Segundaformanormal La segunda forma normal lo que es sacar aparte de las tablas de la 1FN aquellos campos que no dependan enteramente de la llave principal de estas, por ejemplo, viendo la tabla empleado se observa que los campos puesto, bonificacin_puesto, salrio, frec_pago,fecha_ingreso no dependen de emp_id sino que son datos que describenlasituacinlaboraldelempleado,estosepuedeagruparenunatabla. empleado_info_laboral emp_id fecha_ingreso frec_pago nom_puesto bonificacion_puesto salario Ycomoestaesinformacindeunempleadohayquerelacionarlamedianteemp_id.

Normalizacin/EjemplodeNormalizacin.

13

2008II 2

ACCESOADATOSCONJAVA:NOTA ASDECLASE

Terce eraFormaN Normal Elob bjetivodela aterceraformanormalesremove erdelastab blasdela2F FNlosdatosque noso ondependie entesdelaclaveprincipal. Si s observa la tabla puesto_ se a a _info los campos nom_pue esto, sa alario, bonificacin_pu uestosonlo osdatosref ferentesae elpuestode etrabajoy nodepende ende quien nlotengay yaquevariosemplead dospueden ntenerelm mismopuest to,loqueindica quee estainform macinessusceptibleaconvertirse eenotratabla. puesto p emple eado_info_ _laboral puesto_id p emp_ _id nom_puesto n fecha_ingreso bonificacion b n_puesto frec_p pago salario s puest to_id La ta abla puesto almacena la informac o cin de los puestos de la empres y se le aade e sa a una llave principal par cumplir los requ ra r uerimientos del mo s odelo, la tabla empleado_info_ _laboral Sere elacionacon npuestome ediantepue esto_id. Desp pus del pro oceso de normalizaci el diagra n ama de entidad relaci del prob n blema resue eltoquedadelasiguie entemanera a:

Se S podran unir dos ejercicios ant teriores par formar la base de d ra datos final de la empresa.

14 INTRO ODUCCIONALASBASESD DEDATOSRE ELACIONALES S

CAMILOANDRSFERRERBUSTOS

EAM

CAPITULO2 LENGUAJE DE CONSULTA ESTRUCTURADOSQL SQL(StructuredqueryLenguage)esunlenguajequenospermiteejecutarmultitudde operacionessobrelasbasesdedatosrelacionales;trabajandodirectamentesobrelas tablas,filasycolumnas.EllenguajeSQLposeeunaestructuramuysimplequepermite accederasubconjuntoscomplejosdedatosmediantesentenciaspequeas. El lenguaje de consulta estructurado (SQL) es un conjunto especializado de rdenes quepermitenalusuariorealizarlossiguientestiposdetareas: Recuperardatosdeunaomstablasdeunaomsbasesdedatos. Manipular los datos de las tablas insertando, eliminando, o actualizando registros. Obtenerinformacinresumidasobredatosdelastablas,comototales;cuentas deregistros;yvaloresmximo,mnimoymedio. Crear,modificartablasenunabasededatos. Crearoeliminarndicesenunatabla. Laconsultadefineloscamposaprocesar,lastablasqueloscontienen,elintervalode registrosaincluir,y,paralarecuperacinderegistros,elordenenquesetendrnque presentar. Lasinstruccionesdellenguajesedividenen: DDL(DataDefinitionLanguage):Eslapartedellenguajequeseocupadelagestinde labasededatos:creacinyborradodelosusuarios,tablas,vistas,etc...;gestindel controldeacceso;manipulacindelaestructuradelastablas;optimizacindelacceso alosdatos;tiposdedatos... DML(DataManipulationLanguage):EslapartedellenguajeSQLqueseocupadelas operacionesdeinsercin,borrado,actualizacinyconsultadedatos. DQL (Data Query Language): es la parte del lenguaje que se ocupa de extraer la informacindelabasededatos. Normalizacin/EjemplodeNormalizacin. 15

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

DefinicindeunabasededatosatravsdeSQL YacreadalabasededatosenelSistemaGestordeBasedeDatosRelacional(SGDBR) sedebenusarlassentenciasSQLdetipoDDLparacrearlastablasylasrelacionesque puedanexistirentreellas. Antes de poder definir una tabla y todos sus campos, es necesario conocer los distintostiposdedatosqueexistenenelestndarSQL.

TiposdedatosenSQL EnSQLcomoencasicualquierlenguajeexistentrestiposdedatosbsicosqueson: Cadenasoalfanumricos Nmeros FechasyHoras

Alfanumricos Entrelostiposdedatosalfanumricosseencuentranlosdelongitudfijayvariable. LascadenasdelongitudfijasedefinenmedianteCHAR(n)dondeneseltamaoqueel datodefinidovaatomar.Hayquetenerencuentaquesiundatoenespecialocupa menoscaracteresdeloespecificadoconn,elespaciorestantesellenaconespacioslo cualpuedeserpeligrosoenelmomentoderealizarcomparacionesobsquedassobre estosdatos. LascadenasdelongitudvariablesedefinenmedianteVARCHAR(n),dondenindica el tamao mximo de la cadena a almacenar. La diferencia con CHAR es que no se rellena con espacios el espacio sobrante lo que da ms exactitud a la informacin almacenada.Sisedeseaalmacenarunacadenamsgrandedeltamaodefinido,esta setruncaaltamaoespecificadodeldato.

NumricosEntrelostiposdedatosnumricosqueseencuentranenelEstndarestn: NUMERIC:numeroengeneral INTEGER:Entero BIGINT:Enterogrande DECIMAL:numeroconpuntodecimal.

FechasyhorasLostiposdedatosparaalmacenarfechasyhorasenSQLson: DATETIME:fechayhora.Almacenaelao,mes,da,hora,minutoysegundo. DATE:soloalmacenaelao,mesyelda.16 LENGUAJEDECONSULTAESTRUCTURADOSQL

CAMILOANDRSFERRERBUSTOS

EAM

CrearunatablaPara crear una tabla con SQL se utiliza la instruccin CREATE TABLE cuya sintaxis se muestraacontinuacin: CREATETABLEtable_name (field1 data_type [null|notnull], field2 data_type [null|notnull], field3 data_type [null|notnull], field4 data_type [null|notnull], field5 data_type [null|notnull]); Dondefieldxeselnombredelacolumna,data_typeesalgunodelostiposdedatos explicados con anterioridad null o not null define si se puede o no dejar vacio el campoalmomentodelacreacindelregistrodelatabla. Aunquelasintaxisparacrearlatablaesmuysencilla,sedebededicaralgntiempoen planear cual ser el nombre de la tabla, cul es la o las columnas que conforman la llaveprincipalylasdemsrestriccionesquelosotroscamposdelapuedantener.Esta informacinporlogeneraldebesalirdelprocesodenormalizacindelaBD. ParaindicarqueuncampoeslallaveprincipaldelatablaseutilizalaclausulaPRIMARY KEY. Porejemplo,sisequisieracrearlatablaempleadodelabasededatosanteriormente modelada,lasentenciaSQLqueharaestoseria: createtableempleado( nombre_emp varchar(30)notnull, apellido_emp varchar(30)notnull, telefono_emp varchar(10)null, direccion_emp varchar(30)null, correo_emp varchar(30)null, cedula_emp varchar(15)notnullprimarykey );

Esta sera una tabla que tendra como llave principal a cedula_emp, telfono_emp, direccin_emp, correo_emp se podran dejar vacios cuando se aada el nuevo empleado, los campos nombre_emp y apellido_emp se tienen que llenar obligatoriamente.Lallaveprincipaldebetenerlarestriccindenotnullcomoserade esperarseyaquealsereldatoprincipal,nosepuededejarvacio.

DefinicindeunabasededatosatravsdeSQL/Crearunatabla

17

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

Otramaneradeindicarlallaveprincipaldeltablaesusandoprimarykeyconunalista delascolumnasqueformanlallaveprincipalentreparntesis. Primarykey(campo1,campo2,campon)createtableempleado( cedula_emp varchar(15)notnull, nombre_emp varchar(30)notnull, apellido_emp varchar(30)notnull, telefono_emp varchar(10)null, direccion_emp varchar(30)null, correo_emp varchar(30)null, primarykey(cedula_emp) );

Enestecasosolounacolumnaformalallaveprincipal. SisedeseaqueuncampoenespecialseanicoseusalaclausulaUNIQUE. createtableempleado( cedula_emp varchar(15)notnull, nombre_emp varchar(30)notnull, apellido_emp varchar(30)notnull, telefono_emp varchar(10)nullUNIQUE, direccion_emp varchar(30)null, correo_emp varchar(30)null, primarykey(cedula_emp) );

Aqusehizoeltelfonodelempleadonico,esdecir,nopuedehaberdosempleados condostelfonosiguales.

ClavesforneasyrelacionesPara aadir una clave fornea a una tabla y as crear una relacin se usa la clausula foreignkey.Comoseexplicoconanterioridad,unallaveforneahacereferenciaauna columnaqueconformalallaveprimariadeotratabla(madre),esporesoquelallave forneaenlatablahijadebeserdelmismotamaoytipodedatodelacolumnaque referencia.

18 LENGUAJEDECONSULTAESTRUCTURADOSQL

CAMILOANDRSFERRERBUSTOS

EAM

Porejemplo,unatablatabla_facqueserelacionaconempleadomediantelaclave forneacedula_emp,aqulatablahijaosecundariaestabla_facylamadreoprincipal esempleado. Tabla_Fac Cod_Fac(PK) Fec_Fac Ced_cli(FK) cedula_emp(FK) Lasintaxisdeforeignkeyeslasiguiente: Foreign key (campo_tabla_hija) (campo_tabla_principal)

references

nombre_tabla_principal

createtabletab_fac ( cod_facserialprimarykey, fec_facdatenotnull, cedula_empvarchar(15), constraintfk_cedula_empforeignkey(cedula_emp)references empleado(cedula_emp) );

Donde fk_cedula_emp es el nombre del constraint que define la llave fornea, cedula_empenlatablatab_fachacereferenciaacedula_empenlatablaempleado. Fijesequecedula_empenempleado ytab_facsedefinierondelamismamanera.Si estonofueraasi,larelacinnosepodrahacer. Una llave fornea as como muchas ms restricciones se definen a travs de un constraintorestriccin.Larestriccinposeeunnombredefinidoporelusuario.

ModificarUnaTabla Hay ocasiones en que ya definida y creada la tabla se necesita modificar su estructura aadiendo, modificando o eliminado columnas o restricciones a las columnas,enesoscasosseusalasentenciaALTERcuyasintaxiseslasiguiente: ALTERTABLETABLE_NAME [MODIFY|ADD|DROP] [COLUMNCOLUMN_NAME][DATATYPE|NULLNOTNULL][RESTRICT|CASCADE] [ADD|DROP]CONSTRAINTCONSTRAINT_NAME] DefinicindeunabasededatosatravsdeSQL/ModificarUnaTabla 19

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

DondeTABLE_NAMEeselnombredelatabla [MODIFY|ADD|DROP]indicaloquesevaahacer.Modificar,aadiroborraralgo. (Soloseescogeunodelostresynoseponenloscorchetes). COLUMN_NAMEeselnombredelacolumnaquesevamodificar,aadiroborrar. Elrestodelasintaxisdefineloquesevahacerconlacolumna. Si se quisiera aadir a la tabla tab_fac una columna ced_cli para relacionarla con cedula_clientedelatabladeclienteseriadelasiguienteforma: altertabletab_facaddcolumnced_clivarchar(20)not null; Luego, para crear la relacin se aade a la tabla tab_fac una llave fornea con la ced_clicreadaanteriormente: Seutilizaaddysedefinelallaveforneacomoseexplicoconanterioridad.altertabletab_facaddconstraintfk_ced_cliforeignkey(ced_cli)references cliente(cedula cliente);

Paraborrarlarelacinseeliminaelconstraintatravsdelcualsecrelarelacin:altertabletab_facdropconstraintfk_ced_cli;

Paraeliminarunacolumnadeunatabla:altertableclientedropcolumnnombre_cliente;

Nosepuedeneliminarcolumnasquehayansidodefinidascomollaveforneayaque primalarelacinquetieneestacolumnaconlaotratabla.

20 LENGUAJEDECONSULTAESTRUCTURADOSQL

CAMILOANDRSFERRERBUSTOS

EAM

IntegridadReferencial.

Laintegridadreferencialindicaquelasfilasdeunatablarelacionadaconotradeben existir,sino,latablasecundariaestarahaciendoreferenciaaunregistroinexistente. Enlafiguraanteriorseobservaquelafacturaconcdigo3tienetresregistrosenla tabladetem_fac.Qupasaraconesosregistrossiseborraradelatablafacturala factura con cdigo 3? Deberan borrarse tambin ya que estn apuntado a un registro ya inexistente. Si un cdigo en la tabla factura cambiara a otro valor, los registrosdelatablatem_facqueestnrelacionadosconelregistromodificadodeben cambiar para que la relacin persista, si esto no fuera as los registros de la tabla secundariaapuntaranaunregistroinexistente. En SQL esto se hace con ON DELETE CASCADE para borrar en cascada y ON UPDATE CASCADEparaactualizarencascada. altertabletab_facaddconstraintfk_ced_cliforeignkey(ced_cli) referencescliente(cedula_cliente)ONDELETECASCADEUPDATE

Aadirelementosaunatabla Yacreadalatabla,esnecesariollenarlaconinformacin,paralocualseusalaclausula INSERT.Lasintaxiseslasiguiente: INSERTINTOTABLE_NAME[(COLUMN1,COLUMN2,...] VALUES(VALUE1,VALUE2,...)

DefinicindeunabasededatosatravsdeSQL/IntegridadReferencial.

21

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

Donde TABLE_NAME es el nombre de la tabla donde se van a aadir los datos, [ (COLUMN1,COLUMN2,...]sonlascolumnasalascualesselesvaaasignarunvalory VALUES(VALUE1,VALUE2,...)definelalistadelosvaloresaalmacenarsegnelorden definidoenlalistaanterior. ParaaadirunNuevoempleadoalatablaempleadosseria: insertintoempleado (nombre_emp,apellido_emp,cedula_emp,telefono_emp,direccion_emp) values('camiloandres','ferrerbustos','9737630','7488118','manantiales') Hayqueconsiderarlosiguiente: 1. Sienladefinicindelatablasedefinieldatocomonotnull,enlacreacinde lanuevafiladebenestarcomomnimolascolumnasdefinidascomonotnull,Si seomiten,secancelalacreacindelatabla. 2. Sisedefineunacolumnacomollaveprincipal,nosepuedencreardosfilascon el mismo valor en ese campo ya que genera una excepcin y se cancela la creacin de la tabla. Esta condicin tambin la cumplen los valores definidos comounique.

22 LENGUAJEDECONSULTAESTRUCTURADOSQL

CAMIL LOANDRSF FERRERBUST TOS

EAM E

Con nsultasS SQLUnaconsult U taesunape eticinala basededa atosatrav sdeunase entenciaSELECT. Una consulta es usada para extraer informacin de la bas de datos en un for s n se s rmato bleacordea alaspeticionesdelusu uario.Sepodranhacer rconsultassobrelabasede legib datosparadete erminarde unatablad deemplead dosquienes sgananm sde$1000 0.000 depesosobusc carlasvent tasrealizadasporunv vendedorenunafecha adeterminaday etc.

Con nsultasSi implesLa L sentencia SELECT es el comand que rep a s do presenta el DQL en SQ y es la y es la QL sente encia bsica para cons a struir los querys sobre la base de datos. SE e ELECT no trabaja sola,encompa adeotrasclausulas paracomp pletarlafun ncionalidad delasente encia. Hayc cuatroclaus sulasquese eusanjunto oconSELEC CTparadefi inirlaconsu ulta:

SELECT T FROM WHER RE ORDER RBY

N1,COLU UMN2] SELECT[*|ALL|DISTINCTCOLUMN FRO OMTABL LE1[,TABLE2]; COLU UMN1,COL LUMN2esla alistadeco olumnasquesequiere enmostrare enlaconsulta,si sequ uieremostr rartodaslas scolumnasdelatabla,seusaelasterisco(*); LE1[,TABLE2]eslalis stadelastablasquese eusaranenlaconsulta. TABL FROM Mindicaqu uelaconsult taserealiza adelastablasquesigu uendespus sdelaclaus sula Pore ejemplo:

sele ect*from mempleado;

Porm mediode(* *)muestrat todaslasco olumnasdelatablaempleado.

ConsultasSQ C QL/ConsultasSimples 23

2008II 2

ACCESOADATOSCONJAVA:NOTA ASDECLASE

sele ectnomb bre_emp p,cedula_ _empfromemple eado;

Solomuestralas scolumnasnombre_empycedula a_empdela atablaemp pleado.

DIST TINCTla cla ausula disti inct muestr los valor de una columna d una tabl omitiend los ra res de la do elem mentosrepe etitivos. ctDISTINCT Tcat_prodf fromproducto; selec

Se m muestran las categoras existentes en la tab producto omitinedo los eleme s bla o entos repetidos.

Clau usulaWHE ERECuan ndo la consulta est determinada por alg guna condicin se ut tiliza la clausula WHE ERE. select[all| s *|distinct tcolumn1,c column2] fromtable1[,table2] where[condition1|ex w xpression1] [and|ORco ondition2|expression2 2] pusdelaclausulawhe erevaunaexpresinl gicaqued determinae elresultadodela Desp consulta. Esteeselcontenidodeuna atabladep productos: Selec ct*frompr roductos

24 LENGU UAJEDECON NSULTAESTR RUCTURADOSQL

CAMIL LOANDRSF FERRERBUST TOS

EAM E

Dee estatablaso olosedesea amostrarlo osproducto oscuyacate egoraseap procesador: : selec ct*frompr roductowherecat_pro od=procesa ador

mostrarde latablaem mpleadola informacin ndelemple eadoconce edula Solo sequierem 1094 410923: Selec ct*fromem mpleadowh herecedula a_emp=109 9410923 Sequ uieremostr rarlosproductocuyop precioseain nferiora$100000 Selec ctnombre_ _prod,codig go_prod,pr recio_prod from mproductow whereprec cio_prod500 000andpre ecio_prod2 ); al actualizar con precio_producto =1.1*precio_producto se esta incrementando el preciodelosproductosen10%yaquealprecioactualselemultiplicapor1.1o110%. ParaborrarfilasseusalasentenciaDELETE(pg.40).Tambinlacondicindeborrado queseusajuntoconelWHEREpuedecontenerunasubconsultatalycomosemostro conUPDATE. Sedeseaborrartodoslosempleadosquenohayannuncavendidoalgo. Estossonlosempleadosdelaempresa:

Estossonlosquenuncahanvendidoalgunavez: selectdistinctcodigo_empleadofromfactura,item_factura whereitem_factura.codigo_fact=factura.codigo_factura;

Sisecomparalasdostablasseobservaqueelunicoquenoestaaquies1094234424. Esehayqueborrarlo.Enpocaspalabras,hayqueborrartodoslosquenoestnenla lista generada por la consulta anterior para saber si los valores de una columna no estanenunconjuntodedatosseusaNOTIN. DELETEfromproduct wherecodigo_productoNOTIN( selectdistinctcodigo_empleado fromfactura,item_facturawhere item_factura.codigo_fact= factura.codigo_factura );

54 LENGUAJEDECONSULTAESTRUCTURADOSQL

CAMILOANDRSFERRERBUSTOS

EAM

yelresultadoeselsiguiente:

Seobservaqueelempleadoencuestinyanoest.

Consultasanidadas/Actualizacinyborradodefilasatravsdeconsultas anidadas

55

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

CAPITULO3 ACCESO A UNA BD POR MEDIO DEUNAAPLICACINJAVA

IntroduccinUnabasededatosesadministradaprincipalmenteporunSistemagestordeBasede datosoSGBDporsussiglaseningles.Dichaadministracinsehacealniveldedefinir las tablas y las relaciones existentes entre las mismas, los aspectos de seguridad y otrosquesondefinidosporelDataBaseAdministratoroDBA.Todaslastareashechas atravsdelSGBDsehacenpormediodellenguajeSQLcomoenMySQLoconayudas masvisualescomoenACCESSdeMicrosoft. AunqueelSGBDentregaherramientaspoderosasparalaadministracindelosdatosy la estructura de los mismos, estas tareas requieren de conocimientos muy tcnicos queelcomndelosusuariosquerequierenmanipularyconsultarlainformacinno tiene,ademsdelhechoquelainterfazdeusuariodelgestorestdiseadamaspara administrar la BD y no para interactuar la informacin. Por estas y otras razones se crean aplicaciones de uso especfico para poder interactuar con la base de datos de maneramsfcilytransparenteparaelusuariofinalqueenltimaseselpropsitoo motivacinmayorparacrearunabasededatos. El acceso a la base de datos se puede hacer de muchas maneras ya sea por una aplicacinWEBounadeescritoriolacualpuedeserescritaencualquierlenguaje.La potenciadelabasededatosradicaenelhechoquepuedeseraccedidadecualquier manera posible ya quela misma es independiente de la aplicacin que la accede. Es responsabilidad de cada aplicacin obtener los recursos necesarios para poder conectarseconlabasededatos. Enestecaptuloseexplicaranlospasosyrecursosnecesariosparapoderaccederauna base de datos mediante una aplicacin JAVA y como lo aprendido en los captulos anterioresesdegranutilidadparaesefin.

56 CAPITULO3

CAMILOANDRSFERRERBUSTOS

EAM

ConceptosPreliminares. Para poder conectarse a una base de datos a travs de una aplicacin JAVA es necesarioentenderalgunosconceptosclaves.

DriverLaconexinaunabasededatossehaceatravsdeunDriver.UnDrivereselmedio por el cual la informacin almacenada en la base de datos llega a la aplicacin. El Driver constituye una capa intermedia entre la aplicacin y la base de datos la cual tienecomopropsitotraducirlasconsultasdedatosdelaaplicacinencomandosque el SGBD entienda para lo cual se requiere que tanto la aplicacin como la base de datosdebensercompatiblesconelDriverautilizar.PorloanteriorACCESStienesu Driver,MySQLtienesuDriver,ORACLEtienesuDriveryasitodoslosSGBDexistentes tienensupropiodriver.ExistenvariostiposdeDrivers,losODBCqueesunainterfaz creadaporMicrosoftylosJDBCquesondriversespecialesparaconectaraplicaciones JAVAaunabasededatos.

DNSElDATANAMESOURCEoDNSporsussiglaseningles,eslafuentededatosqueala queunDRIVERtipoODBChacereferencia,esdecir,sieldrivereselmedioporelcual seaccedeacualquierbasededatos,elDNSeselqueespecificaculdetodasdeese tipo de driver se va a acceder. Por ejemplo, en un computador pueden haber varias bases de datos de ACCESS, el DNS entonces har referencia a que base de datos de esas es que el usuario se quiere conectar. Al DNS se le llama tambin ALIAS. El DNS posee la informacin de la ubicacin fsica de la base de datos y el driver necesario paraaccederaella.Laubicacinfsicahacereferenciaalservidorocarpetadentrodel discodurodelPCdondeestlabasededatos.

ConceptosPreliminares./Driver

57

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

ConfiguracindeunDriverODBC

DriverparaunabasededatosdeACCESSParaconfigurarundriverODBCsedebetenerlabasededatosyalista.Acontinuacin semuestracomocrearunDNSparaunabasededatosdeACCESS. ParacrearunDNSsesiguenlossiguientespasos: Primerpaso. Enelpaneldecontrolseescogeherramientasadministrativas. SegundoPaso: Yaenherramientasadministrativasseescoge orgenesdedatosODBC Tercerpaso. YaenlaventanadeODBCseescogelapaleta DSN de usuario y en agregar se crea un nuevoorigendedatos.

58 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

CuartoPaso: Enestepasoseescogeeldriverdelabasededatosquesevaacceder.Enesalista estntodoslosdriverinstaladosenelsistema.

ComosevaacrearunDNSparaunabasededatosdeACCESseescogedichodriver yluegosedaclicenfinalizar. QuintoPaso: Enestaventanaseescogelarutadelabasededatosaconectarmedianteseleccionar. ElnombredelDNSoALIASseponeenelcampodenombredeorigendedatos. AquenelejemploelDNSsevaa llamar aprendiendo y apunta a c:\london.mdb que es la base de datosencuestin.Seguidoaesto se presiona aceptar y el DNS ya estalistoparausarse. AquenlalistadeDNSestaelnuevoorigendedatosquesecre.Sisequiereapuntar alabasededatosLondon.mdbsedebeapuntaralDNSllamadoaprendiendo.

ConceptosPreliminares./ConfiguracindeunDriverODBC

59

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

DriverparaMySQLParaconfigurarunDNStipoMySQLhayquetenerencuentaelservidordondeesta basededatosyaqueMySQLfuncionacomotal.Parahacerestodemanerasencillase recomienda utilizar el asistente que trae el aplicativo mysqlconnectorodbc5.1.4 win32quevieneconelmaterialdelcurso. Para configurar el DNS de MySQL se siguen los pasos del primero al tercero de la mismamaneracomosehizoconACCESS. Cuartopaso seescogeelMySQLODBC5.1Driver

Quintopaso Aqu se le pone un nombre al DNS(aprendiendoMySQL),unnombreal servidor(server),elnombredelservidor o server, nombre de usuario( User), contrasea(password) y puerto(port) fueron los que se usaron en la configuracindeMySQLalmomentode instalarlo.Losvaloresqueseusaronen la configuracin del DNS son los referentesalosconfiguradosenMySQL. Con el botn Test se prueba si la conexin es exitosa. El nombre de la base de datos se escoge de la lista que se muestra en database que en este casoesaprendiendo.

60 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

JDBC

Introduccin.Comosedijoconanterioridadlosdriverssonelmedioporelcualselaaplicacino el usuario se conectan a la base de datos. JDBC es pues un conjunto de clases que permitenaunaaplicacintipoJAVAconectarseaunabasededatosdeunfabricante en particular. JDBC es una interfaz que permite hacer transparente para el programadorenJAVAtodoloreferentealaconexinaunorigendedatoshaciendo que la comunicacin con el mismo sea a travs de consultas SQL, y al ser SQL un EstndaraplicableacasitodaslosSGBD,hacequelatareadeinteractuarconlabase dedatosatravsdellenguajedeprogramacinseamuchomsfcil. JDBCesunAPIdefinidoenlospaquetesjava.sqlyjavax.sqlquecontienentodaslas interfacesyclasesnecesariasparamanipularlosdatosenlastablasdelabasededatos lo que permite hacer consultas de tipo Select, aadir, borrar o editar datos de las mismas. JDBC tambin permite conectarse a DNS de tipo ODBC a travs de una interfazespecial.

ConexinalaBasededatos.Lasclasesnecesariasparalaconexinalabasededatosseencuentranenjava.sqly javax.sql. Loprimeroquesedebehacerescargaredriverquesevaausarenlaaplicacin.Esto se logra usando el mtodo estatico forName() de la clase Class. La sintaxis es la siguiente: Class.forName(nombre_driver) Dondenombre_drivereseldriverquesevaacargar. Los nombres de los driver ya estn definidos por el JDK solo hay que descargar e instalarlosqueseannecesarios.EldriverpordefectoquetraeelJDKeseldenominado puente JDBCODBC que permite conectarse a cualquier DNS de tipo ODBC. Se le denomina puente ya que crea un camino entre JDBC y ODBC que como se vio

JDBC/Introduccin.

61

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

anteriormente son dos tipos de drivers distintos. El nombre de este driver es:

sun.jdbc.odbc.JdbcOdbcDriver.ParacargarundriverdeMySQLseusa: SieldrivernosepuedecargarsegeneralaexcepcinClassNotFoundException. Ya cargado el driver hay que escoger a cual base de datos se va a conectar la aplicacin. Esto se hace a travs de la clase DriverManager. DriverManager no necesita instanciarse ya que implementa mtodos estticos que permiten cargar el driver apropiado. Si DriverManager no puede cargar el Driver genera la excepcin SQLException. Para conectarse con la base de datos a travs de DriverManager se usa el mtodo getConnection(StringURL,Stringuser,StringPassword)querecibe3parmetrosque son: StringURL:direccindelabasededatosqueevaausar. Stringuser:nombredeusuariodelabasededatos.Estenombrefuenelquese lepusoalabasedatosenelmomentodesucreacin. StringPassword:contrasadelaBD.Estacontraseatambinsedefinienel momentodcrealabasededatos. ElURLseconocecomolocalizadoruniversalderecursosysuestructuraeslasiguiente: jdbc:: donde jdbc es el estndar usado, subprotocol es el tipo particular de la fuente de datos que puede ser ODBC, MySQL, Oracle y el subname depende solo del subprotocoloquepuedeserelnombredelabasededatosoDNSolaubicacion. EncasoquesequisieraaccederaunabasededatosODBCelurlquedaraasi: jdbc:odbc: sifueraenconunabasededatosremotaelurlseria: jdbc:://ubicacion:puerto/nombreBD paraMySQLtrabajandocomolocalunejemplodeurlseria: jdbc:mysql://localhost:3306/aprendiendo elurltienelacapacidaddedireccionarlaaplicacinaunabasededatosqueesteen cualquierubicacinlocaloremotacomoseriaenunaredoenlamismainternet. ElmtodogetConnectionretornaunobjetodetipoConnection,queeslaquepermite quehayaunaconexindirectaentrelaBDylaaplicacin. LacomunicacinentrelaBDylaaplicacinsedaatravsdeconsultasSQL.Laclase que permite enviar las consultas a la BD es la interfaz Statement. El mtodo62 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

executeQuery(String consulta) recibe como parmetro una cadena donde se encuentralaconsultaenlenguajeSQLyretornaelresultadodedichaconsultaenun objetodetipoResultSet.ParacrearunStatementqueinteractueconlabasededatos conectadaalaaplicacinseusaelmetodocreateStatement()delobjetoConnection creadocongetConnectiondeDriverManager. Elsiguientefragmentodecdigomuestracomoconectarseaunabasededatosdecon undriverodbcyDNSaprendiendomySQl.EstaesunabasededatoshechaenMySQL quetienecomousuariorootynotienecontrasea. ConexinalDNS aprendiendomySqlconusuario Connection conexion; rootysinpassword().Aquse Aqusecargaeldrivertipo Statement stmt; estableceelvalordelobjeto try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); conexion=DriverManager.getConnection("jdbc:odbc:aprendiendoMysql","root" ,""); stmt=conexion.createStatement(); } Delobjetollamadoconexin catch (ClassNotFoundException e){ creadocongetConnectionse e.printStackTrace(); creaelStatementllamadostmt } catch (SQLException e) { poreleccindelprogramador. e.printStackTrace(); } Excepciones

generadasenel procesode conexin

Consultandolabasededatos.Del fragmento de cdigo anterior, la interfaz Statement llamada stmt permite hacer las consultas de tipo SQL a travs del mtodo executeQuery( string consulta). Este mtododevuelvecomoresultadounobjetodetipoResultSet.elsiguientefragmento decdigomuestralosprincipalesmtodosycaractersticasdelResultSetydelcualse destacanalgunosmtodosimportantesdelresulsetcomoson: Next() getString() getDouble() lasfilasresultantesdelaconsultaestnalmacenadasenelresulset.Pararecorrerlas unaaunaseutilizaelmtodonext()queretornaverdaderocuandoseapuntaauna filavalida.Cuandosellegaalfinal,next()retornafalso.Poresolatablaserecorrecon unwhilequerevisasisellegoalfinal. JDBC/ 63

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

public static void main(String[] args) { Connection conexion; Statement stmt; ResultSet resultado; String consulta; String Cad=""; String nombre,descripcion,codigo; double precio=0; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); conexion=DriverManager.getConnection ("jdbc:odbc:aprendiendoMysql","root" ,""); stmt=conexion.createStatement(); consulta="Select * from producto";//consulta SQL resultado=stmt.executeQuery(consulta); while(resultado.next()==true) { nombre=resultado.getString("nombre_prod"); codigo=resultado.getString("codigo_prod"); precio=resultado.getDouble("precio_prod"); Cad+=(codigo+" | "+nombre+"|"+precio+"\n"); } JOptionPane.showMessageDialog(null, Cad); } catch (ClassNotFoundException e){ e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } Conexin es el Objeto que gestiona conexinalaBD Stmt es el Objeto para escribir la consultaSQL ResultadoeselResultSetquerecibe elresultadodelaconsulta Consulta es un String donde se definelaconsultaSQL Dentrodelbloquetrycatchsecarga eldriverconclass.forName Y con driverManager seconecta alabasededatos.

Conelobjetostmtsecreaelobjeto alcualseleenvanlasconsultas. Se define en el String consulta la consulta a la base de datos y se enva con executeQuery la cual devuelve en resultado un ResulSet conlosdatosdelaconsulta. En un while se recorre con el mtodonextlasfilasdelResultSety con getString que recibe como parmetroelnombredelacolumna seextraeeldato. Se muestran los datos acumulados encad.

Se gestionan las excepciones generadas.

El ResultSet tieneunapuntadorinternoqueindicasobrequefiladelresultadosevan hacer las operaciones. next() mueve ese apuntador de menor a mayor. Hay otros mtodosquemodificanelvalordelapuntadorocursorqueson: first():mueveelcursoralaprimerafiladelresultadodelaconsulta beforeFirst():mueveelcursorantesdelaprimerafila last():mueveelcursoralaltimafila afterLast():mueveelcursordespusdelaltimafila.

64 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

getString(String), getDouble(String) son un conjunto de mtodos que sirven para obtenerelvalordelacolumnadelafilaqueapuntaelcursordelResultSet.Antesde profundizar en esa clase de mtodos es necesario saber cmo JDBC interpreta los diferentestiposdedatospresentesenSQL.Lasiguientetablamuestraesarelacin. Tipo de dato en JAVA String java.sql.Numeric boolean byte short int long float double byte[] java.sql.Date java.sql.Time Tipo de dato en SQL VARCHAR or LONGVARCHAR NUMERIC BIT TINYINT SMALLINT INTEGER BIGINT REAL DOUBLE VARBINARY or LONGVARBINARY DATE TIME Mtodo para obtener el valor getString(nombre_col)

getBoolean(nombre_col) getByte(nombre_col) getShort(nombre_col) getInt(nombre_col) getLong(nombre_col) getFloat(nombre_col) getDouble(nombre_col) getByte(nombre_col) getDate(nombre_col) getTime(nombre_col)

EstatablamuestraademslosmtodosdelResultSetnecesariosparaobtenerundato deuntipodeterminadoenSQL. LosmtodosgetXXXX(String)recibencomoparmetroelnombredelacolumnaenla queesteldatodeseado. Ejemplo. se hizo una consulta(select * from producto) y el ResultSet arrojo el siguiente resultado:

Nota:elResultSetnogeneraestatabla.ParamostrarunobjetoResultSetenunJTable hayinvertirvariaslneasdecdigo.

JDBC/Consultandolabasededatos.

65

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

Si el cursor del ResultSet estuviera en la lnea resaltada y se quisiera obtener los valoresdeesafilaseutilizaranlosmtodosdelasiguientemanera: Paraobtenerelnombredelproducto:resultado.getString(nombre_prod) Entre parntesis va el nombre de la columna tal y como se defini en la BD y esto retornaelStringMonitorAOC21Inchesqueelvalorqueestenesacolumna. Paraobtenerelvalordelproducto:resultado.getDouble(valor_producto)querecibe unacadenaconelnombredelacolumnayretornaundoubl(451000)conelprecio del producto. Se escogi getDouble por la columna precio_prod se defini como DoubleenlaBD. Loanteriorseharaconlasotrascolumnasdelafila.Sisedeseapasaralaotrafilase usaelmtodonext()yserepiteloanterior. Lotratadoenesteapartesonlosconceptosyconocimientosbsicosacercadecmo conectarsealaBDyrealizarconsultassobreellausandounprogramaenjava. A continuacin se muestra un ejemplo sencillo que busca consultar los datos de un clienteingresandosucedulaparalocualsediseolasiguienteinterfaz:

Alpresionarelbotnbuscarsedebemostrarelrestodelosdatosenloscampos correspondiente. Enelprogramaprincipalsehacelaconexinalabasededatosyseenvaalaventana pormediodelconstructordelamismaelobjetoConnectionpararealizarlasconsultas enlaventana. Eneleventodelbotnbuscarserealizalaconsultaysemuestranlosresultados. 66 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

Programaprincipal. publicstaticvoidmain(String[]args) Objetoconnectionparaenviarala { Connectionconexion; CargadeldriveryconexinalaBD proporcionandoelURLcorrespondiente try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); conexion=DriverManager.getConnection ("jdbc:odbc:aprendiendoMysql","root",""); interfazBDClienteGUI=newinterfazBDCliente(conexion); } catch(ClassNotFoundExceptione) { Aquseinstanciala e.printStackTrace(); interfazyseenvael } objetoconexinque catch(SQLExceptione){ representaalaBD printStackTrace(); } } ConstructordelainterfazgraficaInterfazBDCliente privateConnectionconexion; /** *Thisisthedefaultconstructor */ publicinterfazBDCliente(Connectionconexion) { super(); this.conexion=conexion; initialize(); }

Constructordelainterfaz querecibeelobjeto connectionquevienedel programaprincipal

Elmtodoinitialize() configuralaposicinyel tamaodetodoslos componentesvisualesy ademsloseventos.

JDBC/Consultandolabasededatos.

67

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

Eventobotnbuscarenlainterfazgrafica Objetosnecesariosparacrearla publicvoidactionPerformed(ActionEvente) consulta(stmt)yrecibirelresultadodela { misma(ResultSetresultado) if(e.getSource()==BBuscar) { Statementstmt; ResultSetresultado; StringconsultaSQL; try { stmt=conexion.createStatement();//secreaelobjetoStatement consultaSQL="select*fromclientewherecedula_cliente='"+TFcedula.getText()+"'"; resultado=stmt.executeQuery(consultaSQL); Aquseformala //comoestaconsultadaunafila,sielmtodonextdaverdadero cadenaquerealizala if(resultado.next()==true)//esporquehubounafilacomoresultado consulta.comola { consultadependedel TFNombre.setText(resultado.getString("nombre_client")); valordelJTextField,este TFTelefono.setText(resultado.getString("telefono_cliente")); seconcatenaala TFDireccion.setText(resultado.getString("direccion_cliente")); consultayserodeapor TFcorreo.setText(resultado.getString("ciudad_cliente")); comillassimplesyaque } esvarcharenlaBD. else//sinextretornafalsofuequelaconsultanoarrojoninguna {//filaynoseencontrelcliente.SeborranlosJTextFields JOptionPane.showMessageDialog(null,"Noexisteelcliente"); TFNombre.setText(); Aquseponeenlos TFTelefono.setText(); JTextFieldslosotros TFDireccion.setText( datosdelclientequese TFcorreo.setText(); obtienenconel respectivogetterque } recibeelnombredela } columnaaobtener catch(SQLExceptione1){ JOptionPane.showMessageDialog(null,e1.getMessage()); } } }

Enestefragmentodecdigoseobservaquesepuedeformarlaconsultapormediode datosqueelusuarioingresaatravsdeunJTextFielduotroscomponentessumandoa lacadenadelaconsultaeltextodelcomponente.Hayquetenerencuentalostiposde datosvarcharseencierranentrecomillas,poresoelcontenidodelcomponentedebe estarrodeadoporcomillassimples.Cuandolaconsultadependedevaloresvariableso esdinmicaesmejorusarunPreparedStatement.

68 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

PreparedStatement

PreparedStatementesunainterfazqueimplementaunaconsultaSQLprecompilada, osea,unaconsultaenlaquesedefinelastablasquesevanausarylascolumnasque sevanapresentar,esdecir,loquevaenlaclausulaselectyfromdelaconsulta.Los parmetrosdeentradaquedefinenlaconsultayquevanjuntoconlaclausulawhere sedefinendespuscuandosetenganesosdatos.Elusodeestainterfazestilcuando senecesitaenviarmuchasconsultassimilaresalaBDendondecambiensololas condicionesdelwhere. ParadefinirunaconsultapreparadaseinstanciaunobjetoPreparedStatementapartir delobjetoconnectionconlapartedelaconsultaquenovaacambiar. stmt=conexion.prepareStatement("select*fromclientewherecedula_cliente=?"); elsignodeinterrogacinpresenteenlaconsultaindicaqueesecamposeproveer masadelanteyesloquehacealaconsultadinmica.Yaenstmtseencuentraun PreparedStatementenelqueintervienelatablaclienteyqueentregaratodaslas columnas. Paradefinerelvalordelsignodeinterrogacinseusaunsetterquerecibecomo parmetrounnumeroenteroquerepresentalaposicindelsignodeinterrogacina completarenlaconsulta.sihayvarioscamposdesconocidosenlaconsultase enumerandesde1hastansegnellugardeocurrenciaenlaconsulta.Tambinrecibe comoparmetroelvalorquesevaaponerenlugardelsignodeinterrogacin.Como elcampoquesevaallenaresunStringovarcharenlaBDseusasetString.Asicomo elResultSettienelosmtodosgetXXX,elPreparedStatementtienelosmtodos setXXX. stmt.setString(1,TFcedula.getText()); LaconsultaseejecutaconexecuteQuery()yretornaelResultSetconelresultadodela consulta. resultado=stmt.executeQuery(); Ejemplo. Elsiguienteejemploesunvisualizadorde lasfacturasquehayahechounclienteen especial.Paralocualsediseolasiguiente interfaz. Enlainterfazseingresalaceduladel clienteysepresionaconsultar.Enese momentodebeaparecerenlalistatodasJDBC/PreparedStatement 69

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

lasfacturasquehayahechoesecliente.Cuandoseescogelafacturadelalista,en JTextAreadebenaparecerlosproductosdedichafacturacomosemuestraenla figura.

EventodelBotnConsultar

public void actionPerformed(ActionEvent e) { if (Bconsultar==e.getSource()) { PreparedStatement Pstmt; ResultSet resultado;

PreparedStatementdonde seestablecelaconsultaSQL dinmica.Fjeseenelsignode interrogacinqueindicaque esevalorsedefinidodespus. Soloseestconsultadouna columnadelatablafactura

try { Pstmt=conexion.prepareStatement("select codigo_factura+ Seborranlos from factura+ elementosdel where cedula_cliente=?"); JComboBoxque pudieranestar Pstmt.setString(1, TFCedulaCliente.getText()); conanterioridad resultado=Pstmt.executeQuery(); Sedefineel primer(1)campo CBFacturas.removeAllItems(); incognitodela PreparedStatement while(resultado.next()==true) queesunStringcon { laceduladelcliente CBFacturas.addItem(resultado.getInt(1)); enelJTextField } } catch (SQLException e1) SerecorreelResultSetpor { mediodelmtodonext()yel e1.printStackTrace(); whileyseaadealJComboBox } laprimeracolumnadela } consultaqueeselcdigodela } facturaquealserautonumerico enlaBDsepuedeobtenercon getInt Paracumplirtodoslosrequerimientosdelejemploesnecesariohacer2consultas:una enelbotnconsultarquetienecomoobjetivollenarelJComboBoxconlosnmeros defacturasasociadosalclientedeseadoyotraquemuestrelosproductosdelafactura seleccionada de la lista y adems sean del cliente escrito en el JTextField. Para este ejemplosesiguelamismametodologadelanteriorqueesconectarlabasededatos enelprogramaprincipalyenviaralainterfazelobjetoConnectionconlaconexinala BD. Solo se muestran los eventos ActionPerformed del botn Consultar y el ItemStatechangedelJComboBox.

70 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

EventoItemStateChangedelJComboBox public void itemStateChanged(ItemEvent e) { if(CBFacturas==e.getSource()) { PreparedStatement Pstmt; ResultSet resultado; try { Pstmt=conexion.prepareStatement("select codigo_prod, nombre_prod,+ cantidad,precio_prod,fecha_factura" + " from factura,item_factura,producto " + Estaconsultaesunjoinentre "where factura.codigo_factura+ factura,productoetem_factura =item_factura.codigo_fact and " + dondesenecesitasaberlosproductos "item_factura.codigo_producto+ quecomprounclienteenunafactura =producto.codigo_prod " + dada.Lacedulaylafacturasonlos "and factura.codigo_factura=? and + camposincognitos cedula_cliente=?"); Pstmt.setInt Pstmt.setString (1, (Integer)CBFacturas.getSelectedItem()); (2, TFCedulaCliente.getText()); Elnmerode lafacturaesel primervalor incognitoyes entero.Lacedula estadesegunday esunvarcharenla BD. Serecorreel resulSetconelwhile

TADatosFact.setText(""); Seejecutala resultado=Pstmt.executeQuery(); consulta. String cad=""; TADatosFact.setTabSize(10); cad="______________________________________" + "____________________________________\n" + "codigo | Nombre Prod\t| Cantidad\t| Precio\n" + "------------------------------------------------------------" + "------------------------------------------------------------\n" ; while(resultado.next()==true) {

TFFechaFact.setText(resultado.getDate("fecha_factura").toGMTString()); cad+=resultado.getString(1)+" "+resultado.getString(2)+"\t| "+ resultado.getInt(3)+"\t| "+resultado.getDouble(4)+"\n"; Seobtienen todaslascolumnas } delaconsulta.el cad+="_______________________________________" + numerodelgetteres "______________________"; deacuerdoconel TADatosFact.setText(cad); ordendelas Seaadelacadena columnasenla conlosdatosalJTextArea consultaselect. } catch(Exception e1){JOptionPane.showMessageDialog(null, getMessage());} } }

JDBC/PreparedStatement

71

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

ActualizandoLaBaseDeDatos LaactualizacindelainformacindelaBDatravsdelaaplicacinJAVAsehacea travsdesentenciasSQLdeltipoinsert,updateydeletequeseenvanalaBDpor mediodeunobjetodetipoStatementounPreparedStatement.Comoestaclasede consultasnogeneraningnresultado,noseusaelmtodoexecuteQueryelcual retornaunResultSet.Envezdeeso,usaelmtodoexecuteUpdate()queesespecial paraejecutaractualizacionessobrelosdatos.executeUpdateretornaunenteroque indicacuantasfilasdentrodelaBDseafectaronconlaactualizacin. Paradaraconocerlaactualizacin,borradoycreacindefilassobreunatabla considreseelsiguienteejemplo. Ejemplo1. Diseeunainterfazquepermitacrearun nuevoclienteingresandolosdatosdel mismo. Elclientesecreacuandosepresionael botncrear. Siguiendolamismametodologadeejemplosanterioresdondelaconexinsehaceen elprogramaprincipalyseenvapormediodelconstructordelainterfaz,solose muestraeleventodelbotncrearqueesdondeserealizalaactualizacin. Talycomoseaprendienelcapitulo public void actionPerformed(ActionEvent e) anterior,lacreacindeunnuevoregistropara { unatablasehaceatravsdeunaconsulta if (e.getSource()==BCrear) insert.Aqusehacelacreacinatravsdeun { PreparedStatementyporesoseponenlos PreparedStatement stmt; camposincognitosparallenarlosdespus. ResultSet resultado; try { stmt=conexion.prepareStatement("insert into cliente " + "(cedula_cliente,nombre_client,direccion_cliente," + Laactualizacinsehacea "ciudad_cliente,telefono_cliente) values (?,?,?,?,?)"); travsdelexecuteUpdate(). stmt.setString(1, TFCedula.getText()); stmt.setString(2, TFNombre.getText()); stmt.setString(3, TFDireccion.getText()); stmt.setString(4, TFcorreo.getText()); stmt.setString(5, TFTelefono.getText()); stmt.executeUpdate(); Aqusellenanloscampos incognitosdelaconsultapuestaenel PreparedStatement,elordenquese usaenlossettersesdeacuerdocomo sedistribuyeronenlaconsulta:cedula_cliente,nombre_client,direccion_cliente,".

fijeseenelnumeroqueacompaaal setterparadeterminardichoorden

} catch (SQLException e1) { JOptionPane.showMessageDialog(null, e1.getMessage()); }

72 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

ResaltadoenlafiguraestaelclientecreadoenlaBDmediantelainterfazenJAVA. Ejemplo2. Sedeseacrearunainterfazque permitaactualizaroinclusoborrarun clientedelatablacliente.Lainterfaz creadaeslasiguiente: Serecorrenlosclientesconelbotn >>>>yparaborrarelregistroactualse presionaborraryparaactualizaralgn cambioquesehagasobreloscampos dedatossepresionaelbotn actualizar. PararecorrerlosclientesestossecarganenunResultSetenelconstructordela interfazquesemuestraacontinuacin: ConstructorInterfaz EnesteResultSetsealmacenanlos clientesdelaBD private ResultSet resultado; public InterfazModificarCliente(Connection conexion) { Aqusehaceuna super(); consultasimplea initialize(); travsdeunStatement this.conexion=conexion; cuyoresultadose this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); almacenaenel ResultSet Statement stmt; anteriormente String consultaSQL; declarado.Laconsulta sacatodosloscampos try { yfilasdelatabla stmt=conexion.createStatement(); cliente. resultado=stmt.executeQuery("select * from cliente"); } catch (SQLException e1) { JOptionPane.showMessageDialog(null, e1.getMessage()); } }

ActualizandoLaBaseDeDatos/PreparedStatement

73

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

YaconlosregistrosdelatablaenelResultSet,conelbotn>>>>>,serecorrenlas filas.Paraesoseusaelmtodonext()delResultSetyseobtienenloscamposdelafila actualqueseponenenlosJTextFields. Eventobotn>>>>>. public void actionPerformed(ActionEvent e) Serecorreconnext()el { ResultSet.Esderecordarqueen if (e.getSource()==BotonSig) { elconstructorsellenoconlos try { datosdelatablacliente. if (resultado.next()==true) { TFCedula.setText (resultado.getString(1)); TFNombre.setText (resultado.getString(2)); TFDireccion.setText (resultado.getString(3)); TFcorreo.setText (resultado.getString(4)); TFTelefono.setText (resultado.getString(5)); } else Sesacanloscamposdela resultado.beforeFirst(); filaactualenelordenenel } catch (SQLException e1) { queestndefinidosenlaBD. e1.printStackTrace(); } Estosseponenenel } JTextFieldcorrespondiente. paraqueseansusceptiblesa modificaciones ParaactualizarsetomalacedulaqueesteenJTextFielddecedulaysehaceun Updatesobreelclientecondichacedula.Enelupdateseactualizanlosotrosdatos comoelnombre,telfonoydemsporsielusuariocambioalgunodeellos. Eventobotnactualizar. PreparedStatementquerecibelasentenciaSQL if (BotonActual==e.getSource()) deconsultadondeseactualizantodoslos camposdeunclienteconcedula=?hayque { PreparedStatement stmt; String consultaSQL; try { stmt=conexion.prepareStatement("update cliente set nombre_client=?," + "direccion_cliente=?," + "ciudad_cliente=?, " + "telefono_cliente=?" + where cedula_cliente=?"); stmt.setString stmt.setString stmt.setString stmt.setString stmt.setString (1, TFNombre.getText()); (2, TFDireccion.getText()); (3, TFcorreo.getText()); (4, TFTelefono.getText()); (5, TFCedula.getText()); recordarqueloscamposincognitossedefinen despus

SeEjecutalaordenSQL stmt.executeUpdate(); } catch (SQLException e1) { JOptionPane.showMessageDialog(null, e1.getMessage()); }

Valoresincognitosquese completanenelobjetostmt. Nteseelordendelossettersyel ordenenlascolumnasdela consulta. }

74 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

ElprocesodeborradoesfamiliaryaquesehaceunDELETEsobreelregistroquetenga comocedulalacedulaquemuestreelJTextField.Hayquerecordarqueesacedulase obtienerecorriendolosclientesconelbotn>>>>. Eventoborrar if (BotonBorrar==e.getSource()) { PreparedStatement stmt; String consultaSQL; try { int opc=JOptionPane.showConfirmDialog(null, "desea borrar el registro"); if (opc==JOptionPane.YES_OPTION) { stmt=conexion.prepareStatement("delete from cliente where cedula_cliente=?"); stmt.setString(1, TFCedula.getText()); stmt.executeUpdate(); SentenciaSQLconel } DELETEsobrelacedula=?. Sellenaelcampo El?sellenadespus. } incognitoyseejecuta laactualizacin. catch (SQLException e1) { JOptionPane.showMessageDialog(null, e1.getMessage()); } }

ActualizandoLaBaseDeDatos/PreparedStatement

75

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

JTableElcomponenteidealparamostrarlosresultadosdeunaconsultaqueretornevarias filasesunJTable.UnJTableesuncomponenteconlaaparienciadeunagrilladeExcel quepermitevisualizardatosqueseandelaformafilacolumnacomomatricesoenel casodeinters,elresultadodeunaconsulta.

UnJTabledebeserusadoenconjuntoconunJScrollAreaparapoderexplorartodaslas filasycolumnasdelJTableconlosScrollBarobarrasdedesplazamientodelmismo. LosconstructoresmstilesdelJTableson: JTable(intnumFilas,intnumCols)recibeelnumerodefilasycolumnasconlas queiniciar. JTable(Object[][]Datos,Object[]nombreColumnas):Recibeunamatrizdedatos yunvectorconelnombredelascolumnas.Esdeaclararqueelnmerode columnasdelamatrizDatosdebeserelmismoqueloselementosdelvector nombreColumnas. JTable(TableModeldm):recibecomoparmetrounobjetoTableModel.La InterfazTableModeldefinelaaparienciadeunJTableencuantoalnumerode columnas,losdatosdelJTable.CuandosedeseanaadirdatosalJTablese debehaceratravsdesuTableModelinterno.Estainterfazseestudiamsa fondoacontinuacin.

76 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

Ejemplos: UnJTablede5x5. Instanciacindeun public static void main(String[] args) JTablede5x5 { JTable tabla=new JTable(5,5); ScrollPanequerecibeel JScrollPane panel=new JScrollPane(tabla); JTable.Fjesequeenla creacindelJScrollBarse defineelcomponenteque JOptionPane.showMessageDialog(null,panel, vaacontener. "JTable", JOptionPane.PLAIN_MESSAGE); } SeusaunshowMessageDialogparamostrarelJScrollPanecon elJTableadentro.ElshowMessageDialogrecibeelpanel,el mensajeyeltipodelmensaje. elresultadodelosiguienteesestaventana. Paradefinirelnombredelascolumnasydelosdatossepuedeusarelsegundo constructorqueseexplico.Enelsiguienteejemploseindicacomousarlo. EstaesunamatrizdeString.Un vectorsepuedecrearencerrandosus public static void main(String[] args) elementosdentrodecorchetesylos { valoresseparadosporcomas.Una String [][]valores={{"camilo","juan","pepe"}, matrizesunpuesvariosarreglos {"lucas","esteban","felipe"}, separadosporcoma. {"coco","canela","fulanito"}}; Arreglode String []nombreCols={"personas A","Personas B","Personas C"}; Stringdonde estnlosnombres Seinstanciael delacolumnasde JTableconel JTable tabla=new JTable(valores,nombreCols); latabla vectorylamatriz JScrollPane panel=new JScrollPane(tabla); de datos JOptionPane.showMessageDialog(null,panel, "JTable",JOptionPane.PLAIN_MESSAGE); }

ActualizandoLaBaseDeDatos/JTable

77

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

Elresultadodeestefragmentodecdigoeseste:

Sepuedeobservarlamatrizdevaloresyelnombredelascolumnas. ElJTabletienelosmtodossetValuesAt(Objectobj,intfila,intcolumna)querecibe comoparmetroelobjetoylaposicindondevaaquedarenelJTable.Ttambin tieneelmtodogetValuesAt(intfila,intcolumna)queretornaelvaloralmacenadoen unafilayenunacolumna.Lafilasseenumerandesdecerosintenerencuentalafila detitulo.

DefaultTableModelLosconstructoresanteriorestienenelinconvenientequeesnecesariotenertodoslos datosenelmomentodelainstanciacin.Enmuchasocasionesesnecesarioaadiro hastaeliminarfilasy/ocolumnasdelJTableentiempodeejecucinloquehaceque dichasimplementacionesseanmuylimitadas.Cuandoesnecesariorealizardichas tareassobreJTablesehacensobresupropiedadTableModel.Comosedijo anteriormente,elTableModeleselquedefinecomosonycomoestnorganizadoslos datosdentrodelJTable. YaqueunTableModelesunobjetoconmuchaslimitacionesseacostumbraautilizar unobjetodeltipoDefaultTableModelelcualtienemtodosparaaadir,eliminar columnas,obtenerelnmerodefilasycolumnasdelatablaydemsutilidades. LosmtodosmsrepresentativosdeunDefaultTableModelson: getRowCount():retornaelnumerodefilasdelDefaultTableModel. getColCount():retornaelnumerodecolumnas. addColumn(ObjectnombreColumna):recibecomoparmetrounobjetoconel nombredelanuevacolumna. addRow(Object[]valoresFila):recibeunvectordevaloresyloaadecomo nuevafila.Elnmerodeelementosdelvectordebeserigualaldenmerode columnas. removeRow(intnumFila):eliminalafilaenlaposicinnumFiladel DefaultTableModel. ParausarelDefaultTableModelenelJTableseusaelmtodosetModeldelJTableque recibecomoparmetroelDefaultTableModel.Cualquiercambioquesehagaluego sobreelDefaultTableModelsereflejaenlatabla. ParaobtenerelTableModeldeunJTableseusasetModel().78 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

publicstaticvoidmain(String[]args) { //DefaultTableModeltm=newDefaultTableModel(); DefaultTableModeltmm=newDefaultTableModel(); JTabletabla=newJTable(); tabla.setModel(tmm); JScrollPanepanel=newJScrollPane(tabla); 1.Seaadenlascolumnas tmm.addColumn("Cedula"); conaddColumn tmm.addColumn("Nombre"); tmm.addColumn("Telefono"); String[]datos={"1234","Camilo","7453321"}; tmm.addRow(datos); 2.secreaelvectorde treselementosquesonel String[]datos1={"42442","Juan","7432123"}; numerodecolumnasyse tmm.addRow(datos1); aadenalJTableatravsdel addRowquerecibeelvector. String[]datos2={"6464","Gladys","7389876"}; tmm.addRow(datos2); JOptionPane.showMessageDialog(null,panel, "JTable",JOptionPane.PLAIN_MESSAGE); JOptionPane.showMessageDialog(null, "Hay"+tmm.getColumnCount()+"Columnas\n"+ "Hay"+tmm.getRowCount()+"Filas"); CongetRowCountse obtieneelnumerodefilasy congetColumnCountel 3.Seborralasegundafila nuemro de columnas delJTable tmm.removeRow(1); JOptionPane.showMessageDialog(null,panel, "JTable",JOptionPane.PLAIN_MESSAGE); JOptionPane.showMessageDialog(null, "Hay"+tmm.getColumnCount()+"Columnas\n"+ "Hay"+tmm.getRowCount()+"Filas"); }

Elsiguienteejemplomuestraelusodelosmtodosmsimportantesdel DefaultTableModel.

ActualizandoLaBaseDeDatos/JTable

79

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

Estassonlasventanasquesegenerandelcdigoanterior. 1. secreanlascolumnascon addColumn 2. Seaadenlosdatoscon addRow

3. Seborralafila1(juan)con removeRow

MostrarunResultSetenunJTableSabiendoyacomosemanejaunJTableycmosacartodalainformacindelResultSetconel ResultMetaDatasepresentaunejemplodeaplicacindondesemuestraelresultadodeuna consultaenunJTable.

Elsiguienteejemploesunvisualizadordelasfacturasquehayahechounclienteen especial.Paralocualsediseolasiguienteinterfaz. Enlainterfazseingresalaceduladelclienteysepresionaconsultar.Enesemomento debeaparecerenlalistatodaslasfacturasquehayahechoesecliente.Cuandose escogelafacturadelalista,enJTextAreadebenaparecerlosproductosdedicha facturacomosemuestraenlafigura. Esteesunejemployaestudiado.Laideaesmejorarlainterfazdeesta: Aesta

80 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

DondelostemdelafacturanosemuestrenenunJTextAreasinoenunJTable. LoscambiosdeesteejemploestneneleventoItemStateChangeddelJComboBoxque semuestraacontinuacin: publicvoiditemStateChanged(ItemEvente) { Consultaparaobtenerlosdatosseleccionadosque if(CBFacturas==e.getSource()) sonelcdigo,nombre,preciodelproducto,lafecha { delafactura,lacantidadquesecomprdel PreparedStatementPstmt; producto.Enelwhereestlafacturaseleccionaday ResultSetresultado; elclientedelJTextfieldyestoseponecomo incognitoparallenardespus try { Pstmt=conexion.prepareStatement ("selectcodigo_prod,nombre_prod,"+ "cantidad,precio_prod,fecha_factura"+ "fromfactura,item_factura,producto"+ "wherefactura.codigo_factura=item_factura.codigo_fact+ and"+ factura.codigo_producto=producto.codigo_prod"+ andfactura.codigo_factura=?andcedula_cliente=?"); Verpgina78 Sellenanloscampos pararecordarPstmt.setInt(1,(Integer)CBFacturas.getSelectedItem()); incognitosdelnumero los Pstmt.setString(2,TFCedulaCliente.getText()); delafacturaylacedula constructoresresultado=Pstmt.executeQuery(); del cliente. del TableModel Secreaun Stringtitulos[]={"Codigo","Nombre","Cantidad","Precio"}; TableModelconlos DefaultTableModeltm=newDefaultTableModel(titulos,0); ttulosdelas Elarreglo columnasdefinidosen esde ObjectdatosFila[]=newObject[4]; elarreglodeString tamao4 Arreglo quesellena tituloy0filas. porque conloselementosde son4 while(resultado.next()==true) una filadelResultSet. columnas { enlatabla TFFechaFact.setText(resultado.getDate(5).toGMTString()); datosFila[0]=resultado.getString(1); Sellenaenelvectorloselementos datosFila[1]=resultado.getString(2); Yaconlos delResultSetenelordendelos datosFila[2]=resultado.getInt(3); datosenel ttulosdelatabla.En[0]valaprimera datosFila[3]=resultado.getDouble(4); TableModel columnadelResultSet,quesegnla tm.addRow(datosFila); estesepone consultaescdigo_prod,en[1]va Seaadeel enelJTable } nombre_prodyasisucesivamente. vectorllenoal TablaFactura.setModel(tm); TableModely } sesigueconel whileconla catch(SQLExceptione1) otrafila { JOptionPane.showMessageDialog(null,e1.getMessage()); } }} ActualizandoLaBaseDeDatos/JTable 81

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

YaquemostrarelresultadodeunaconsultaenunJTableestancomn,acontinuacin semuestraunaclasequeheredandotodaslascaractersticasdeunJTableyconun ResultSetcomoatributo,lomuestrasegnlosdeseosdelusuario.

82 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

TipoDeDatoBLOB UnodelostiposdedatosenSQLeseldenominadoBLOB(BinaryLargeObject).Eneste tipodedatosealmacenalainformacindemanerabinariaporloquesepuedeusar paraguardarcualquierclasedecontenidocomopuedeserimagen,videooaudioo texto,enfin,cualquierclasedearchivo. HaytresclasesdeBLOBqueseclasificansegnlacapacidadmximaquesoportan. TinyTextyTinyBlob:Columnaconunalongitudmximade255caracteres. BlobyText:Camponomayora65535byteso65KB MediumBlobyMediumTextCamponomayora16.777.215(16MB)bytes LongBlobyLongTextCamponomayora4.294.967.295bytes(4GB).Hayque tenerencuentaquedebidoalosprotocolosdecomunicacinlospaquetes puedentenerunmximode16Mb.

LeyendounBLOBmediantelaaplicacinJAVA

ParaleerdesdelaaplicacinJAVAunblobseusaelmtodogetBlob()delResultSet.El destinofinaldelosbytesledosdependedelanaturalezadelosmismos.Sielblob contenaunaimagen,seesperaqueestasemuestreenalgunaparte. EltipodedatoBlobSQLserepresentamediantelainterfazBlobenJAVA.Esteobjeto estdefinidoenelpaquetejava.sql. Losmtodosmsimportantesdeestainterfazson: getBytes(intinicio,intfin):retornaunarreglodebytesquecontienelosdatos delblobdesdeelparmetroiniciohastaelparmetrofin. lentgh():retornaunlongconeltamaoenbytesdelcampoblob.

Comounblobesuncampoquecontieneunarreglodebytes,tambinsepuedeleer delResultSetconelparmetrogetBytes()envezquecongetBlob().Estemetodo retornaunarreglodebytesqueeselquecontienelainformacindelBlobalmacenado enlaBD Elsiguienteejemplomodificalainterfazdebuscarclienteanteriormenteexplicaday aadelaposibilidaddeverlafotodelclientesiestaestenlabasededatos.Esde aclararqueesnecesariomodificarlatablaclienteyaadirleuncampoBlob.

TipoDeDatoBLOB/LeyendounBLOBmediantelaaplicacinJAVA

83

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

Estaeslanuevainterfaz. Eventoclicdelbotnbuscar. PreparedStatement stmt; ResultSet resultado; String consultaSQL; Consultaparabuscarel clienteporcedula. try { stmt=conexion.prepareStatement("select * from cliente + where cedula_cliente=?"); stmt.setString(1, TFcedula.getText()); Sellenaelcampoincognito resultado=stmt.executeQuery(); Se ejecutalasentencia Setomanlosvaloresde if (resultado.next()==true) lascolumnasdelafila { TFNombre.setText(resultado.getString2)); resultantesegnel TFTelefono.setText(resultado.getString3)); ordenenqueestn Sifotoes TFDireccion.setText(resultado.getString(4)); definidosenlabasede diferentede TFcorreo.setText(resultado.getString(5)); datos nulles porqueenesa Blob foto=resultado.getBlob(6); Seleeelcampobloben filasihaba unavariabledetipoBlob unafoto if (foto!=null) { byte[]datosImagen=foto.getBytes(1, (int)foto.length()); ImageIcon imagen=new ImageIcon(datosImagen); panelFoto.setIcon(imagen.getImage()); } SeobtienenlosbytesdelBlob Conesosbytessecrea conelmtodogetBytesdesde unImageIconysepone elprincipiocon1yhastaelfin enunJLabelconsetIcon length(). 84 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

else{ JOptionPane.showMessageDialog(null, "No existe el cliente"); } } catch (SQLException e1) { JOptionPane.showMessageDialog(null, e1.getMessage()); }

EscribiendounBLOBalaBDmediantelaaplicacinJAVA ComosedijoanteriormenteunBlobbsicamentesonunconjuntodebytesquejuntos formanalgunaclasedecontenido.Siguiendoesaidea,cuandosenecesitealmacenar undatobinarioalabasededatoshayqueencontrarlarepresentacinbinariade dichosdatosyesoesloqueseescribeenlabasededatos. ParaescribirdatosbinariosalabasededatosseusaelmtodosetBytes(ndice,valor) delPreparedStatement.Esnuestratareaentoncesencontrarlarepresentacinbinaria deldatoaalmacenar.Sidichainformacinestenunarchivoesnecesariousarun flujodeentradadedatostalcomoInputStreamoFileInputStreamparaleerlosbytes delarchivo. FileInputStreameselmedioporelcualsepuedeleerlosdatosdearchivosbinarios talescomoimgenes,videooaudio.Estosbytessepuedenalmacenarenunvector parasuposteriormanipulacinoloqueesdenuestrointers,enviaralaBD.El constructordelFileInputStreamrecibecomoparmetrounacadenaconrutadel archivoaleerounobjetoFilequelorepresente.Losmtodosmasimportantesdel FileInputStreamson: read(byte[]b):recibeunarreglobdebytedetamaonylollenaconnbytes desdeelarchivo. read(byte[]b,intoff,intlen):leedelarchivolenbytesempezandodesdeel byteoffyalmacenaesainformacionenelvectorb.

CuandosedesealeerunarchivodetextoesmejorusarunFileReadero BufferedReaderqueretornasonarreglosdecaracteresenvezquedebytes. ElsiguienteejemplomodificalainterfazdecrearClienteparapermitirescogeruna imagenalmacenadaenelcomputadoryguardarlaenlaBDenelcampofoto_cliente delatablacliente.

TipoDeDatoBLOB/EscribiendounBLOBalaBDmediantelaaplicacinJAVA

85

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

Interfazcrearcliente Elfuncionamientodelainterfazestdivididoendospartes.Primeroencargarlafoto desdeunarchivoyluegoenelbotncrearguardartodoslosdatosjuntoconlafotoa labasededatos. EventodelbotncargarFoto. ObjetoFiledondesealmacenalareferencia alarchivoseleccionadoconelJFileChooser

if(BotonCargar==e.getSource()) Cuadrodedialogoparaexplorar { elPCenbuscadelaimagen FilearchivoFoto; JFileChooserexplorer=newJFileChooser(); Seabreelcuadrodedilogoparabuscarel archivo.Esteretornaunintdependiendo intopcion=explorer.showOpenDialog(this); delsiseaceptaocancelalaoperacin.Si imagen=null; seaceptaretorna JFileChooser.APPROVE_OPTION.estose if(opcion==JFileChooser.APPROVE_OPTION) puedecompobarenunif { archivoFoto=explorer.getSelectedFile(); Aquseencuentrael imagen=newImageIcon(archivoFoto.getAbsolutePath()); tamaoenbytesdel PFotoCliente.setIcon(imagen.getImage()); archivoconlength() ysecreaunarreglo try{//seinstanciaelFileInputStreamconelFiledelJFileChhoser debytesdeese FileInputStreambyteImagen=newFileInputStream(archivoFoto); tamaoqueesledo conreaddel longtam=archivoFoto.length(); FileInputStream datosImagen=newbyte[(int)tam1]; byteImagen.read(datosImagen); Seobtieneelarchivo seleccionadocon } catch(FileNotFoundExceptione1){e1.printStackTrace();} getSelectedFileque retornaunFile.Conla catch(IOExceptione1){e1.printStackTrace();} rutadeeseFile } (getAbsolutePath)se } creaunImageIcony ExcepcionesgeneradasporelFileInputStreamluegoseponeenun JLabelconsetIcon

86 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

LuegodetenerlosbytesdelaimagenenelvectordatosImagenqueesunatributo globalatodalaclase,enelbotncrearseaadenlosnuevosdatos.Tambincomo atributodelainterfazestaelImageIconimagenqueesdondeestalaimagen seleccionada. Eventocrear. Lanicadiferenciadeesteejemploconel public void actionPerformed(ActionEvent e) anterioresqueaquyasehacereferenciaala { fotodelclienteenelinsertjuntoconsucampo if (e.getSource()==BCrear) { incognito. PreparedStatement stmt; ResultSet resultado; try { stmt=conexion.prepareStatement("insert into cliente " + "(cedula_cliente,nombre_client,direccion_cliente," + "ciudad_cliente,telefono_cliente, foto_cliente) values + (?,?,?,?,?,?)"); Sellenanloscamposincognitosdellos datostipotexto. stmt.setString(1, TFCedula.getText()); stmt.setString(2, TFNombre.getText()); stmt.setString(3, TFDireccion.getText()); stmt.setString(4, TFcorreo.getText()); Losdatosdelaimagenpreviamente stmt.setString(5, TFTelefono.getText()); obtenidosdelStreamenelarreglode SilaimagenseescogiconelJFileChooser el bytesseenvanalaBDatravsdel mtodosetBytesdelPreparedStatement. ImageIconimagenesdiferentedenull. Lafotoestadesextaenlaconsulta if (imagen!=null) stmt.setBytes(6, datosImagen); else stmt.setBytes(6, null); Sinoseescoginadase envaunnullalaBD. stmt.executeUpdate(); Serealizalaactualizacincon executeUpdatedel PreparedStatement } catch (SQLException e1) { JOptionPane.showMessageDialog(null, e1.getMessage()); } } Alterminarlatransaccin,enlabasededatoshayunacopiadelaimagen seleccionadaconelJFileChooser.Estemismoprocedimientosepuedehacersilos datossondeaudioovideoocualquiertipodecontenido.

TipoDeDatoBLOB/EscribiendounBLOBalaBDmediantelaaplicacinJAVA

87

2008II

ACCESOADATOSCONJAVA:NOTASDECLASE

RESULTSETComosevioenapartesanteriores,elResultSetesunainterfazenlacualunobjeto StatementoPreparedStatementalmacenaelresultadodeunaconsultadetipoSelect. TambinseaprendiqueelobjetodetipoResultSetpermiterecorrerdeprincipioafin elresultadodedichaconsultaconelmtodonext()ascomoobtenerelvalordeuna columnaconlosmtodosgetXXXX(numeroonombredelacolumna). OtracaractersticanonombradadelResultSetesqueelquedaconectadoalaBasede datosdirectamente,loqueindicaquecualquiercambioquesehagaaunafiladel ResultSetseleesthaciendoalabasededatos.Esporesoqueescostumbrequeya conlosdatosenelResultSetestosseactualicenpormediodelmismoResultSetyno pormediodesentenciasSQLUpdateoDelete. EnmuchasocasionessepuedenecesitarrecorrerelResulSetdemaneraarbitrariasea haciadeatrsparaadelanteoescogercualquierfilaaleatoriamente.

PropiedadesdelResultSet.ElResultSettienedospropiedadesimportantesqueson: resulsetTypequedefineeltipodelResultSetytienetresvaloresposiblequeson: TYPE_FORWARD_ONLY:Esteeselvalorpordefectodelapropiedadeindica queelResultSetserecorredeprincipioafin. TYPE_SCROLL_INSENSITIVE:EstevalordelapropiedadpermitealResultSet recorrenaleatoriamentelasfilasdelmismo.LaetiquetadeINSENSITIVEindica queelenResultSetnosevernreflejadosloscambiosquesehaganenlabase dedatosporotrosusuariosoaplicacionesenelmomentodeestarusndolo. TYPE_SCROLL_SENSITIVE:Tambinpermiteaccesodinmicoalasfilasdel ResultSetconlaadicinquecualquiercambioporunterceroalabasededatos severeflejadoenelResultSet. LaotrapropiedaddelResultSetesresulSetConcurrencyeindicasilaBDsepuede actualizaronoatravsdelResultSet.Estapropiedadsetrataafondomsadelante. LadefinicindeltipodeResultSetsehaceenelmomentoquesecreaelStatemento elPreparedStatementquevaadarorigenalResultSetpormediodelExecuteQuery. RecurdesequeelStatementsecreaatravsdemtodocreateStatementdelobjeto Connection. ElmtodocreateStatementoPreparedStatementdelobjetoconexinseagregandos nuevosparmetrosquesoneltipoylaconcurrenciadelResultSet.Estosparametros sonenteroscuyovalorsepuedeaveriguarusandounasconstantesqueestndefinidas dentrodelaclaseResultSet.Elnombredelasconstanteseselqueseexpreso anteriormentecomoTYPE_FORWARD_ONLY,TYPE_SCROLL_INSENSITIVEy TYPE_SCROLL_SENSITIVE. 88 ACCESOAUNABDPORMEDIODEUNAAPLICACINJAVA

CAMILOANDRSFERRERBUSTOS

EAM

lasintaxisparaloanterioresentonces: ParaunStatementseria Stmt=conexin.createStatement(tipo,concurrencia) YparaunPreparedStatementserentonces: Stmt=conexin.preparedStatement(consulta,tipo,concurrencia) Dondeconsultaeslacadenaqueseponeconloscamposincognitosoconsignode interrogacion. Acontinuacinunejemplo: consulta="select*fromempleadowherecedula_emp=?"; stmt=conexion.prepareStatement(consulta, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); stmt.setString(1,TFCedulaEmp.getText()); resultado=stmt.executeQuery(); EnelmomentodelacreacindelPreparedStatementsedefinequeelResultSetqueel objetostmtconelmtodoExectuteUpdateretornaravaaserdeltipo TYPE_SCROLL_INSENSITIVEyquecualquiercambioquesehagasobreelResultSet quedarareflejadoenlabasededatos.Loanteriorsehacemediantelasconstantes ResultSet.TYPE_SCROLL_INSENSITIVEyResultSet.CONCUR_