Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Acceso A Datos
Acceso A Datos
Ciclo DAM
IRENE CALDELAS
2º CURSO
Camino de la Miranda
Tema 1. Introducción al acceso a
datos
1.Introducción 2.Acceso a datos
Iniciamos esta primera unidad del módulo Acceso a datos, en el
que veremos la gran variedad de métodos de acceso a datos que
tenemos en el panorama actual.
Pero, ¿a qué nos referimos cuando hablamos de acceso a datos en Hay diversas estrategias de acceso a datos para gestionar la
una aplicación informática? persistencia de los datos:
Conociendo el funcionamiento de las diferentes alternativas Por eso, en muchas ocasiones se recurre a utilizar este tipo de
podemos comparar sus prestaciones al problema de la persistencia soluciones, el uso de ficheros en vez de bases de datos, y en
concreto que se nos presente. Cada una de las tecnologías tiene su particular de ficheros XML cuando se necesita intercambiar
propio origen y filosofía para alcanzar el mismo fin y, por esta información a través de varias plataformas de hardware o de
razón, no es fácil analizar sus ventajas y desventajas frente a las software, o de varias aplicaciones. A veces se exporta de una base
demás alternativas. de datos a ficheros XML para trasladar la información a otra base
de datos que leerá esos ficheros XML.
Por poner un ejemplo, lo más sencillo posible: si voy a crear una
base de datos para guardar mi colección de vídeos, probablemente Por esta razón se emplea XML en tecnologías de comunicación
no me va a interesar utilizar una base de datos Oracle, sino un como, por ejemplo, en WML (lenguaje de formato inalámbrico) y
producto mucho más barato, y sencillo de instalar y mantener. WAP (protocolo de aplicaciones inalámbricas).
7.Mapeo objeto relacional
DB2 Universal Database de IBM (International Business
Machines).
Universal Server de Informix (ahora de IBM),
INGRES II, de Computer Associates.
ORACLE de Oracle Corporation,
(ORM)
SyBASE
Por ello, para ahorrar trabajo al programador, se puede utilizar un Entre las implementaciones comerciales se puede resaltar TopLink
framework que se encargue de realizar estas tareas de modo que es un paquete de Mapeo objeto-relacional (ORM) para
transparente, de modo que el programador no tenga por qué usar desarrolladores Java. Provee un marco de trabajo para almacenar
JDBC ni SQL y la gestión del acceso a base de datos esté objetos Java en una base de datos relacional, o convertir objetos
centralizada en un componente único permitiendo su reutilización. Java a archivos XML.
*Insertar imagen
9.Desarrollo de
permitían como Visual Basic de Microsoft.
Aumenta la competencia.
Reduce los costes.
Facilita la construcción de estándares.
Tema 2. Manejo de ficheros
o Muchos métodos no lanzaban excepciones por
1.Introducción lo que era muy complicado detectar y resolver
errores
Si estás estudiando este módulo, es probable que ya hayas o No permitía manejar enlaces simbólicos
estudiado el de programación, por lo que no te serán desconocidos o Presenta problemas de escalabilidad.
muchos conceptos que se tratan en este tema. Directorios largos provocaban problemas de
memoria e incluso de denegación de servicio
Ya sabes que cuando apagas el ordenador, los datos de la memoria
El paquete java.nio.file incorporado a partir de JSE7
RAM se pierden. Un ordenador utiliza ficheros para guardar los
resuelve estos problemas.
datos. Piensa que los datos de las canciones que oyes en mp3, las
películas que ves en formato avi, o mp4, etc., están, al fin y al cabo, Es el que debemos usar para trabajar con archivos
almacenadas en ficheros, los cuales están grabados en un soporte independientemente de si realizamos I/O con streams
como son los discos duros, DVD, pendrives, etc. (java.io) ó con buffers y channels (java.nio)
Depende de lo que necesitemos pueden ser Las instancias de la clase File representan nombres de archivo, no
complementarios y utilizaremos conjuntamente ambos los archivos en sí mismos.
paquetes.
El archivo correspondiente a un nombre puede ser que no exista,
java.nio permite manejar múltiples canales (archivos o
por esta razón habrá que controlar las posibles excepciones.
conexiones de red) con uno o unos pocos hilos.
En java.nio el procesamiento de datos es más complicado Un objeto de clase File permite examinar el nombre del archivo,
que usar los streams bloqueantes de java.io descomponerlo en su rama de directorios o crear el archivo si no
java.nio es la opción si necesito manejar cientos de existe, pasando el objeto de tipo File a un constructor adecuado
conexiones (canales) abiertas y en cada una manejar una como FileWriter(File f), que recibe como parámetro un objeto File.
pequeña cantidad de datos.
Para archivos que existen, a través del objeto File, un programa
java.io es la opción si voy a manejar pocas conexiones puede examinar los atributos del archivo, cambiar su nombre,
con un alto ancho de banda (envío mucha información a borrarlo o cambiar sus permisos. Dado un objeto File, podemos
la vez) hacer las siguientes operaciones con él:
Hasta JSE7 java.io.File era la clase utilizada para realizar
operaciones I/O con archivos Renombrar el archivo, con el método renameTo(). El
Esta clase tenía limitaciones como: objeto File dejará de referirse al archivo renombrado, ya
que el String con el nombre del archivo en el objeto File no File f = new File("ficheros/personas.dat");
cambia. Crea un Objeto File asociado al fichero personas.dat que
Borrar el archivo, con el método delete(). También, con se encuentra en el directorio ficheros dentro del
deleteOnExit() se borra cuando finaliza la ejecución de la directorio actual. En este caso se indica la ruta relativa
máquina virtual Java. tomando como base el directorio actual de trabajo. Se
Crear un nuevo fichero con un nombre único. El método supone que el fichero personas.dat se encuentra en el
estático createTempFile() crea un fichero temporal y directorio ficheros. A su vez el directorio ficheros se
devuelve un objeto File que apunta a él. Es útil para crear encuentra dentro del directorio actual de trabajo.
archivos temporales, que luego se borran, asegurándonos File f = new File("c:/ficheros/personas.dat");
tener un nombre de archivo no repetido. Crea un Objeto File asociado al fichero personas.dat
Establecer la fecha y la hora de modificación del archivo dando la ruta absoluta:
con setLastModified(). Por ejemplo, se podría hacer: new
File("prueba.txt").setLastModified(new Date().getTime()); para Ejemplos utilizando el segundo constructor:
establecerle la fecha actual al fichero que se le pasa como
parámetro, en este caso prueba.txt. En este caso se crea un objeto File cuya ruta (absoluta o relativa) se
Crear un directorio, mediante el método mkdir(). También indica en el primer String.
existe mkdirs(), que crea los directorios superiores si no
existen. File f = new File("ficheros", "personas.dat" );
Listar el contenido de un directorio. Los métodos list() y Crea un Objeto File asociado al fichero personas.dat que
listFiles() listan el contenido de un directorio. list() devuelve
se encuentra en el directorio ficheros dentro del
un vector de String con los nombres de los archivos, directorio actual. En este caso se indica la ruta relativa
listFiles() devuelve un vector de objetos File.
tomando como base el directorio actual de trabajo.
Listar los nombres de archivo de la raíz del sistema de Ejemplos utilizando el tercer constructor:
archivos, mediante el método estático listRoots().
Este constructor permite crear un objeto File cuya ruta se indica a
La clase proporciona los siguientes constructores para crear través de otro objeto File.
objetos File:
File ruta = new File("ficheros");
public File(String nombreFichero|path); File f = new File(ruta, "personas.dat" );
public File(String path, String nombreFichero|path); Crea un Objeto File asociado al fichero personas.dat que
public File(File path, String nombreFichero|path); se encuentra en el directorio ficheros dentro del
directorio actual.
La ruta o path puede ser absoluta o relativa.
Debemos tener en cuenta que crear un objeto File no significa que
Ejemplos utilizando el primer constructor: deba existir el fichero o el directorio o que el path sea correcto.
Método Descripción
boolean canRead() Devuelve true si se puede leer el fichero
boolean canWrite() Devuelve true si se puede escribir en el fichero
boolean createNewFile() Crea el fichero asociado al objeto File. Devuelve true si se ha podido crear. Para poder crearlo el fichero no debe existir.
Lanza una excepción del tipo IOException.
boolean delete() Elimina el fichero o directorio. Si es un directorio debe estar vacío. Devuelve true si se ha podido eliminar.
boolean exists() Devuelve true si el fichero o directorio existe
String getName() Devuelve el nombre del fichero o directorio
String getAbsolutePath() Devuelve la ruta absoluta asociada al objeto File.
String getCanonicalPath() Devuelve la ruta única absoluta asociada al objeto File. Puede haber varias rutas absolutas asociadas a un File pero solo
una única ruta canónica. Lanza una excepción del tipo IOException.
String getPath() Devuelve la ruta con la que se creó el objeto File. Puede ser relativa o no.
String getParent() Devuelve un String conteniendo el directorio padre del File. Devuelve null si no tiene directorio padre.
File getParentFile() Devuelve un objeto File conteniendo el directorio padre del File. Devuelve null si no tiene directorio padre.
Cuando queramos crear un fichero, podemos proceder del Después de vaciar el directorio, este, se puede borrar importando la
siguiente modo: librería FileUtils y después
escribir FileUtils.deleteDirectory(newFile(destination));
try {
// Creamos el objeto que encapsula el fichero
File fichero = new File("c:\\prueba\\miFichero.txt");
1.2. Interface FilenameFilter
Hemos visto cómo obtener la lista de ficheros de una carpeta o
// A partir del objeto File creamos el fichero físicamenteif
directorio. A veces, nos interesa ver no la lista completa, sino los
(fichero.createNewFile())
archivos que encajan con un determinado criterio.
System.out.println("El fichero se ha creado correctamente");
else Por ejemplo, nos puede interesar un filtro para ver los ficheros
System.out.println("No ha podido ser creado el fichero"); modificados después de una fecha, o los que tienen un tamaño
} catch (Exception ioe) { mayor del que el que indiquemos, etc.
ioe.getMessage(); El interface FilenameFilter se puede usar para crear filtros que
} establezcan criterios de filtrado relativos al nombre de los ficheros.
Una clase que lo implemente debe definir e implementar el
Para borrar un fichero podemos usar la clase File, comprobando método:
previamente si existe el fichero, del siguiente modo:
boolean accept(File dir, String nombre)
// Borrar fichero
File fichero = new File("c:\\prueba\\miFichero.txt"); Este método devolverá verdadero en el caso de que el fichero cuyo
nombre se indica en el parámetro nombre aparezca en la lista de los
if (fichero.exists ())
ficheros del directorio indicado por el parámetro dir..
fichero.delete();
En el siguiente ejemplo vemos cómo se listan los ficheros de la
carpeta c:\datos que tengan la extensión .txt. Usamos try y catch para
Para crear un directorio, lo realizaremos del siguiente modo: capturar las posibles excepciones, como que no exista dicha
carpeta.
Try {
// Declaración de variables import java.io.File;
import java.io.FilenameFilter;
1.5. Flujos basados en texto o binarios) y dos tipos de acceso a los ficheros (secuencial
o aleatorio). Si bien, y según la literatura que consultemos, a veces
1.6. Operaciones básicas También se puede montar un buffer sobre cualquiera de los flujos
que definen estas clases:
sobre ficheros de acceso BufferedWriterse usa para montar un buffer sobre un flujo
secuencial
de salida de tipo FileWriter.
BufferedReader se usa para montar un buffer sobre un flujo
Como operaciones más comunes en ficheros de acceso secuencial, de entrada de tipo FileReader.
tenemos el acceso para:
// Leer los otros campos En el primer caso se pasa un objeto File como primer parámetro,
apellidos = archivo.readUTF (); mientras que en el segundo caso es un String. El modo es: "r" si se
edad = archivo.readInt (); abre en modo lectura o "rw" si se abre en modo lectura y escritura.
}
A continuación puedes ver una presentación en la que se muestra
// Cerrar fichero
cómo abrir y escribir en un fichero de acceso aleatorio. También,
archivo.close (); en el segundo código descargable, se presenta el código
} correspondiente a la escritura y localización de registros en
catch (FileNotFoundException fne) { / * Archivo no encontrado * / ficheros de acceso aleatorio.
}
catch (IOException ioe) { / * Error al escribir * / } Ejemplo:
Vamos a ver un pequeño ejemplo, Log.java, que añade una cadena conexión abierta, datos recibidos, etc.). Un Selector permite que
a un fichero existente, lo crea en caso de que no exista. un solo hilo maneje múltiples canales.
import java.io.IOException; El estudio de la API NIO completa, excede el modulo, por lo que
import java.io.RandomAccessFile; veremos lo mas básico. Vamos a estudiar en los subcapítulos
siguiente las interfaces Path y Files que son las clases básicas para
public class RandomEjemplo {
acceder a los ficheros.
public static void main( String args[] ) throws IOException {
En la imagen puedes ver las clases de las que se dispone en
RandomAccessFile miRAFile; java.nio.
String s = "linea a añadir al final del fichero";
// Abrimos el fichero de acceso aleatorio
miRAFile = new RandomAccessFile( "java.log","rw" );
// Nos vamos al final del fichero
miRAFile.seek( miRAFile.length() );
// Incorporamos la cadena al fichero
miRAFile.writeBytes( s );
// Cerramos el fichero
miRAFile.close();
}
}
Ejemplo: Esta clase tiene métodos estáticos para el manejo de ficheros, los
métodos de la clase Files trabajan sobre objetos Path.
import java.nio.file.Path;
Las operaciones principales a realizar con archivos y
import java.nio.file.Paths;
directorios son:
import java.io.IOException;
Ejemplo4: copiar directorios
import java.nio.file.FileAlreadyExistsException;
Se puede copiar un archivo o directorio usando el import java.nio.file.Files;
método copy(Path, Path, CopyOption...). La copia falla si el import java.nio.file.Path;
archivo de destino existe, a menos que se especifique la opción import java.nio.file.Paths;
REPLACE_EXISTING.
import java.nio.file.StandardCopyOption;
Se puede copiar directorios Aunque, los archivos dentro del public class FileEjemplo7 {
directorio no se copian, por lo que el nuevo directorio está vacío public static void main(String args[]) {
incluso cuando el directorio original contiene archivos.
Path sourcePath = public class FileEjemplo10 {
Paths.get("C:\\Users\\alumno\\FileEjamplo\\hola.txt"); public static void main(String args[]) {
Path destinationPath = Path inputFile =
Paths.get("C:\\Users\\alumno\\FileEjamplo\\destino\\OtroNombre.t Paths.get("C:\\Users\\alumno\\FileEjamplo\\origen\\hola.txt");
xt"); Path outputFile =
try { Paths.get("C:\\Users\\alumno\\FileEjamplo\\destino\\hola.txt");
Files.move(sourcePath, destinationPath, try {
StandardCopyOption.REPLACE_EXISTING); byte[] contents = Files.readAllBytes(inputFile);
} catch (FileAlreadyExistsException e) { Files.write(outputFile, contents,
System.out.println("el destino existe"); StandardOpenOption.WRITE,
} catch (IOException e) { StandardOpenOption.CREATE,
e.printStackTrace(); StandardOpenOption.TRUNCATE_EXISTING);
} } catch (IOException e) {
} System.err.println(" ERROR : " + e);
} System.exit(1);
}
}
5.3. Escribir contenido en }
Escritura desde buffers
un fichero La escritura desde buffers resulta mucho más eficiente que
utilizando arrays de bytes para ficheros grandes.
Modos de acceso, el parámetro OpenOptions.
El siguiente programa Java copia ficheros, accediendo al fichero
A la hora de utilizar un fichero en Java se puede restringir el acceso original una
que tenemos al mismo desde el propio lenguaje, haciendo más vez por línea y escribiendo en el fichero destino una línea cada vez.
estrictos los permisos de acceso que dicho fichero ya tiene en el Utiliza las clases de java.io: BufferedReader y BufferedWriter:
sistema de ficheros.
import java .nio. file. Path;
Por ejemplo, si el usuario tiene permisos de lectura y escritura import java .nio. file. Paths ;
sobre un fichero, un programa Java que solo quiera leerlo puede import java .nio. file. Files ;
abrir el fichero solo en modo lectura, lo que ayudará a evitar bugs import java .io. IOException;
desde el propio lenguaje. import java .nio. charset . Charset ;
A tal efecto, en java se definen una serie de modos de acceso a un import java .io. BufferedReader;
fichero a través del parámetro OpenOptions. La forma más cómoda de import java .io. BufferedWriter;
utilizar este parámetro es a través del enum StandardOpenOptions que import java .nio. file. StandardOpenOption;
puede tomar los siguientes valores (hay más): public class FileEjemplo11 {
// Copy a file
WRITE: habilita la escritura en el fichero
public static void main( String args []) {
APPEND: todo lo escrito al fichero se hará al final del
Path input = Paths .
mismo
get( "C:\\Users\\alumno\\FileEjamplo\\origen\\hola.txt") ;
CREATE_NEW: crea un fichero nuevo y lanza una
Path output = Paths .
excepción si ya existía
get("C:\\Users\\alumno\\FileEjamplo\\destino\\hola.txt") ;
CREATE: crea el fichero si no existe y simplemente lo
try {
abre si ya existía
BufferedReader inputReader = Files .
TRUNCATE_EXISTING: si el fichero existe, y tiene
newBufferedReader(input , Charset .
contenido, se ignora su contenido para sobreescribirlo
defaultCharset());
desde el principio.
BufferedWriter outputWriter = Files .
Los métodos que se muestran en las siguientes ejemplos utilizan newBufferedWriter(output , Charset .
este parámetro, en la descripción de cada método en el API se defaultCharset() , StandardOpenOption. WRITE ,
explica cual es el comportamiento por defecto en caso de no StandardOpenOption.
utilizarse este parámetro. CREATE , StandardOpenOption.
TRUNCATE_EXISTING);
Escritura desde arrays de bytes String line;
La escritura a ficheros mediante arrays es la forma más sencilla (y while ( ( line = inputReader. readLine ()) != null ) {
limitada) de escritura de ficheros, y se realiza mediante el outputWriter. write (line , 0, line. length ());
método java.nio.file.Files.write(). outputWriter. newLine () ;
}
import java.io.IOException;
inputReader. close ();
import java.nio.file.Files;
outputWriter. close ();
import java.nio.file.Path;
} catch ( IOException e) {
import java.nio.file.Paths;
System .err. println (" ERROR : " + e);
import java.nio.file.StandardOpenOption;
System . exit (1);
} representando la información obtenida de los documentos XML en
} un programa en formato Java, o sea, proporciona a los
desarrolladores de aplicaciones Java, una forma rápida para
}
vincular esquemas XML a representaciones Java.
6.Trabajo con ficheros obtener árboles de contenido (generados en código Java), para
después operar con ellos o manipular los los mismos en una
aplicación Java y generar documentos XML con la estructura de
XML: analizadores los iniciales, pero ya modificados.
El metalenguaje XML se crea para evitar problemas de >Binding runtime framework: proporciona operaciones de
interoperabilidad entre plataformas y redes. Con él se consigue un unmarshalling y marshalling para acceder, manipular y validar
soporte estándar para el intercambio de datos: no sólo los datos contenido XML usando un esquema derivado o elementos de
están en un formato estándar sino también la forma de acceder a programa.
ellos. Y entre las ventajas de su uso destacamos:
Marshalling: es un proceso de codificación de un objeto en un
Facilita el intercambio de información entre distintas medio de almacenamiento, normalmente un fichero. Proporciona a
aplicaciones ya que se basa en estándares aceptados. una aplicación cliente la capacidad para convertir un árbol de
Proporciona una visión estructurada de la objetos Java JAXB a ficheros XML. Por defecto, el marshaller usa
información, lo que permite su posterior tratamiento de codificación UTF-8 cuando genera los datos XML.
forma local.
Unmarshalling: proporciona a una aplicación cliente la capacidad
de convertir datos XML a objetos Java JAXB derivados.
1.8. Conceptos previos
¿Cómo se trabaja con datos XML desde el punto de vista del
desarrollador de aplicaciones?
El proceso anterior se enmarca en lo que se conoce en informática Los documentos XML consiguen estructurar la información
como "parsing" o análisis léxico-sintáctico, y los programas que intercalando una serie de marcas denominadas etiquetas. En XML ,
lo llevan a cabo se denominan "parsers" o analizadores (léxico- las marcas o etiquetas tienen cierta similitud con un contenedor de
sintácticos). Más específicamente podemos decir que el "parsing información. Así, una etiqueta puede contener otras etiquetas o
XML" es el proceso mediante el cual se lee y se analiza un información textual. De este modo, conseguiremos subdividir la
documento XML para comprobar que está bien formado para, información estructurando de forma que pueda ser fácilmente
posteriormente, pasar el contenido de ese documento a una interpretada.
aplicación cliente que necesite consumir dicha información.
Como toda la información es textual, no existe el problema de
Schema: Un esquema (o schema) es una especificación XML que representar los datos de diferente manera. Cualquier dato, ya sea
dicta los componentes permitidos de un documento XML y las numérica o booleana, habrá transcribirla en modo texto, de modo
relaciones entre los componentes. Por ejemplo, un esquema que cualquiera que sea el sistema de representación de datos será
identifica los elementos que pueden aparecer en un documento posible leer e interpretar correctamente la información contenida en
XML, en qué orden deben aparecer, qué atributos pueden tener, y un archivo XML.
qué elementos son subordinados (esto es, son elementos hijos) para
Es cierto que los caracteres se pueden escribir usando también
otros elementos. Un documento XML no tiene por qué tener un
diferentes sistemas de codificación, pero XML ofrece diversas
esquema, pero si lo tiene, debe atenerse a ese esquema para ser un
técnicas para evitar que esto sea un problema. Por ejemplo, es
documento XML válido.
posible incluir en la cabecera del archivo que codificación se ha
utilizado durante el almacenamiento, o también se pueden escribir
1.9. Definiciones los caracteres de código ASCII superior a 127, utilizando entities
¿Qué es y para qué sirve JAXB (Java Architecture for XML de carácter , una forma universal de codificar cualquier símbolo .
Binding)? JAXB simplifica el acceso a documentos XML
XML consigue estructurar cualquier tipo de información Los analizadores secuenciales, que permiten extraer el contenido a
jerárquica. Se puede establecer cierta similitud con la forma como medida que se van descubriendo las etiquetas de apertura y cierre,
la información se almacena en los objetos de una aplicación y la se denominan analizadores sintácticos. Son analizadores muy
forma como se almacenaría en un documento XML . La rápidos, pero presentan el problema de que cada vez que se
información, en las aplicaciones orientadas a objeto, estructura, necesita acceder a una parte del contenido necesario releer todo el
agrupa y jerarquiza en clases, y en los documentos XML se documento de arriba a abajo.
estructura, organiza y jerarquiza en etiquetas contenidas unas
dentro de otras y atributos de las etiquetas En Java hay dos analizadores secuenciales: SAX, que es el
acrónimo de Simple API for XML . Es una analizador muy usado
en varias bibliotecas de tratamiento de datos XML , pero no suele
usarse en aplicaciones finales y STAX, Streaming API for XML,
Analizador XML posterior a SAX y que lo ha superado.
Dado que XML es un lenguaje utilizado ámpliamente en el Analizadores jerárquicos
desarrollo de la World Wide Web, existen ya herramientas y
estándares de programación para leer documentos XML. Las Generalmente, las aplicaciones finales que necesitan trabajar con
herramientas o programas que leen el lenguaje XML y comprueban datos XML suelen usar analizadores jerárquicos, porque además de
si el documento es válido sintácticamente, se denominan realizar un análisis secuencial que les permite clasificar el
analizadores o "parsers". contenido, se almacenan en la memoria RAM siguiendo la
estructura jerárquica detectada en el documento. Esto facilita
Un parser XML es un módulo, biblioteca o programa que se ocupa mucho las consultas que haya que repetir varias veces, dado que las
de analizar, clasificar y transformar un archivo de XML en una estructuras jerárquicas de la memoria RAM tienen un rendimiento
representación interna, extrayendo la información contenida en de acceso parcial a los datos muy eficiente.
cada una de las etiquetas y relacionándola de acuerdo con su
posición en la jerarquía.
En el caso de XML, como el formato siempre es el mismo, no Los analizadores jerárquicos guardan todos los datos del XML en
necesitamos crear un parser cada vez que hacemos un programa, memoria dentro de una estructura jerárquica. Son ideales para
sino que existen un gran número de parsers o analizadores aplicaciones que requieran una consulta continua de los datos. El
sintácticos disponibles que pueden averiguar si un documento formato de la estructura donde se almacena la información en la
XML cumple con una determinada gramática. Estos analizadores o memoria RAM ha sido especificado por el organismo internacional
parsers pueden ser secuenciales como SAX o STAX o jerarquicos W3C (World Wide Web Consortium) y se suele conocer como
como DOM. DOM (Document Object Model). Es una estructura que HTML y
javascript han popularizado mucho y se trata de una especificación
Analizadores secuenciales que Java materializa en forma de interfaces. La principal se
denomina Documento y representa todo un documento XML . Al
tratarse de una interfaz, puede ser implementada por varias clases.
Comparativa analizadores
CARACTERÍSTICA STAX SAX DOM TRAX
Tipo de API Pull, streaming Push, streaming En memoria Regla XSLT
Facilidad de uso Alta Media Alta Media
Capacidad XPath No No Si Si
Eficiencia de CPU y memoria Buena Buena Varia Varia
Solo hacia adelante Si Si No No
Lee XML Si Si Si Si
Escribe XML Si No Si Si
Crear, Leer, Modificar, Borrar No No Si No
Element raiz = document.getDocumentElement(); La lectura de un documento XML produce eventos los cuales
invocan a métodos, los eventos son: inicio y fin de un archivo
y a partir de el añadiendo otros elementos, los métodos:
XML(startDocument() y endDocument()), inicio y fin de un elemento
(startElement() y endElement()) y la información que llevan las diferentes
createElement(String tagName) //crea el elemento del tipo
etiquetas (characters()).
especificado
createTextNode(String data)//crea un Textnode dando valor SAX genera un objeto procesador de XML llamado XMLReader,
(Node newChild) para después decir que objetos tienen métodos para transferir los
appendChild(Node newChild) eventos. Estos objetos implementan los siguientes interfaces:
//añade un nodo hijo al final de de la lista de nodos hijos del
nodo3.- Creación e instalación Transformer. ContentHandler, el cual recibe las notificaciones de los
eventos del fichero XML.
DTDHandler, que recoge los eventos del DTD del fichero.
<span>Transformer trans = ErrorHandler, crea el tratamiento de errores.
TransformerFactory.newInstance .newTransformer ;< EntityResolver, se utilizan siempre que se referencia a otra
br></span><span id="yui_3_17_2_1_1596016483417_136"> entidad.
// Creación de los adaptadores Source y Results a partir de un DefaultHandler, la cual implementa por defecto los métodos,
Documento siendo el programador quien los defina. Con esta clase se
<br></span><span> podrá crear el parser XML. Se compone de los siguientes
// y un File.<br></span><span>StreamResult result = new eventos básicos:
StreamResult ( file ) ; o startDocument: se llama cuando se detecta que el
<br></span><span>DOMSource source = new DOMSource ( doc ) documento empieza. Aquí deben indicarse las
;<br></span> acciones a realizar al inicio del documento.
<span>trans. transform ( source, result ) ;</span> o endDocument: se llama cuando se detecta que el
documento ha acabado. Por lo tanto, aquí
deben indicarse las acciones a realizar al
import java.io.FileInputStream;
import java.io.FileNotFoundException;
6.4. Binding
import java.io.InputStream; El Binding es una técnica que consiste en vincular clases Java con
import java.util.Iterator; formatos específicos de almacenamiento de manera automatizada.
import javax.xml.namespace.QName;
El Binding es una técnica que consiste en vincular clases Java
import javax.xml.stream.XMLEventReader; con formatos específicos de almacenamiento de manera
import javax.xml.stream.XMLInputFactory; automatizada.
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException; En Java existen varias bibliotecas para gestionar el binding , como
por ejemplo JAXB , JiBX , XMLBinding , etc. Desde la versión 6.0
import javax.xml.stream.events.Attribute;
se ha incorporado en el JDK estándar JAXB, una potente biblioteca.
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent; Java Architecture for XML Binding (JAXB) permite a los
public class EventReader { desarrolladores Java asignar clases de Java a representaciones
public static void main(String[] args) { XML. JAXB proporciona dos características principales: la
capacidad de serializar las referencias de objetos Java a XML y la
// primero crea un nuevo XMLInputFactory
inversa, es decir, deserializar XML en objetos Java. En otras
palabras, JAXB permite almacenar y recuperar datos en memoria
en cualquier formato XML, sin la necesidad de implementar un <ListaLibro>
conjunto específico de rutinas de carga y guardado de XML para la <Libro>
estructura de clases del programa. <autor>XXXXXXX</autor>
La siguiente figura muestra lo que ocurre durante el proceso de <nombre>XXXXXXX</nombre>
enlace de JAXB. <editorial>XXXXXXX</editorial>
<isbn>XXXXXXX</isbn>
</Libro>
......
</ListaLibro>
....
<lugar>XXXXXXX</lugar>
<nombre>XXXXXX</nombre>
</libreria>
Para mapear la raiz es necesario una clase librería con anotación
@XmlRootElement.
6.4.1. Configuración con
anotaciones @XmlRootElement
Las Anotaciones pueden asociarse a un paquete, a una clase, a
un atributo o incluso a un parámetro. Estas clases especiales se public class Libreria {
declaran en el código de la aplicación anteponiendo el símbolo .....
@ en el nombre de la Anotación. }
Esta clase tiene un atributo por cada etiqueta del XML incluido
Las Anotaciones pueden asociarse a un paquete, a una clase, a ListaLibro que es un array de elementos de tipo Libro:
un atributo o incluso a un parámetro. Estas clases especiales se
declaran en el código de la aplicación anteponiendo el símbolo @XmlElementWrapper(name = "ListaLibro")
@ en el nombre de la Anotación . Cuando el compilador de Java @XmlElement(name = "Libro")
detecta una Anotación crea una instancia y la inyecta en el
private ArrayList<Libro> ListaLibro;
elemento estructural afectado (paquete, clase, método, atributo,
etc.). Esto hace que éstas no aparezcan como atributos o métodos
propios del objeto, y por eso decimos que no interacciona con el
modelo de datos, pero las aplicaciones que lo necesiten pueden
obtener la instancia inyectada y usarla.
Unmarshall. }
Una vez que tenemos el proyecto con las clases del apartado
Ejemplo anotaciones, vamos a añadir el siguiente programa
6,7,5, Generación automática de
import java.io.File;
import java.io.FileReader; clases Java a partir del esquema
import java.io.IOException;
import java.util.ArrayList;
.xsd.
AXB es una parte de la plataforma Java SE y una de las APIs de la
import javax.xml.bind.JAXBContext;
plataforma Java EE, y es parte del Java Web Services Development
import javax.xml.bind.JAXBException; Pack (JWSDP). También es uno de los fundamentos para WSIT.
import javax.xml.bind.Marshaller; JAXB es parte de la versión 1.6 SE.
import javax.xml.bind.Unmarshaller;
JAXB es una parte de la plataforma Java SE y una de las APIs de
public class JavaJAXB {
la plataforma Java EE, y es parte del Java Web Services
private static final String LIBRERIA_XML = "./libreria-
Development Pack (JWSDP). También es uno de los fundamentos
jaxb.xml";
para WSIT. JAXB es parte de la versión 1.6 SE.
public static void main(String[] args) throws JAXBException,
IOException { La herramienta "xjc" se puede utilizar para convertir un XML
// Lista de LIbros Schema y otros tipos de archivo de esquemas (en Java 1.6, RELAX
ArrayList<Libro> libroLista = new ArrayList<Libro>(); NG, XML DTD y WSDL son compatibles experimentalmente) a
// Creamos varios libros representaciones de clase. Las clases son marcadas usando
anotaciones del espacio de nombres javax.xml.bind.annotation.*, por
Libro libro1 = new Libro();
ejemplo, @XmlRootElement y @XmlElement. Las secuencias de listas
libro1.setIsbn("978-0060554736"); XML se representan con atributos de tipo java.util.List.
Los serializadores y deserializadores se crean a través de una
instancia de JAXBContext. Byte
xsd:string java.lang.String
javax.xml.datatype.XMLGre
xsd:g
gorianCalendar
xsd:positiveI
java.math.BigInteger
nteger
xsd:anySimp
leType (for
java.lang.Object
xsd:element
xsd:int int
of this type)
xsd:long long
xsd:anySimp
leType (for
java.lang.String
xsd:short short xsd:attribute
of this type)
xsd:decimal java.math.BigDecimal
xsd:duration javax.xml.datatype.Duration
xsd:float float
xsd:NOTAT
javax.xml.namespace.QName
ION
xsd:double double
xsd:boolean boolean Los pasos para obtener las clases IDE Eclipse
1. Descargar la distribución:
xsd:byte byte Download standalone distribution, descomprimimos el
fichero.
2. Añadir todas las clases que estan en la carpeta \jaxb-ri-
xsd:QName javax.xml.namespace.QName 2.3.0\jaxb-ri\lib, jaxb-api.jar, jaxb-core.jar, jaxb-
impl.jar, jaxb-jxc.jar, jaxb-xjc.jar
3. Obtener el esquema .xsd a partir del XML.
xsd:dateTim javax.xml.datatype.XMLGre 4. Crear un proyecto en Eclipse, en la carpeta scr del
e gorianCalendar proyecto situar el esquema y en la carpeta raíz del
proyecto situamos el fichero XML .Para generar las
clases de forma automática clicamos el botón derecho del
xsd:base64Bi ratón sobre el esquema, generate -> JAXB Classes.
byte[]
nary
xsd:hexBina
byte[]
7.Librerías para
ry
xsd:unsigned
Int
long conversión de
xsd:unsigned
documentos XML a
int
Short
otros formatos
xsd:unsigned short En la mayoría de las aplicaciones informáticas, hay que mostrar la
información resultante de los procesos que se ejecutan, sobre todo
en aplicaciones que generan información que implica tomar
decisiones comerciales. Dicha información está almacenada
normalmente en bases de datos o en archivos.
Paso 4: Visualización
Una base de datos relacional se puede definir, de una manera Ser un API con soporte de SQL: poder construir
simple, como aquella que presenta la información en tablas con sentencias SQL e insertarlas dentro de llamadas al API
filas y columnas. de Java.
Aprovechar la experiencia de los API's de bases de
Una tabla o relación es una colección de objetos del mismo tipo
datos existentes.
(filas o tuplas).
Ser lo más sencillo posible.
En cada tabla de una base de datos se elige una clave primaria para
identificar de manera unívoca a cada fila de esta.
1.1. El desfase objeto- 2. Protocolos de acceso
relacional a bases de datos
Inicialmente, cada empresa desarrolladora de un SGBD
implementaba soluciones propietarias específicas para su
sistema, pero pronto se dieron cuenta de que colaborando
conjuntamente podían sacar mayor rendimiento y avanzar
mucho más rápidamente.
/*Añadir imagen
/*Añadir imagen
4.Creación de la base
3.2. Pool de conexiones (I) de datos
Acabamos de ver cómo se realiza una conexión a una base de Juan le explica a Antonio, que una base de datos puede crearse
datos. En ocasiones, sobre todo cuando se trabaja en el ámbito de utilizando las herramientas proporcionadas por el fabricante de la
las aplicaciones distribuidas, en entornos web, es recomendable base de datos, o por medio de sentencias SQL desde un programa
gestionar las conexiones de otro modo. Java. Pero normalmente es el administrador de la base de datos, a
través de las herramientas que proporcionan el sistema gestor, el
La explicación es que: abrir una conexión, realizar las operaciones que creará la base de datos. No todos los conectores JDBC
necesarias con la base de datos, y cerrar la conexión; puede ser soportan la creación de la base de datos mediante el lenguaje de
lento en entornos web si lo hacemos como hemos visto. definición de datos (DDL). Es decir, la sentencia CREATE
DATABASE no es parte del estándar SQL, sino que es dependiente
En las aplicaciones en las que es necesario el acceso concurrente y
masivo a una base de datos, como es el caso de las aplicaciones del sistema gestor de la base de datos.
web, es necesario disponer de varias conexiones. El proceso de Así pues, mediante JDBC podemos conectarnos y manipular bases
creación y destrucción de una conexión a una base de datos es de datos: crear tablas, modificarlas, borrarlas, añadir datos en las
costoso e influye sensiblemente en el rendimiento de una tablas, etc. Pero la creación en sí de la base de datos la hacemos
aplicación. Es mejor en estos casos, por tanto, abrir una o más con la herramienta específica para ello.
conexiones y mantenerlas abiertas.
Normalmente, cualquier sistema gestor de bases de datos incluye
La versión 3 y 4 de JDBC proporcionan un pool de conexiones que asistentes gráficos para crear la base de datos, sus tablas, claves, y
funciona de forma transparente. todo lo necesario.
Al iniciar un servidor JavaEE, automáticamente el pool de También, como en el caso de MySQL, o de Oracle, y la mayoría de
conexiones crea un número de conexiones físicas iniciales. los sistemas gestores de bases de datos, se puede crear la base de
Cuando un objeto Java del servidor J2EE necesita una conexión a datos, desde la línea de comandos de MySQL o de Oracle, con las
través del método dataSource.getConnection(), la fuente de datos sentencias SQL apropiadas.
javax.sql.DataSource habla con el pool de conexiones y éste le entrega
Veamos cómo crear paso a paso una base de datos con Microsoft
una conexión lógica java.sql.Connection. Esta conexión lógica la Access. Si no dispones de Microsoft Access, no te preocupes, más
recibe, por último, el objeto Java. abajo puedes descargar la base de datos ya creada.
Cuando un objeto Java del servidor Java EE desea cerrar una /*Añadir imagen
conexión a través del método connection.close(), la fuente de datos
javax.sql.DataSource habla con el pool de conexiones y le devuelve la
conexión lógica en cuestión.
Consultas: SELECT
Actualizaciones: INSERT, UPDATE, DELETE, sentencias
DDL. 5.1.1. Ejemplo: consultas con
Veamos a continuación cómo realizar una consulta en la base de
datos que creamos en el apartado anterior, la base de datos
MS-Access (II)
Las consultas que se realizan a una base de datos se realizan
farmacia.mdb.
utilizando objetos de las clases Statement y PreparedStatement. Estos
En este caso utilizaremos un acceso mediante puente JDBC- objetos se crean a partir de una conexión.
ODBC. Dicho puente da acceso a bases de datos ODBC.
Statement stmt = con.createStatement();
Este driver está incorporado dentro de la distribución de Java, por
lo que no es necesario incorporarlo explícitamente en el classpath La clase Statement contiene los métodos executeQuery y executeUpdate
de una aplicación Java. para realizar consultas y actualizaciones, respectivamente. Ambos
métodos soportan consultas en SQL-92. Así por ejemplo, para
obtener los nombres de los medicamentos que tenemos en la tabla
medicamentos, de la base de datos farmacia.mdb que creamos
5.1. Ejemplo: consultas con anteriormente, tendríamos que emplear la sentencia:
Class.forName("jdbc:odbc:admdb");
Posteriormente, una vez instalado el conector y cargado dentro del 5.2. Consultas preparadas
código Java sólo necesitamos realizar la conexión a la base de Las consultas preparadas están representadas por la clase
datos para comenzar a trabajar con ella. La clase DriverManager PreparedStatement.
define el método getConnection para crear una conexión a una base de
datos. Este método toma como parámetro una URL JDBC donde se Son consultas precompiladas, por lo que son más eficientes, y
indica el sistema gestor y la base de datos. Opcionalmente, y pueden tener parámetros.
dependiendo del sistema gestor, habrá que especificar el login y
Una consulta se instancia del modo que vemos con un ejemplo:
password para la conexión. En el caso de JDBC-ODBC la cadena
de conexión sería: jdbc:odbc:admdb, en la que no es necesario PreparedStatement pstmt = con.preparedStatement("SELECT *
establecer el protocolo. Finalmente, el código para establecer una from medicamentos");
conexión quedaría del siguiente modo:
Para las consultas que se realizan muy a menudo es aconsejable
Connection con = usar este tipo de consultas, de modo que el rendimiento del sistema
DriverManager.getConnection("jdbc:odbc:admdb"); será mejor de esta manera.
Ahora ya podemos realizar las consultas que deseemos. Si hay que emplear parámetros en una consulta, se puede hacer
usando el carácter ‘?’. Por ejemplo, para realizar una consulta de
un medicamento que tenga un código determinado, haríamos la
consulta siguiente: almacenados en
PreparedStatement pstmt = con.preparedStatement("SELECT *
from medicamentos WHERE codigo = ? ");
MySQL
A continuación, vamos a realizar un procedimiento almacenado en
MySQL, que simplemente insertará datos en la tabla clientes.
Establecemos los parámetros de una consulta utilizando métodos
Desde el programa Java que realizamos, llamaremos para ejecutar a
set que dependen del tipo SQL de la columna.
ese procedimiento almacenado. Por tanto, ¿cuál sería la secuencia
Así, le decimos que el primer parámetro, que es el único que tiene que seguiríamos para realizar esto?
esta consulta, es “712786”:
Si no tenemos creada la tabla de clientes, la creamos. Por
pstmt.setString(1, "712786"); simplicidad, en este ejemplo, trabajamos sobre la base de
datos que viene por defecto en MySQL, el esquema
El primer argumento de este método es la posición del parámetro denominado: test. Para crear la tabla de clientes, el script
dentro de la consulta. correspondiente es:
/*Añadir imagen
Finalmente, ejecutamos la consulta utilizando el método Creamos el procedimiento almacenado en la base de
executeQuery()o executeUpdate(), ambos sin parámetros, dependiendo datos. Sería tan fácil como:
del tipo de consulta. /*Añadir imagen
Crear la clase Java para desde aquí, llamar al
procedimiento almacenado:
/*Añadir imagen
6. Ejecución de Si hemos definido la tabla correctamente, con su clave primaria, y
ejecutamos el programa, intentando insertar una fila igual que otra
procedimientos insertada, o sea, con la misma clave primaria, obtendremos un
mensaje al capturar la excepción de este tipo:
almacenados en la SQL Exception:
Las acciones que se realizan sobre una base de datos pueden lanzar
la excepción SQLException. Este tipo de excepción proporciona entre
otra información:
El mapeo objeto-relacional (ORM) soluciona este problema. Es En el modelo relacional, cada fila en la tabla se mapea a un objeto
una técnica de programación que se utiliza con el propósito de y cada columna a una propiedad.
convertir datos entre el utilizado en un lenguaje de programación
orientado a objetos y el utilizado en una base de datos relacional, Las herramientas ORM pues, actúan como un puente que conecta
gracias a la persistencia. Esto posibilita el uso en las bases de datos las ventajas de los RDBMS con la buena representación de estos en
relacionales de las características propias de la programación un lenguaje Orientado a Objetos, o, dicho en otras palabras, nos
orientada a objetos (básicamente herencia y polimorfismo). lleva de la base de datos al lenguaje de programación.
La mayoría de las aplicaciones se construyen usando técnicas de En el siguiente documento podrás ver un adelanto de los siguientes
programación orientada a objetos; sin embargo, los sistemas de puntos de la unidad:
bases de datos más extendidos son de tipo relacional.
/* Añadir imagen
Las bases de datos más extendidas son del tipo relacional y estas
sólo permiten guardar tipos de datos primitivos (enteros, cadenas
de texto, etc.) por lo que no se puede guardar de forma directa los
objetos de la aplicación en las tablas. Por tanto, se debe convertir
los valores de los objetos en valores simples que puedan ser
2.1. Características
Las herramientas ORM facilitan el mapeo de atributos entre una
almacenados en una base de datos (y poder recuperarlos más base de datos relacional y el modelo de objetos de una aplicación,
tarde). mediante archivos declarativos (XML) que permiten establecer
estas relaciones. Gracias a las ORM, podemos conectar con una
El mapeo objeto-relacional surge, pues, para dar respuesta a esta
problemática: traducir los objetos a formas que puedan ser base de datos relacional para extraer la información contenida en
objetos de programas que están almacenados. Para ello, sólo
almacenadas en bases de datos preservando las propiedades de los
objetos y sus relaciones; estos objetos se dice entonces que son tendremos que definir la forma en la que establecer la
correspondencia entre las clases y las tablas una sola vez
persistentes.
(indicando qué propiedad se corresponde con cada columna, qué
/* Añadir imagen clase con cada tabla, etc.). Una vez hecho esto, podremos utilizar
POJO's de nuestra aplicación e indicar a la ORM que los haga
El ORM se encarga, de forma automática, de convertir los objetos persistentes, consiguiendo que una sola herramienta pueda leer o
en registros y viceversa, simulando así tener una base de datos escribir en la base de datos utilizando VO's directamente.
orientada a objetos.
Una herramienta ORM permite tomar un objeto Java y hacerlo
persistente, carga el objeto de la base de datos a memoria y permite
hacer consultas a las tablas de la base de datos.
2. Herramientas ORM. Ventajas de ORM.
Hibernate: 4. Ficheros de
Hibernate es una herramienta de Mapeo objeto-relacional (ORM)
para la plataforma Java (y disponible también para .Net con el configuración y mapeo.
nombre de NHibernate) que facilita el mapeo de atributos entre una
base de datos relacional tradicional y el modelo de objetos de una
aplicación. Utiliza archivos declarativos (XML) o anotaciones en
Estructura y
los beans de las entidades que permiten establecer estas relaciones.
propiedades
Hibernate es software libre, distribuido bajo los términos de la
licencia GNU LGPL Para empezar a trabajar con Hibernate es necesario configurar la
herramienta para que conozca qué objetos debe recuperar de la
Java Persistence Api (JPA): base de datos relacional y en qué lugar los hará persistir. Por tanto,
el primer paso será tener una base de datos relacional con la que
El Java Persistence API (JPA) es una especificación de Sun
poder trabajar.
Microsystems para la persistencia de objetos Java a cualquier base
de datos relacional. Esta API fue desarrollada para la plataforma Debes conocer
JEE e incluida en el estándar de EJB 3.0, formando parte de la Java
Specification Request JSR 220. /* Imágenes
Para su utilización, JPA requiere de J2SE 1.5 (también conocida En NetBeans, cuando se crea el archivo de configuración de
como Java 5) o superior, ya que hace uso intensivo de las nuevas Hibernate usando el asistente, podemos especificar la conexión a la
características de lenguaje Java, como las anotaciones y los base de datos, eligiendo de una lista de conexiones de bases de
genéricos. datos registradas en el IDE. Cuando se genera el archivo de
configuración, el IDE añade de forma automática detalles de la
iBatis: conexión e información basada en la conexión de la base de datos
seleccionada. El IDE añade también las bibliotecas de Hibernate en
iBatis es un framework (marca de trabajo) de persistencia
el proyecto. Después de crear el fichero de configuración, éste
desarrollado por la Apache software Foundation. Al igual que que
puede ser editado usando el editor interactivo, o editar directamente
el resto de los proyectos desarrollados por la ASF, iBatis es una
el código XML.
herramienta de código libre y de código abierto.
El fichero de configuración contiene información sobre la base de
iBatis sigue el mismo esquema de uso que Hibernate; se apoya en
datos a la que vamos a conectar la aplicación. Si la aplicación se va
ficheros de mapeo XML para persistir la información contenida en
a conectar a varias bases de datos, sería necesario definir tantos
los objetos en un repositorio relacional.
archivos de configuración como bases de datos a las que nos Hibernate.show_sql.Para mostrar la herramienta. Por
queramos conectar. defecto, su valor es true.
El archivo de configuración de Hibernate es el Hibernate.cfg.xml y Para extraer un tabla concreta de la base de datos, la sintaxis en el
contiene información sobre la conexión de base de datos, las mapeo requiere definir el POJO Nombre_Clase.hbm.xml, donde
asignaciones de recursos y otras propiedades de conexión. nombre_clase se corresponderá con el nombre la tabla que
queremos extraer y donde se describe cómo se relacionan clases y
tablas y propiedades y columnas.
Debes conocer Mediante el asistente de NetBeans, seleccionamos Nuevo Mapeo
Resumen en Hibernate y rellenamos los campos que nos piden, en función de
la información que nos interese extraer de la base de datos.
Hibernate.dialect:
ejemplo, MySQL.
Dialecto o lenguaje empleado. Por 5.Mapeo de colecciones,
Hibernate.connection.driver_class . Driver utilizado para la
conexión con la base de datos. relaciones y herencia
Hibernate.connection.url. Dirección de la base de datos con la
que se va a conectar Hibernate. 1. Mapeo de colecciones.
Hibernate.connection.username. Nombre del usuario que va a
Hay bastantes rangos de mapeos que se pueden generar para
realizar la extracción de información. Por defecto, el
colecciones que cubran diversos modelos relacionales.
nombre de usuario es root.
Hibernate.connection.password . Contraseña el root. El elemento de mapeo de Hibernate utilizado para mapear una
colección depende del tipo de la interfaz; por ejemplo, un elemento
se utiliza para mapear propiedades de tipo Set aunque, no obstante, JDO permite a los programadores convertir sus clases en
existen además los elementos de mapeo etc. persistentes, de forma que los objetos pertenecientes a clases
concretas definidas por el programador pueden mantener su
Las instancias de colección de distinguen por la clave foránea de la estado, con la única limitación de que el estado esté compuesto por
entidad que posee la colección. El elemento mapea la columna los atributos persistentes que sean independientes del contexto de
clave de la colección. ejecución: tipos primitivos, tipos de referencia e interfaz y algunas
clases del sistema que permiten modelar el estado como por
Hay que resaltar que las colecciones pueden contener casi
ejemplo la clase Array, Date, etc.
cualquier tipo de datos; esto implica que un objeto en una
colección puede ser manejado con una semántica de "valor" o Para poder indicar las clases y atributos que son persistentes, se
podría ser una referencia a otra entidad, con su propio ciclo de utiliza un fichero de configuración XML, que se denomina
vida. Todos los mapeos de colección necesitan una columna índice descriptor de persistencia. Para que las instancias de las clases
en la tabla de colección: una columna índice es una columna que persistentes pueden mantenerse en los sistemas gestores de bases
mapea a un índice de array o índice de List. Por último, una de datos, es necesario establecer la correspondencia entre los
colección de valores o asociación muchos-a-muchos requiere una objetos y su estado persistente.
tabla de colección dedicada con una columna o columnas de clave
foránea, columna de elemento de colección y probablemente una o
varias columnas índice.
6.Clases persistentes Los estados en los que se puede encontrar un objetos son:
Para cargar un objeto de acceso a datos en la aplicación Java, el Para borrar objetos persistentes, podemos ejecutar Session.delete(), que
método load() de la clase Session suministra un mecanismo para quitará el estado de un objeto de la base de datos. Por supuesto, su
capturar una instancia persistente, si conocemos su identificador. El aplicación podría aún contener una referencia al objeto quitado. Se
método load() acepta un objeto Class, y cargará el estado de una puede borrar objetos en cualquier orden, no se van a producir
nueva instancia de esa clase, inicializada en estado persistente. violaciones de llave externa, pero sí es posible violar constraints NOT
NULL aplicadas a la columna de llave externa.
El método load() lanzará una excepción irrecuperable si no existe la
fila de base de datos correspondiente. Si no se está seguro de que Muchas aplicaciones necesitan capturar un objeto en una
exista una fila correspondiente, debe usarse el método get(), el cual transacción, mandarlo a la capa de interfaz de usuario para su
consulta la base de datos inmediatamente y devuelve null si no manipulación, y grabar sus cambios en una nueva transacción. Las
existe una fila correspondiente aplicaciones que usan este tipo de estrategia en entornos de alta
concurrencia, normalmente usan datos versionados para garantizar
Existen dos métodos que se encargan de recuperar un objeto aislamiento durante la "larga" unidad de trabajo.
persistente por identificador: load() y get(). La diferencia entre ellos
radica en cómo indican que un objeto no se encuentra en la base de Hibernate soporta este modelo, proveyendo "reasociación" de
datos: get() devuelve un nulo y load() lanza una excepción entidades desprendidas usando los métodos Session.update() o
ObjectNotFoundException . Session.merge().
Hibernate utiliza un lenguaje de consulta potente (HQL) que se Esto retorna instancias de Alumnos llamados "Francisco".
parece a SQL. Sin embargo, comparado con SQL, HQL es
completamente orientado a objetos y comprende nociones como Funciones de agregación. Las consultas HQL pueden retornar
herencia, polimorfismo y asociación. Las consultas se escriben en resultados de funciones de agregación sobre propiedades:
HQL y Hibernate se encarga de convertirlas al SQL usado por la
base de datos con la que estemos trabajando y ejecutarla para select avg(alumnos.nota), sum(alumnos.nota), max(alumnos.nota),
realizar la operación indicada. count(alumnos) from Alumnos alumnos.
HQL es case-insensitive, o sea que sus sentencias pueden escribirse Expresiones. Las expresiones utilizadas en la cláusula where
en mayúsculas y minúsculas. Por lo tanto "SeLeCt", "seleCT", incluyen lo siguiente: operadores matemáticos, operadores de
"select", y "SELECT" se entienden como la misma cosa. Lo único comparación binarios, operadores lógicos, paréntesis () que indican
con lo que debemos tener cuidado es con los nombres de las clases agrupación, funciones Java, etc.
que estamos recuperando y con sus propiedades, ahí si se
La cláusula order by. La lista retornada por una consulta se puede
distinguen mayúsculas y minúsculas. O sea, en este caso
ordenar por cualquier propiedad de una clase retornada o
"pruebas.Hibernate.Usuario" NO ES LO MISMO que
componentes. La palabra asc o desc opcionales indican ordenamiento
"PrueBAs.Hibernate.UsuArio".
ascendente o descendente respectivamente.
Entre las características más importantes de HQL.
La cláusula group by. Una consulta que retorna valores agregados
Soporte completo para operaciones relacionales: HQL se puede agrupar por cualquier propiedad de una clase retornada o
permite representar consultas SQL en forma de objetos. componentes:
HQL usa clases y atributos o propiedades en vez de
Subconsultas. Para bases de datos que soportan subconsultas,
tablas y columnas.
Hibernate soporta subconsultas dentro de consultas. Una
Regresa sus resultados en forma de objetos: Las subconsulta se debe encerrar entre paréntesis (frecuentemente por
consultas realizadas usando HQL regresan los resultados una llamada a una función de agregación SQL). Incluso se
de las mismas en la forma de objetos o listas de objetos, permiten subconsultas correlacionadas (subconsultas que se
que son más fáciles de usar. refieren a un alias en la consulta exterior).
Consultas Polimórficas: Podemos declarar el resultado
usando el tipo de la superclase e Hibernate se encargara
de crear los objetos adecuados de las subclases correctas
de forma automática. 12. Gestión de transacciones
Soporte para características avanzadas: HQL contiene Una transacción es un conjunto de órdenes que se ejecutan
muchas características avanzadas que son muy útiles y formando una unidad de trabajo, en forma indivisible o atómica.
que no siempre están presentes en todas las bases de
datos, o no es fácil usarlas, como paginación, fetch joins Para la gestión de transacciones en Hibernate, no se produce
con perfiles dinámicos, inner y outer joins, etc. Además bloqueo de objetos en la memoria. La aplicación puede esperar el
soporta proyecciones, funciones de agregación (max, comportamiento definido por el nivel de aislamiento de sus
avg), y agrupamientos, ordenamientos, y subconsultas. transacciones de las bases de datos. Gracias a la Session, la cual
Independiente del manejador de base de datos: Las también es un caché con alcance de transacción. Para realizar con
consultas escritas en HQL son independientes de la base éxito la gestión de transacciones, éstas se van a basar en el uso del
de datos (siempre que la base de datos soporte la objeto Session.
característica que estamos intentando utilizar)
El objeto Session se obtiene a partir de un objeto SessionFactory,
invocando el método openSession. Un objeto SessionFactory
representa una configuración particular de un conjunto de
10.1. Lenguaje HQL metadatos de mapping objeto/relaciona.
from Alumnos
Gran capacidad de modelado. El modelado de datos Por ser SGBD debe incluir mecanismos para optimizar el
orientado a objetos permite modelar el 'mundo real' de acceso, gestionar el control de concurrencia, la seguridad
una manera óptima gracias al encapsulamiento y la y la gestión de usuarios, así como facilitar la consulta y
herencia. recuperación ante fallos.
Flexibilidad. Permiten una estructura cambiante con solo Por ser OO incorpora características de identidad,
añadir subclases. encapsulación, herencia, polimorfismo y control de tipos.
Soporte para el manejo de objetos complejos.
Cuando aparecieron las bases de datos orientadas a objetos, un
Manipula de forma rápida y ágil objetos complejos, ya
grupo formado por desarrolladores y usuarios de bases de objetos,
que la estructura de la base de datos está dada por
denominado ODMG (Object-Oriented Database Management
referencias (apuntadores lógicos) entre objetos.
Group), propuso un estándar que se conoce como estándar
Alta velocidad de procesamiento. Como el resultado de
ODMG-93 y que se ha ido revisando con el tiempo, pero que en
las consultas son objetos, no hay que reensamblar los
realidad no ha tenido mucho éxito, aunque es un punto de partida.
objetos cada vez que se accede a la base de objetos
Extensibilidad. Se pueden construir nuevos tipos de Debes conocer
datos a partir de los ya existentes, agrupar propiedades
comunes de diversas clases e incluirlas en una /*Añadir resumen
superclase, lo que reduce la redundancia.
Mejora los costes de desarrollo, ya que es posible la ¿Qué estrategias o enfoques se siguen para el desarrollo de
reutilización de código, una de las características de los SGBDOO? Básicamente, las siguientes:
lenguajes de programación orientados a objetos.
Facilitar el control de acceso y concurrencia, puesto Ampliar un lenguaje de programación OO existente con
que se puede bloquear a ciertos objetos, incluso en una capacidades de BD (Ejemplo: GemStone).
jerarquía completa de objetos. Proporcionar bibliotecas de clases con las capacidades
Funcionan de forma eficiente en entornos tradicionales de las bases de datos, como persistencia,
cliente/servidor y arquitecturas distribuidas. transacciones, concurrencia, etc., (Ejemplo: ObjectStore
y Versant).
Pero, aunque los sistemas de bases de datos orientados a objetos Ampliar un lenguaje de BD con capacidades OO, caso de
pueden proporcionar soluciones apropiadas para muchos tipos de SQL 2003 y Object SQL (OQL, propuesto por ODMG).
aplicaciones avanzadas de bases de datos, también tienen sus
desventajas. Éstas son las siguientes: Tal y como estarás pensando, la carencia de un estándar real hace
difícil el soporte para la portabilidad de aplicaciones y su
interoperabilidad, y es en parte por ello, que a diferencia de las
bases de datos relacionales donde hay muchos productos donde Entonces, ¿las referencias de asociación son como las relaciones
elegir, la variedad de sistemas de bases de datos orientadas a del modelo relacional? Así es:
objetos es mucho menor. En la actualidad hay diferentes productos
de este tipo, tanto con licencia libre como propietaria. La referencia de asociación representa las relaciones o
interrelaciones entre objetos independientes, dando la
A continuación, te indicamos algunos ejemplos de SGBOO: posibilidad de que los objetos puedan detectarse
mutuamente en una o dos direcciones, (lo que en el
Db4o de Versant. Es una BDOO Open Source para Java modelo relacional representamos mediante claves ajenas
y .NET. Se distribuye bajo licencia GPL. o foráneas que provienen de relaciones uno a uno, uno a
Matisse. Es un SGBOO basado en la especificación muchos y muchos a muchos).
ODMG, proporciona lenguajes para definición y Una relación uno a muchos se representa mediante un
manipulación de objetos, así como interfaces de objeto tipo colección (List, Set, etc.). En una BDOO la
programación para C, C++, Eiffel y Java. colección se maneja como cualquier otro objeto (aunque
ObjectDB. Es una BDOO que ofrece soporte para Java, potencialmente profundo) y normalmente se podrá
C++, y Python entre otros lenguajes. No es un producto recuperar y almacenar el objeto padre junto con la
libre, aunque ofrecen versiones de prueba durante un colección asociada y su contenido en una sola llamada.
periodo determinado.
EyeDB. Es un SGBOO basado en la especificación Además, un objeto miembro referenciado puede ser referenciado
ODMG, proporciona lenguajes para definición y por más de un objeto estructurado y, no se elimina
manipulación de objetos, e interfaces de programación automáticamente cuando se elimina el objeto del nivel superior.
para C++ y Java. Se distribuye bajo licencia GNU y es
software libre.
Neodatis, ObjectStore y GemStone. Son otros SGBDOO.
3.3. Instalación del gestor de
objetos Db4o
3.2. Objetos simples y /* Añadir imagen
Por ejemplo, si observas la figura superior derecha, en un objeto Una de las ventajas de db4o es que es un simple fichero .jar
tipo Oficina los componentes codigo y dirección son_parte_del distribuible con cualquier aplicación sin necesidad de tener que
objeto, mientras que el componente jefe, es un objeto instalar nada. Tampoco necesita drivers de tipo JDBC o similar.
independiente que está_asociado_con el objeto oficina.
La instalación de db4o consistirá en:
Instalar el motor de base de datos, que son las clases
necesarias para hacer que funcione la API en toda su
extensión.
Instalar alguna aplicación para visualizar los datos con
3.2 Apertura y cierre de
los que se está trabajando. Esto último es necesario, pues
en otro caso se trabajaría a ciegas con los datos.
conexiones
/*Añadir imagen
3.4 Actualización de objetos alto, se almacenarán de forma implícita todos los objetos
hijo.
3.5 Actualización de objetos Es un lenguaje declarativo del tipo de SQL que permite
realizar consultas de modo eficiente sobre bases de datos
estructurados
orientadas a objetos.
Su sintaxis es similar a la de SQL, proporcionando un
/*Añadir imagen
superconjunto de la sintaxis de la sentencia SELECT,
con algunas características añadidas para los conceptos Además, en una consulta OQL se pueden utilizar, entre otros, los
ODMG, como la identidad del objeto, los objetos siguientes operadores y expresiones:
complejos, las operaciones, la herencia, el polimorfismo
y las relaciones. Operadores de acceso: "." / "->" aplicados a un atributo,
No posee primitivas para modificar el estado de los una expresión o una relación. FIRST / LAST (primero /
objetos ya que las modificaciones se pueden realizar último elemento de una lista o un vector).
mediante los métodos que estos poseen. Operadores aritméticos: +, -, *, /, -(unario), MOD, ABS
Puede ser usado como un lenguaje autónomo o para formar expresiones aritméticas.
incrustado dentro de otros lenguajes como C++, Operadores relacionales: >, =, <=, <>, = que permiten
Smalltalk y Java. comparaciones y construir expresiones lógicas.
Una consulta OQL incrustada en uno de estos Operadores lógicos: NOT, AND, OR que permiten enlazar
lenguajes de programación puede devolver objetos que otras expresiones.
coincidan con el sistema de tipos de ese lenguaje.
A continuación, te indicamos de manera resumida, algunas otras
Desde OQL se pueden invocar operaciones escritas en
características, del estándar OQL:
estos lenguajes.
Permite acceso tanto asociativo como navegacional: Definición de vistas, es decir, es posible dar nombre a
o Una consulta asociativa devuelve una una consulta y utilizarlo en otras consultas.
colección de objetos. Extracción de elementos sencillos de colecciones set, bag,
o Una consulta navegacional accede a objetos o list.
individuales y las interrelaciones entre objetos Operadores de colecciones como funciones de
sirven para navegar entre objetos. agregación (MAX(), MIN(), COUNT(), SUM() y AVG()) y
cuantificadores (FOR ALL, EXISTS).
Realización de agrupaciones mediante GROUP BY y filtro
de los grupos mediante HAVING.
5.1 Sintaxis, expresiones y Combinación de consultas mediante JOINs
Unión, intersección y resta de colecciones mediante los
operadores operadores UNION, INTERSEC y EXCEPT.
La sintaxis básica y resumida de una sentencia SELECT del OQL
En los siguientes apartados nos centraremos en el OQL concreto de
estándar es la siguiente:
un SGBDOO y que por supuesto, incorpora sus propias
/*Añadir imagen particularidades y diferencias respecto a la propuesta OQL de
ODMG.
SELECT [DISTINCT <expresión, ...>]
FROM <lista from>
[WHERE <condición>]
[ORDER BY <expresión>] 5.2 Matisse, un gestor de
Por ejemplo, suponiendo el esquema de base de objetos que puedes objetos que incorpora
ver en la figura ampliable de la derecha, la siguiente sentencia
select recupera de la base de objetos los atributos nombre y el OQL
correo de objetos tipo profesor cuyo año de ingreso es anterior al Para practicar y trabajar con OQL utilizaremos Matisse, un gestor
1990, y ordenados alfabéticamente por nombre: orientado a objetos que incorpora características del estándar
ODMG, como los lenguajes ODL y OQL, y que tiene soporte para
SELECT p.nombre, p.email FROM p in Profesor WHERE Java. Aunque Matisse llama SQL a su lenguaje de consultas,
p.ingreso <= 1990 ORDER BY p.nombre; nosotros nos referiremos a él como OQL.
Las siguientes, son algunas consideraciones a tener en cuenta: El propio gestor proporciona el driver matisse.jar para interactuar
con aplicaciones escritas en Java.
En las consultas se necesita un punto de entrada, que
suele ser el nombre de una clase. Dentro de los paquetes del API destacamos:
El resultado de una consulta es una colección que puede
ser tipo bag (si hay valores repetidos) o tipo set (no hay com.matisse. Proporciona las clases e interfaces básicos
valores repetidos). En este último caso habrá que para trabajar con Java y una base de datos de objetos
especificar SELECT DISTINCT. Matisse.
En general, una consulta OQL puede devolver un MtDatabase. Clase que proporciona todos los métodos para
resultado con una estructura compleja especificada en la realizar las conexiones y transacciones en la base de
misma consulta utilizando struct. objetos.
Una vez que se establece un punto de entrada, se pueden com.matisse.sql. Proporciona clases que permiten interactuar
utilizar expresiones de caminos para especificar un con la base de objetos vía JDBC.
camino a atributos y objetos relacionados. Una expresión
Todas las interacciones entre una aplicación Java y la base de
de camino empieza normalmente con un nombre de
objetos Matisse se realizan en el contexto de una transacción
objeto persistente o una variable iterador, seguida de
(implícita o explícita).
ninguno o varios nombres de relaciones o de atributos
conectados mediante un punto.
Es posible crear objetos mutables (no literales) formados
por el resultado de una consulta.
En el siguiente recurso didáctico encontrarás diferentes ejemplos
5.3 Ejecución de Sentencias de consultas utilizando de forma autónoma o conversacional el
lenguaje OQL de Matisse.
OQL /*Añadir imagen
La sintaxis básica del OQL de Matisse es una sentencia SELECT de
la forma: SELECT... FROM... WHERE...;
Las siguientes son algunas consideraciones y ejemplos sobre las 1. Para crear una conexión vía JDBC puro utilizaremos
consultas con SELECT: java.SQL.* y com.Matisse.SQL.MtDriver , no siendo necesario en
este caso el paquete com.Matisse.
Toda sentencia SELECT finaliza en punto y coma. a. La cadena de conexión será de la forma: String
Además de la cláusula WHERE, que permite establecer un url = "JDBC:mt://" + hostname + "/" + dbname;
criterio de selección se pueden utilizar las cláusulas de b. La conexión se realizará mediante Connection
agrupamiento GROUP BY, y de ordenación ORDER BY, jcon = DriverManager.getConnection(url);
entre otras. También se pueden asignar alias mediante AS, 2. Para crear una conexión vía JDBC y Matisse (a través de
realizar búsquedas por patrones de caracteres con LIKE. MtDatabase) se necesita java.SQL.* y com.Matisse.MtDatabase.
Ejemplo: título y tema de las tesis cuyo tema contien la a. La cadena de conexión será de la forma:
palabra Objeto, ordenadas por tema. MtDatabase db = new MtDatabase(hostname,
dbname);
SELECT titulo AS "Tesis", tema FROM Tesis b. La conexión se realizará mediante: db.open(); y
WHERE tema LIKE '%Objeto%' ORDER BY tema; Connection jcon = db.getJDBCConnection();
más de un objeto.
Se pueden hacer JOIN de clases, y por ejemplo esto puede
bases de datos objeto-
permitir obtener todos los objetos relacionados con otro
objeto en una consulta asociativa.
relacionales
Ejemplo: nombre de cada profesor y título y tema de las
Las BDOR las podemos ver como un híbrido de las BDR y las
tesis que dirige con JOIN
BDOO que intenta aunar los beneficios de ambos modelos, aunque
por descontado, ello suponga renunciar a algunas características de
SELECT p.nombre, t.titulo, t.tema FROM Profesor p
ambos.
JOIN Tesis t ON t.es_dirigida = p.OID;
Los objetivos que persiguen estas bases de datos son:
Mediante SELECT se pueden realizar consultas
navegacionales haciendo referencia a las Mejorar la representación de los datos mediante la
interrelacionales entre objetos. orientación a objetos.
Ejemplo: nombre de cada profesor y título y tema de las Simplificar el acceso a datos, manteniendo el sistema
tesis que dirige, navegacional relacional.
Pues porque internamente tanto las tablas como las columnas son
SELECT REF(p.dirige) FROM Profesor p 1) tratados como objetos, esto es, se realiza un mapeo objeto-
WHERE p.ingreo >= 1990; relacional de manera transparente.
Como consecuencia de esto, aparecen nuevas características, END;
entre las que podemos destacar las siguientes:
Algunas extensiones que contempla este estándar y que están 7.1 Instalación del Gestor
relacionadas directamente con la orientación a objetos son las
siguientes: PostgreSQL
Para practicar con este tipo de gestores y algunas de las nuevas
Extensión de tipos de datos. características que incorporan, hemos elegido PostgreSQL,
o Nuevos tipos de datos básicos para datos de considerado como el gestor de código abierto más avanzado del
caracteres de gran tamaño, y datos binarios de mundo.
gran tamaño (Large Objects)
o Tipos definidos por el usuario o tipos El código fuente de PostgreSQL está disponible bajo la licencia
estructurados. BSD. Esta licencia te da libertad para usar, modificar y distribuir
o Tipos colección, como los arrays, set, bag y list. PostgreSQL en cualquier forma, ya sea junto a código abierto o
o Tipos fila y referencia cerrado. Además, PostgreSQL. incluye API para diferentes
Extensión de la semántica de datos. lenguajes de programación, entre ellos Java y .NET
o Procedimientos y funciones definidos por el
usuario, y almacenados en el gestor. En la instalación se solicita una contraseña para el usuario postgres,
o Un tipo estructurado puede tener métodos que es el administrador por defecto de la Base de Datos. La utilidad
definidos sobre él. pgAdmin (III) permite realizar esta administración de forma visual.
CREATE TYPE direccion AS ( Para interactuar con PostgreSQL desde Java, vía JDBC, debemos
calle varchar, enviar sentencias SQL a la base de datos mediante el uso de
comandos.
numero integer,
Por tanto, si nuestra conexión es conn, para enviar un comando
codigo_postal integer); Statement haríamos lo siguiente:
y luego definir la tabla de nombre afiliados, con una columna Crear la sentencia, por ejemplo.: Statement sta =
basada en el nuevo tipo: conn.createStatement();
Ejecutar la sentencia:
CREATE TABLE afiliados AS( o sta.executeQuery(string sentenciaSQL); si
afiliado_id serial, sentenciaSQL es una consulta (SELECT)
nombre varchar(45), o sta.executeUpdate(string sentenciaSQL); si
apellidos varchar(45), sentenciaSQL es una actualización ( INSERT,
domicilio direccion); UPDATE O DELETE)
o sta.execute(string sentenciaSQL); si sentenciaSQL
es un CREATE, DROP, o un ALTER
7.3 Conexión mediante Como ves, en PostgreSQL se utilizan estos comandos como en
JDBC cualquier otra BDR.
La conexión de una aplicación Java con PostgreSQL se realiza
mediante un conector tipo JDBC. En el siguiente enlace te proporcionamos un ejemplo que ilustra
este hecho, con sentencias perfectamente conocidas por ti del
Una vez integrado en un proyecto, el driver puede utilizarse desde modelo relacional. Se crean varias tablas en la base de datos
cualquiera de sus clases mediante un: anaconda, se insertan, modifican, eliminan y consultan datos de
tipos básicos.
import java.sql.*
/*Añadir imagen
calle varchar, numero integer, codigo_postal varchar); versiones actuales ignoran estos valores en la práctica, de manera
que los array declarados de esta forma tienen la misma
funcionalidad que los del ejemplo anterior.
y la tabla afiliados, con una columna basada en el nuevo tipo:
En realidad, ninguna de estas declaraciones es conforme al estándar
CREATE TABLE afiliados(afiliado_id serial, nombre varchar, SQL99, que sólo contempla el tipo array como columnas de vectores
apellidos varchar, domicilio direccion); unidimensionales declarados con la palabra reservada array:
¿Cómo insertamos valores en una tabla con un tipo En el siguiente ejemplo puedes ver la creación de una tabla con una
estructurado? Se puede hacer de dos formas: columna de tipo array de varchar y como se insertan y consultan
valores:
Pasando el valor del campo estructurado entre comillas
simples (lo que obliga a encerrar entre comillas dobles /*Añadir imagenes
cualquier valor de cadena dentro), y paréntesis para
encerrar los subvalores separados por comas: Debes conocer
/*Añadir información
INSERT INTO afiliados (nombre, apellidos, direccion)
VALUES ('Onorato', 'Maestre Toledo', '(“Calle
de Rufino”, 56, 98080)'); 7.7 Funciones del gestor
Mediante la función ROW que permite dar valor a un desde Java
tipo compuesto o estructurado. Recuerda que el estándar SQL99 introduce la posibilidad de crear
funciones de usuario que puedan quedar almacenadas en el gestor
INSERT INTO afiliados (nombre, apellidos, direccion) de bases de datos, utilizando un Lenguaje Procedural (PL). Estas
funciones pueden definir el comportamiento de ciertos objetos y
VALUES ('Onorato', 'Maestre Toledo',
entonces, se llaman métodos. Oracle soporta métodos en este
ROW('Calle de Rufino', 56, 98080));
sentido, no así el gestor PostgreSQL.
¿Cómo se referencia una subcolumna de un tipo estructurado? Lo que si podremos hacer en PostgreSQL es crear funciones con
prestaciones para los nuevos tipos de datos, tipos estructurados y
Se emplea la notación punto, '.' , tras el nombre de la array, y llamarlas desde una aplicación Java.
columna entre paréntesis, (tanto en consultas de
selección, como de modificación) . Por ejemplo: En PostgreSQL se pueden construir funciones mediante diferentes
lenguajes:
SELECT (domicilio).calle FROM afiliados WHERE
(domicilio).codigo _postal=98080 Funciones de lenguaje de consultas o funciones SQL
(Escritas en lenguaje SQL)
devolvería el nombre de la calle Maestre Toledo. Los Funciones de lenguaje procedural (Escritas en lenguaje
paréntesis son necesarios para que el gestor no confunda PL/pgSQL, PL/Java, etc)
el nombre del campo compuesto con el de una tabla. Funciones de lenguaje de programación (Escritas en
un lenguaje de compilado, como C o C++),
Y ¿cómo se elimina el tipo estructurado?
Veremos algún ejemplo de funciones en SQL. Sobre estas
Se elimina con DROP TYPE, por ejemplo DROP TYPE funciones debes saber que:
direccion;
Los parámetros de la función pueden ser cualquier tipo
7.6 Consulta y actualización de dato admitido por el gestor (un tipo básico, un tipo
compuesto, un array o alguna combinación de ellos).
Arquitectura del estándar ODMG La arquitectura propuesta por Algunos fabricantes sólo ofrecen vinculaciones de lenguajes
ODMG consta de: específicos, sin ofrecer capacidades completas de ODL y OQL
Un modelo de objetos que permite que tanto los diseños,
como las implementaciones, sean portables entre los
sistemas que lo soportan.
Un sistema de gestión que soporta un lenguaje de bases
de datos orientado a objetos, con una sintaxis similar a un
lenguaje de programación también orientado a objetos.
Un lenguaje de base de datos que es especificado
mediante:
o Un Lenguaje de Definición de Objetos (ODL)
o Un Lenguaje de Manipulación de Objetos
(OML)
o Un Lenguaje de Consulta (OQL)
El almacenamiento basado en texto consiste en Comparando con una base de datos relacional o un sistema de
almacenar el documento XML entero en forma de texto archivos:
(fichero de texto), y proporcionar alguna funcionalidad
de base de datos para acceder a él. Se suelen aplicar Las colecciones juegan en las bases de datos nativas el
técnicas de compresión para reducir el espacio de papel de las tablas en las DB relacionales, o de un
almacenamiento, utilizar índices adicionales para mejorar directorio en un sistema de archivos.
el acceso a la información, y se pueden definir sobre BD Los documentos juegan el papel de las filas de una tabla
tradicionales o sistemas de ficheros. Básicamente existen de una BD relacional o un fichero en un sistema de
dos posibilidades: archivos.
o Almacenar el documento como un binario
largo (BLOB) en una base de datos relacional, Aunque depende de cada implementación, en muchos casos:
o mediante un fichero, y proporcionar algunos
índices sobre el documento que aceleren el Cada colección puede tener más de un DOCTYPE
acceso a la información. asociado.
o Almacenar el documento en un almacén El elemento raíz del documento XML define a que
adecuado con índices, soporte para DOCTYPE estará asociado el documento, en caso de no
transacciones, etc. poseer ninguno, éste se crea dinámicamente. Esto
El almacenamiento basado en modelo consiste en posibilita el almacenamiento de documentos sin formato
definir un modelo de datos lógico, como DOM, para la definido.
estructura jerárquica de los documentos XML y La colección también puede tener asociado un Schema
almacenar el modelo binario del documento en un con información tanto física como lógica de la colección.
almacén existente o bien específico. En este caso las La parte lógica define las relaciones y propiedades de los
posibilidades que existen son: documentos XML y la física contiene información sobre
o Traducir el DOM a tablas relacionales como el almacenamiento e indexación de los mismos.
elementos, atributos, entidades, etc. También se pueden almacenar documentos no-XML,
o Traducir el DOM a objetos en una BDOO. para estos existe un DOCTYPE especial llamado non-
o Utilizar un almacén creado especialmente para XML.
esta finalidad
No necesitan mapeos adicionales. Gestores nativos XML comerciales o de código propietario son:
Conservan la integridad de los documentos. TaminoXML Server. Es un gestor nativo XML de la
Permiten almacenar documentos heterogéneos empresa SoftwareAG. Es un producto comercial de alto
rendimiento y disponibilidad, además de ser uno de los
primeros SGBD XML nativos disponibles. Algunas de
8.2 Colecciones y sus características son las siguientes:
o Los documentos se almacenan en una base de
documentos datos propia y no se transforman en otro
modelo.
/*Añadir imagen
o Existe un espacio separado para documentos y
En general, una BD XML tiene una estructura jerárquica para índices.
organizada en colecciones y documentos XML. La estructura o Soporta el lenguaje de consultas XQuery y
jerárquica comienza con un nodo raíz ('/'), del que parten APIs para Java, C, y .NET, entre otras.
colecciones y documentos. TEXTML de Isiasoft. Los documentos se almacenan en
su formato nativo, sin ser mapeados.
Una colección: o Permite almacenar documentos sin DTD o
esquema.
Es un conjunto de documentos agrupados, normalmente, o Proporciona índices de acuerdo a la propia
en función de la información que contienen. estructura del documentos.
Puede contener otras colecciones.
o Permite la utilización de varios índices al Qizx fue lanzado de nuevo por Qualcomm a finales de 2014 on
mismo tiempo. Amazon Web Services.
o Incluye API para Java, WebDAV, OLE DB
y .NET.
Gestores nativos XML libres o de código abierto son: a. Gestionar la base de
Qizx. Es una base de datos nativa XML escrita en Java.
Almacena los datos utilizando una representación que se datos XML mediante
basa en el modelo de XPath 2,0.
o La representación utiliza compresión de QizxStudio
manera que un documento y sus índices suelen Una BD XML Qizx está organizada como una estructura jerárquica
utilizar menos espacio que el original XML. de colecciones, que a su vez contienen documentos, similar a un
o Los documentos se almacenan en una jerarquía sistema de archivos, donde las colecciones juegan el papel de los
de colecciones. directorios y los documentos XML desempeñan el papel de los
o Permite almacenar documentos sin DTD o archivos planos. Dentro de una colección pueden almacenarse
esquema. documentos de cualquier tipo.
o Soporta el lenguaje de consulta XQuery y sus
extensiones, como XUpdate, así como API Te detallamos a continuación la terminología utilizada por Qizx:
para Java.
eXist. Utiliza un sistema de almacenamiento propio XML Library. Es el equivalente a una base de datos XML.
(árboles B + y archivos paginados). Se puede ejecutar Físicamente, una BD o Library se almacena en un
como un servidor de base de datos independiente, como directorio en un disco, y no hay límite en el número de
una biblioteca de Java embebida, o en el motor servlet de bases de datos que se pueden crear con Qizx.
una aplicación Web. Su estructura jerárquica siempre comienza con un nodo
o Los documentos se almacenan en una jerarquía raíz, '/', del que parten documentos XML y/o colecciones.
de colecciones. XML Library Group. Es un conjunto de BD XML,
o Permite almacenar documentos sin DTD o agrupadas dentro de un directorio en disco.
esquema.
o Soporta el lenguaje de consulta XQuery y sus Por ejemplo, la imagen ampliable de la derecha muestra:
extensiones, como XUpdate, así como API
para Java. XML Library Group at C:\dxml. Es el grupo de BD XML
situado en el directorio físico c:\dbxml.
XML Library 'Libros'. Es la BD XML de nombre Libros.
9. Instalación del
'/'. Es el nodo raíz de la BD o Library
Las colecciones Publisher, Authors y Books dentro de la BD
gestor Qizx
XML de nombre Libros.
Diferentes documentos (archivos XML) dentro de la
colección Authors, como por ejemplo iasimov.xml.
En los siguientes apartados trabajaremos con la base de datos
nativa XML Qizx, especialmente diseñada para integrarse en una Podemos trabajar directamente con Qizx a través de la herramienta
aplicación Java independiente, esto es, para trabajar en modo gráfica denominada QizxStudio, la cual nos permite entre otras
embebido (embedded). Como tal, se utiliza principalmente como acciones las siguientes:
una biblioteca de clases, lo que supone que para utilizarla en una
aplicación habrá que añadir los correspondientes archivos .jar.
Crear la BD XML
También se puede utilizar en un entorno JEE, Servlets o EJB.
Explorar colecciones y documentos XML de la base de
datos
Algunas características de Qizx, que iremos viendo en los
Importar, crear y eliminar colecciones
siguientes apartados, son las siguientes:
Importar y eliminar documentos, así como copiar o
exportar a fichero
Consultas e indexación optimizadas. A diferencia de
otras bases de datos nativas XML, que están optimizadas Consultar documentos
para la actualización masiva de documentos XML, Qizx
optimiza las búsquedas y consultas de documentos Antes de comenzar a trabajar con Qizx y Java, y con el objetivo de
mediante un sistema de indexación muy eficiente. Sin que te familiarices con esta BD XML, verás algunos ejemplos de
embargo, la actualización de documentos de gran tamaño cómo gestionar colecciones y documentos mediante QizxStudio.
no es tan eficiente.
En el siguiente recurso didáctico encontrarás ejemplos de todo ello.
Compatible con estándares. Es totalmente compatible
con el lenguaje XQuery y sus extensiones Full-Text
/*Añadir imagen
XQuery y Update XQuery.
No necesita DTD o Esquemas predefinidos, siempre y
cuando el documento XML esté bien formado.
Indexado Automático. Los documentos son indexados
4 El lenguaje de consultas
automáticamente, aunque permite también personalizar
los índices. XQuery
Qizx fue inicialmente desarrollado por Xavier Franc of Axyana y XQuery es un lenguaje de consulta diseñado para extraer
fue comprado por Qualcomm in 2013. información de colecciones de datos expresadas en XML. Entre las
principales características de XQuery vamos a destacar las Nodo atributo. Un nodo elemento puede tener etiquetas
siguientes: que complementen la información de ese elemento. Esto
sería un nodo atributo.
Está basado en el lenguaje XPath, (XML Path
Language), y se fundamenta en él para realizar la Debes conocer
selección de información y la iteración a través del /*Añadir imagen
conjunto de datos XML.
Es un lenguaje declarativo, lo que significa que, en vez
de ejecutar una lista de comandos como un lenguaje 4.2 Caminos de localización
procedimental clásico, cada consulta es una expresión ¿Cómo se localiza cada uno de esos nodos en al árbol XML?
que es evaluada y devuelve un resultado, al igual que en Mediante una expresión XPath conocida como camino o ruta de
SQL. localización. Un camino de localización:
Podemos decir que XQuery es a XML lo mismo que SQL es a Selecciona un conjunto de nodos relativo al nodo de
las bases de datos relacionales. Sin embargo, aunque XQuery y contexto.
SQL puedan considerarse similares, el modelo de datos sobre el Puede contener recursivamente expresiones utilizadas
que se sustenta XQuery es muy distinto del modelo de datos para filtrar conjuntos de nodos.
relacional sobre el que sustenta SQL, ya que XML incluye Al ser evaluado, devuelve el conjunto de nodos
conceptos como jerarquía y orden de los datos que no están seleccionados por el camino de localización.
presentes en el modelo relacional. Se construye siguiendo unas reglas de sintaxis y
semántica.
Por ejemplo, a diferencia de SQL, en XQuery es importante y
determinante el orden en que se encuentren los datos, ya que no es Hay dos tipos de caminos de localización:
lo mismo buscar una etiqueta nombre dentro de una etiqueta autor
que todas las etiquetas nombre del documento (que pueden estar Caminos relativos. Son una secuencia de uno o más
anidadas dentro de una etiqueta autor o fuera). pasos de localización separados por /.
o Los pasos se componen de izquierda a derecha.
Los principales tipos de expresiones de XQuery son:
Caminos absolutos. Consiste en / seguido,
opcionalmente, por un camino de localización relativo.
Expresiones XPath, para navegar por los documentos. o Una / por si misma selecciona el nodo raíz del
Expresiones FLWOR (For, Let, Where, Order, Return) para documento que contiene al nodo contextual.
iterar por los elementos de un conjunto de datos.
Los siguientes, son algunos ejemplos de caminos de localización:
Pero XQuery también admite:
cuadro selecciona los elementos cuadro hijos del nodo
Constructores para generar nodos y contenido dinámico. contextual.
Condicionales (IF, THEN ELSE) para construir el resultado cuadro//titulo selecciona los elementos titulo descendientes de
en base a alguna condición. los elementos cuadro hijos del nodo contextual.
Cuantificadores (SOME, ANY) para chequear la existencia * selecciona todos los elementos hijos del nodo
de algún elemento que cumpla una condición. contextual.
Listas a las que se pueden aplicar operadores ( UNION,...) @año selecciona el atributo año del nodo contextual
y funciones de agregación (AVG, COUNT,...).
@* selecciona todos los atributos del nodo contextual
cuadro[1] selecciona el primer hijo cuadro del nodo
Nodo raíz o /. Es el primer nodo del documento. Una secuencia es un conjunto ordenado de cero o más
Nodo elemento. Cualquier elemento de un documento ítems.
XML. Cada nodo elemento posee un padre y puede o no Un ítem es cualquier tipo de nodo del árbol XML o un
tener hijos. En el caso de que no tenga hijos, es un nodo valor atómico.
hoja.
Nodo texto. Cualquier elemento del documento que no Las funciones que se pueden invocar para referirnos a colecciones
esté marcado con una etiqueta de la DTD del documento y documentos dentro de la BD son las siguientes:
XML.
collection(camino de la colección)
doc(camino del documento) /* Añadir imagen
Para crear una BD XML y establecer una conexión se utilizan /*Añadir imagen
métodos del interface LibraryManager.
Si por ejemplo, ruta vale /Publishers/Pocket.xml, lo que estaríamos El método Expression.bindVariable() que permite vincular una
borrando con la sentencia bd.deleteMember(ruta); sería exactamente el secuencia de Items a una variable.
documento Pocket.xml.
A continuación, dispones de un ejemplo detallado de consultas
¿Y cómo eliminar toda la base de datos? Para ello, puedes XQuery desde una aplicación Java. Las consultas se realizan sobre
utilizar: la BD Cursillos que creaste anteriormente. Las consultas que se
ejecutan están almacenadas como scripts en ficheros de extensión .xq
el método de la interface
deleteLibrary(String bdNnombre)
dentro del directorio C:\BDCursillosXML\cursillos_query\.
LibraryManager, que elimina físicamente la BD. También puedes probar con este mismo programa las consultas 7.xq
y 8.xq que vienen con la distribución Qizx Free Engine Edition y
que encontrarás en la carpeta de instalación dentro del directorio
\docs\samples\book_queries\. En este caso, la BD a utilizar será
5.7 Consultar documentos Tutorial.
¿Se utiliza el lenguaje XQuery para realizar consultas a la BD
XML desde una aplicación Java? La respuesta es sí, pero será /* Proyecto java
necesario realizar los siguientes pasos para procesar una
consulta desde Java: Debes conocer
Compilar la consulta o expresión XQuery mediante el Es importante que conozcas las posibilidades del interface Expression
método Library.compileExpression(). Si la compilación se y del interface ItemSequence. Consulta el API (com.quizx.api)
realiza sin errores (CompilationException), devolverá un
objeto Expression.
Evaluar la expresión o consulta compilada mediante el
método Expression.evaluate(). Si la evaluación se realiza sin 5.8 Actualizar documentos.
errores (EvaluationException), devolverá el resultado en Aunque dependiendo del sistema de BD XML pueden existir
forma de un ItemSequence. diferentes formas de actualizar documentos, la manera más sencilla
Iterar sobre la secuencia obtenida. Un ItemSequence de hacerlo es mediante Update XQuery, la extensión del lenguaje
permite iterar sobre una secuencia de Items, donde un XQuery que permite inserciones, eliminaciones y
Item es un valor atómico o un nodo XML. modificaciones de nodos de los documentos XML.
6.4 Excepciones en el
procesamiento de
consultas
Cuando se procesa una consulta XQuery o una consulta de
actualización XQuery, pueden ocurrir errores en el proceso de
compilación y evaluación de la expresión de consulta, que suponen
el lanzamiento de excepciones.
/*Añadir imagen
Tema 7. Creación de componentes
visuales
1. Concepto de Las propiedades son un tipo específico de atributos que representan
características de un componente que afectan a su apariencia o a su
componente. comportamiento. Son accesibles desde fuera de la clase y forman
parte de su interfaz. Suelen estar asociadas a un atributo interno.
2 Propiedades y atributos
Como en cualquier clase, un componente tendrá definido un estado 3 Editores de propiedades
a partir de un conjunto de atributos. Los atributos son variables
definidas por su nombre y su que toman valores concretos. Una de las principales características de un componente es que, una
Normalmente los atributos son privados y no se ven desde fuera de vez instalado en un entorno de desarrollo, éste debe ser capaz de
la clase que implementa el componente, se usan sólo a nivel de identificar sus propiedades simplemente detectando parejas de
programación. tipo de datos
operaciones get/ set, mediante la capacidad denominada
introspección. 4 Eventos. Asociación de
El entorno de desarrollo podrá editar automáticamente cualquier
propiedad de los tipos básicos o de las clases Color y Font. Aunque
acciones a eventos
no podrá hacerlo si el tipo de datos de la propiedad es algo más
complejo, por ejemplo, si usamos otra clase, como Cliente. Para Se puede programar un componente para que reaccione ante
poder hacerlo tendremos que crear nuestro propio editor de determinadas acciones del usuario, como un clic del ratón o la
propiedades. pulsación de una tecla del teclado. Cuando estas acciones se
producen, se genera un evento que el componente puede capturar y
Un editor de propiedad es una herramienta para personalizar un procesar ejecutando alguna función. Pero no solo eso, un
tipo de propiedad en particular. Los editores de propiedades se componente puede también lanzar un evento cuando sea necesario
utilizan en la ventana Propiedades, que es donde se determina el y que su tratamiento se realice en otro objeto.
tipo de la propiedad, se busca de un editor de propiedades
apropiado, y se muestra el valor actual de la propiedad de una Los eventos que lanza un componente se reconocen en las
manera apropiada. herramientas de desarrollo y se pueden usar para programar la
realización de acciones.
La creación de un editor de propiedades usando tecnología Java
Para que el componente pueda reconocer el evento y responder
supone programar una clase que implemente la interfaz
ante el tendrás que hacer lo siguiente:
PropertyEditor, que proporciona métodos para especificar cómo se
debe mostrar una propiedad en la hoja de propiedades. Su nombre
Crear una clase para los eventos que se lancen.
debe ser el nombre de la propiedad seguido de la palabra Editor:
Definir una interfaz que represente el oyente (listener)
public Editor implements PropertyEditor {…} asociado al evento. Debe incluir una operación para el
procesamiento del evento.
Por defecto la clase PropertyEditorSupport que implementa Definir dos operaciones, para añadir y eliminar oyentes.
PropertyEditor proporciona los editores más comúnmente Si queremos tener más de un oyente para el evento
empleados, incluyendo los mencionados tipos básicos, Color y Font. tendremos que almacenar internamente estos oyentes en
una estructura de datos como ArrayList o LinkedList:
Una vez que tengamos todos los editores, tendremos que
empaquetar las clases con el componente para que use el editor que public void addListener(Listener l)
hemos creado cada vez que necesite editar la propiedad. Así, public void removeListener(Listener l)
conseguimos que cuando se añada un componente en un panel y lo
seleccionemos, aparezca una hoja de propiedades, con la lista de Finalmente, recorrer la estructura de datos interna
las propiedades del componente y sus editores asociados para cada llamando a la operación de procesamiento del evento de
una de ellas. El IDE llama a los métodos getters, para mostrar en todos los oyentes registrados. En resumen:
los editores los valores de las propiedades. Si se cambia el valor de
una propiedad, se llama al método setter, para actualizar el valor de /*Añadir imagen
dicha propiedad, lo que puede o no afectar al aspecto visual del
componente en el momento del diseño.
5 Introspección. Reflexión
3.1 Ejemplo de creación de Un componente, como cualquier otra clase dispone de una interfaz,
que es el conjunto de métodos y propiedades accesibles desde el
un componente entorno de programación. Normalmente, la interfaz la forman los
atributos y métodos públicos.
JavaBean con NetBeans
Para ilustrar cómo se implementa un componente con una La introspección es una característica que permite a las
herramienta como NetBeans, crearemos uno que permita almacenar herramientas de programación visual arrastrar y soltar un
la información de una persona, guardaremos por ejemplo, su componente en la zona de diseño de una aplicación y determinar
nombre, apellidos, teléfono y dirección: dinámicamente qué métodos de interfaz, propiedades y eventos del
componente están disponibles.
El nombre se puede representar como una propiedad de
tipo String. Esto se puede conseguir de diferentes formas, pero en el nivel más
Los apellidos también se pueden representar como una bajo se encuentra una característica denominada reflexión, que
propiedad de tipo String. busca aquellos métodos definidos como públicos que empiezan por
El teléfono también puede ser una cadena de caracteres o get o set, es decir, se basa en el uso de patrones de diseño, es decir,
String. en establecer reglas en la construcción de la clase de forma que
La dirección será una propiedad compuesta, por la mediante el uso de una nomenclatura específica se permita a la
dirección propiamente dicha, la población y la provincia. herramienta encontrar la interfaz de un componente. reflexión
Dado que la última propiedad no es simple, será necesario En JavaBeans la introspección se puede conseguir de varias
implementar un editor de propiedades para modificarla desde maneras:
NetBeans.
Reflexión de bajo nivel, que utiliza patrones de diseño
para descubrir las características del componente por
medio de las posibilidades de reflexión del paquete Los componentes que implementarás en esta unidad emplearán la
java.lang.reflect. serialización por defecto por lo que debes tener en cuenta lo
Examinando una clase asociada de información del siguiente:
componente (BeanInfo) que describe explícitamente sus
características para que puedan ser reconocidas. La clase debe implementar la interfaz Serializable.
Es obligatorio que exista un constructor sin argumentos.
6 Persistencia del
7 Propiedades simples e
componente
A veces, necesitamos almacenar el estado de una clase para que
indexadas
perdure a través del tiempo. A esta característica se le llama /*Añadir imagen
persistencia. Para implementar esto, es necesario que pueda ser
almacenada en un archivo y recuperado posteriormente. Una propiedad simple representa un único valor, un número,
verdadero o falso o un texto por ejemplo.
El mecanismo que implementa la persistencia se llama
serialización. Al proceso de almacenar el estado de una clase en un Tiene asociados los métodos getter y setter para establecer y rescatar
archivo se le llama serializar. ese valor. Por ejemplo, si un componente de software tiene una
propiedad llamada peso de tipo real susceptible de ser leída o
/*Añadir imagen escrita, deberá tener los siguientes métodos de acceso:
10 Empaquetado de
cambiado de que el cambio no se ha aprobado.
En BeanBox se pueden escribir los Beans, para luego arrastrarlos Puedes incluir varios componentes en un mismo jar.
dentro de BeanBox y comprobar si funcionan como se esperaba.
El paquete jar debe incluir un fichero de manifiesto (con extensión
.mf) que describa su contenido, por ejemplo: /*Añadir imagen
Manifest-Version: 1.0 La base de datos se compone de una sola tabla de alumnos. Para
Name: demo/Componente.class cada alumno almacenamos su DNI, nombre, apellidos, dirección y
Java-Bean: True fecha de nacimiento
Name: demo/ComponenteBeanInfo.class
Java-Bean: False
Name: demo/ClaseAuxiliar.class
Java-Bean: False
11.2 Controlador o lógica del
Name: demo/Imagen.png
Java-Bean: False
modelo
En el entorno de la arquitectura MVC el controlador representa la
lógica de negocio de una aplicación. Encapsula las reglas de
Observa, en el fichero de manifiesto como la clase del componente
negocio en componentes que son fáciles de probar, permiten
va acompañada de Java-Bean: True, indicando que es un JavaBean.
mejorar la calidad del software y promueven la reutilización.
La forma más sencilla de generar el archivo jar es utilizar la El estado define el conjunto actual de valores del modelo e incluye
herramienta Limpiar y construir del proyecto en NetBeans, que métodos para cambiar estos valores. Estos métodos recogen parte
deja el fichero .jar perfectamente en el directorio /dist del proyecto, de la lógica de negocio. Deberían de ser independientes del
aunque siempre puedes recurrir a la orden jar y crearlo tu protocolo que se utilizara para acceder a ellos. Si resumimos la
directamente: encapsulación, calidad del software, reutilización e independencia
jar cfm Componente.jar manifest.mf Componente.class del protocolo obtenemos que los JavaBeans son la elección lógica
ComponenteBEanInfo.class ClaseAuxiliar.class Imagen.png para implementar estos componentes.
proyecto.jar
El componente se encarga de conectar con la base de datos y
ejecutar la sentencia deseada. A través de los métodos puede
componente de ejemplo Las acciones definen los cambios permitidos para los estados en
respuesta a los eventos.
En el ámbito del acceso a datos que estudiamos en este módulo
formativo el uso de componentes está muy relacionado con el
mundo de la creación de aplicaciones web.
11.3 Estructura del JavaBean
La tecnología JSP utiliza una arquitectura denominado MVC Para la elaboración de un componente, debes tener muy claros
(Modelo-Victa-Controlador) cuya misión fundamental es separar el los pasos que debes dar.
desarrollo de la base de datos (Modelo), creada por ejemplo en
MySQL o cualquier otro gestor de bases de datos, de la interfaz 1. Creación del componente.
(Vista), que puede hacerse usando HTML en combinación con JSP, 2. Adición de propiedades.
de la lógica de negocio (Controlador) cuya implementación más 3. Implementación de su comportamiento.
sencilla y fácil de gestionar por JSP es un JavaBean que acceda a la 4. Gestión de los eventos.
base de datos y permita recuperar fácilmente la información que 5. Uso de componentes ya creados en NetBeans.
contiene.
En las siguientes secciones verás cómo se realizan estos pasos con
/* Añadir imagen el ejemplo que se acaba de exponer.
En el esquema el modelo sería la base de datos, la vista el apartado El componente a crear dispondrá de un constructor con las
de presentación de datos y el controlador está formado por la lógica siguientes características:
de la aplicación y acceso a datos.
Propiedades que se corresponden con los campos de la
Para saber más tabla alumnos.
/*Añadir imagen Clase auxiliar llamada Alumno que usaremos para crear
un vector de alumnos donde cargaremos el contenido de
Para ejemplificar el uso de componentes JavaBean de acceso a la tabla.
datos, supondremos que queremos crear una aplicación web que Vector de alumnos.
muestre información de los alumnos del ciclo que mantendremos Constructor (sin argumentos):
almacenados en una base de datos. De momento, nos encargaremos o Realiza la conexión a la base de datos.
de los apartados Modelo y Controlador, dejando la vista para otros o Realiza la consulta.
módulos del ciclo. o Guarda los resultados en una estructura local al
componente.
o Establece los valores de las propiedades.
11.1 Modelo o base de datos
o Cierra la conexión.
Métodos para recorrer los resultados, recargando las
Nos basaremos en una base de datos muy sencilla que tendremos
almacenada en un servidor MySql. El código SQL para crear la propiedades cada vez que cambie. Usaremos los
base de datos sería: siguientes métodos:
o obtenerFilas():hace la consulta sobre la base de propiedad y su tipo, e insertar los métodos get y set de manera
datos y almacena los resultados sobre un vector automática:
interno actualizando los valores de las
propiedades. /*Añadir imagen
o SeleccionarFilas/(i): se posiciona en el elemento i
del vector y actualiza los valores de las Fíjate que si quisieras crear una propiedad indexada o restringida es
propiedades. muy sencillo de hacer, sólo hay que marcar la opción
o seleccionarDNI(String DNI): busca en el vector correspondiente y la herramienta genera el código base de los
interno el registro que coincide con el valor del métodos necesarios.
DNI y actualiza los valores de las propiedades.
11.6 Implementar el
11.4 Creación del
comportamiento
componente Con las propiedades listas, tenemos que programar el
Comenzamos creando un proyecto NetBeans nuevo de tipo Java comportamiento del componente. En principio la idea es que al
Application. Nos aseguramos de desmarcar las opciones Crear crear el componente se cargue el contenido de la tabla alumno de la
clase principal y Configurar como proyecto principal y ponemos de base de datos en un vector de uso interno que nos va a servir para
nombre al proyecto AlumnoBean, por ejemplo. no tener que estar conectándonos constantemente, recuerda que
estos componentes se usan en entornos cliente servidor con gran
Una vez creado el proyecto, le añadimos un archivo nuevo de tipo cantidad de accesos por parte de múltiples usuarios que pueden
Componente JavaBeans (si no lo encuentras en la lista que sale en llegar a saturar la base de datos. Por este motivo programaremos el
el menú contextual, haz clic en la opción Otros... para acceder al constructor para que realice la carga de datos. En un primer
resto de tipos de archivos). Puedes llamar a la clase AlumnoBean y momento los valores de las propiedades serán los del primer
al paquete en el que se ubicará Alumno. alumno recuperado.
11.5 Añadir propiedades. a la base de datos. Tendrá como especial característica que cada
vez que se inserte un alumno nuevo que generará un evento que
El componente tendrá como propiedades las mismas que los alerte de esta modificación. Esto que en principio puede parecer
campos de la base de datos: DNI, nombre, apellidos, dirección y redundante no lo es en un entorno multiusuario en el que varios
fecha de nacimiento. clientes se conecten simultáneamente a la base de datos. Para poder
implementar esto necesitarás varias cosas:
La adición de propiedades en una clase Java se realiza simplemente
escribiendo el código de declaración del atributo privado (o Una clase que implemente los eventos. Esta clase hereda
protegido) y los métodos getter y setter que son la base de la de java.util.EventObject. En el ejemplo se llamará
instrospección. BDModificadaEvent.
Una interfaz que defina los métodos a usar cuando se
Si bien NetBeans proporciona una ayuda especial para realizar esta genere el evento. Implementa java.util.EventListener. En este
tarea. Con el cursor posicionado dentro de la clase (puedes reservar caso la gestión del evento se hará a través del método
capturarBDModificada de la interfaz BDModificadaListener.
una zona para el código de propiedades), haz clic con el botón
secundario y selecciona la opción Insertar Código..., en la lista También tenemos un objeto de tipo DBModificadaListener
que te saldrá elige Agregar propiedad. Se desplegará el siguiente llamado receptor que representa aquellos programas que
cuadro de diálogo en el que puedes escribir el nombre de la contienen al componente AlumnosBean susceptibles de
recibir el evento.
Dos métodos, addEventoListener y removeEventoListener que
permitan al componente añadir oyentes y eliminarlos. En
principio se deben encargar de que pueda haber varios
oyentes. En nuestro caso sólo vamos a tener un oyente,
pero se suele implementar para admitir a varios.
Implementar el método que lanza el evento,
asegurándonos de todos los oyentes reciban el aviso. En
este caso lo que se ha hecho es lanzar el método que se
creó en la interfaz que describe al oyente.
/* Añadir imagen
AccedeBD(){
alumnos = new AlumnoBean();
alumnos.addBDModificadaListener((BDModificadaListener)t
his );
}