II Curso Online JAVA-J2EE
TEMA 5
ORM, Persistencia de Datos
Autor: PCYTA / Centro de Excelencia de Software Libre de Castilla-La Mancha Versin: 1.0 Fecha: Revisado 26-02-2008 22:46 Licencia: CC-by-sa 2.5
0 Licencia
Usted es libre de: Copiar, distribuir y comunicar pblicamente la obra
Hacer obras derivadas
Bajo las condiciones siguientes:
Reconocimiento. Debe reconocer los crditos de la obra de la manera especificada por el autor o el licenciador (pero no de una manera que sugiera que tiene su apoyo o apoyan el que hace de su obra). Compartir bajo la misma licencia. Si altera o transforma esta obra, o genera una obra derivada, slo puede distribuir la obra generada bajo una licencia idntica a sta.
uso
Al reutilizar o distribuir la obra, tiene que dejar bien claro los trminos de la licencia de esta obra. Alguna de estas condiciones puede no aplicarse si se obtiene el permiso del titular de los derechos de autor Nada en esta licencia menoscaba o restringe los derechos morales del autor.
Para ver la licencia visite: http://creativecommons.org/licenses/by-sa/2.5/es/legalcode.es
6 de febrero de 2008
Tema 5
UNIDAD II. ORM, Persistencia de Datos
0 Licencia............................................................................................................................................ 2 1 SQL...................................................................................................................................................5 2 JDBC................................................................................................................................................ 6 2.1 Introduccin.............................................................................................................................. 6 2.2 Conexin a una Base de Datos ................................................................................................ 6 2.3 Creacin y Ejecucin de una Sentencia ................................................................................... 7 2.4 Creacin y Ejecucin de una Sentencia Preparada ("PreparedStatement") .............................8 2.5 Transaccionalidad .................................................................................................................... 9 3 Instalacion de MySQL....................................................................................................................11 4 Ejemplo de JDBC en Aplicaciones JAVA...................................................................................... 21 5 Ejemplo de JDBC en Aplicaciones J2EE....................................................................................... 28 6 Frameworks.................................................................................................................................... 40 6.1 Introduccin............................................................................................................................ 40 6.2 JDO......................................................................................................................................... 40 6.3 Hibernate ................................................................................................................................41
6 de febrero de 2008
Tema 5
INTRODUCCIN Como veamos durante temas anteriores, uno de los modelos a seguir ms habituales a la hora de desarrollar aplicaciones es el modelo de tres capas. Estas capas eran: capa de presentacin capa de lgica de negocio capa de datos Las dos primeras ya hemos visto como desarrollarlas mediante el empleo de tecnologas como HTML, JavaScript, CSS, JSPs, Servlets, EJBs (lo veremos en el siguiente tema), etc. En este tema nos vamos a centrar en algunas de las tecnologas que se suelen emplear a la hora de desarrollar la capa de datos. Object-Relational Mapping (abreviado como ORM, O/RM y O/R Mapping) es una tcnica de programacin para mapear datos de lenguajes de programacin orientados a objetos (como Java) a bases de datos relacionales (como Oracle, MySQL, DB2, etc.). Sigamos con nuestro ejemplo de la tienda virtual. Tenemos el concepto usuario, que tiene asociados datos como nombre, direccin y dni. Para implementar esto en nuestra tienda virtual tendramos que tener una clase "Usuario" con esos campos y tendramos que tener una tabla "Usuarios" donde almacenar esos datos. Y por ltimo, deberamos implementar la funcionalidad necesaria para relacionar los campos de base de datos con los campos de la clase "Usuario". Esta funcionalidad para "mapear" campos de base de datos con campos de objetos se realiza mediante la tcnica ORM. La tcnica ORM es un modelo a seguir, existiendo un gran nmero de entornos que nos ayudan a la hora de aplicar esta tcnica. En los siguientes apartados de este tema veremos algunos de ellos y varias tecnologas tiles a la hora de manipular la capa de datos.
6 de febrero de 2008
Tema 5
1 SQL
SQL (Structured Query Language) es un lenguaje diseado principalmente para la manipulacin de datos en bases de datos relacionales y modificacin de esquemas de bases de datos (tablas, ndices, vistas, etc.). Este lenguaje fue estandarizado por las organizaciones ANSI e ISO y hoy en da es el empleado en las distintas bases de datos (Oracle, DB2, MySQL, PostgreSQL, etc.). Antes de seguir con el curso, es importante que conozcis algo de SQL. En caso de no ser as, antes de continuar, estudiad el lenguaje SQL (al menos a un nivel bsico) ya que este conocimiento es prcticamente indispensable para continuar con el tema. Para este estudio visitad enlaces como http://www.programacion.com/bbdd/tutorial/sql/ para ver SQL genrico y mirad http://dev.mysql.com/doc/refman/5.0/en/sql-syntax.html para ver SQL con los comandos especficos de MySQL. Por otro lado, en el caso de que s lo conozcis, tampoco es mala idea hacer un repaso al segundo enlace de los antes indicados ya que explica cosas que son propias de MySQL, las cuales no conoceris si no habis trabajado nunca con ella. El segundo enlace situado arriba es un manual de SQL para MySQL ya que esta base de datos es la que usaremos. Aunque SQL es un estndar, cada base de datos suele introducir algunas variantes tanto en tipos de datos como en ciertas sentencias, pero siempre manteniendo la base de SQL.
6 de febrero de 2008
Tema 5
2 JDBC
2.1 Introduccin
JDBC (Java Database Connectivity) es un API que permite la ejecucin de operaciones sobre bases de datos desde el lenguaje de programacin Java. El API JDBC es una especificacin del interfaz que debe emplear el programador que quiere operar sobre la base de datos. Cada distribuidor de bases de datos tiene que ofrecer a los desarrolladores que las van a emplear una implementacin de ese API(tambin llamado driver). En nuestro ejemplo de la tienda virtual vamos a usar MySQL como sistema de gestin de bases de datos, de modo que tenemos que instalar MySQL y, para conectarnos a l y operar mediante JDBC, tenemos que emplear la implementacin del API que los creadores de MySQL nos proporcionen. Esta implementacin, en el caso de MySQL, no es ms que un jar. En el resto del tema veremos los pasos a seguir para conectarse a una base de datos y operar sobre ella. Ms adelante pondremos un ejemplo en el que se instalar el sistema de gestin de base de datos (MySQL), se crear una base de datos de ejemplo con unas tablas y luego realizaremos mediante JDBC algn acceso a la misma.
2.2
Conexin a una Base de Datos
Imaginemos que nos proporcionan una base de datos con sus tablas. Lo primero que deberamos realizar para trabajar con ella es conectarnos. Para ello debemos realizar dos pasos, la carga del driver y la conexin. - Carga del driver: Esta tarea es bastante sencilla. Escribiendo la siguiente lnea es suficiente: Class.forName("clase del driver"); La documentacin del driver nos especificar el nombre de la clase a utilizar. En el caso de MySQL, segn la documentacin, sera: Class.forName("com.mysql.jdbc.Driver"); Una vez cargado el driver, ya podemos realizar la conexin. El "jar" que contiene la clase del driver debe estar en el ClassPath.
6 de febrero de 2008
Tema 5
- Realizar la conexin: Para realizar la conexin deberamos escribir una lnea de cdigo como la siguiente. Connection con = DriverManager.getConnection(url, "miLogin", "miPassword"); Lo complicado de este punto es saber que url proporcionar. La url a emplear normalmente vendr explicada en la documentacin de sistema de gestin de base de datos que estemos utilizando. En nuestro caso, para MySQL, sera algo as: Connection con = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "password"); "test" es una base de datos que viene con la instalacin inicial de mysql, "root" es el usuario administrador de la base de datos y "password" es el password que fijamos en la instalacin para ese usuario.
2.3
Creacin y Ejecucin de una Sentencia
Un objeto de la clase Statement (definida en el API JDBC) es el que enva nuestras sentencias SQL al controlador de la base de datos. Por lo tanto, para lanzar una sentencia SQL simplemente creamos un objeto Statement y lo ejecutamos pasndole por parmetro la sentencia SQL. Si la sentencia SQL es un SELECT (no modifica datos), el mtodo a ejecutar es executeQuery. Si la sentencia SQL crea o modifica tablas o su contenido, empleamos executeUpdate. Statement stmt = con.createStatement(); stmt.executeQuery(SENTENCIA SQL DE TIPO SELECT); stmt.executeUpdate(SENTENCIA SQL QUE CREA O MODIFICA TABLAS O SU CONTENIDO); El objeto "con" es la conexin creada en el apartado anterior.
Un detalle importante es que "executeUpdate()" devuelve un "int" con el nmero de lneas modificadas mientras que "executeQuery()" devuelve un "ResultSet" que contiene el conjunto de registros que devuelve la sentencia de tipo "select" que se le pasa por parmetro. Evidentemente, una sentencia sql de tipo "select" puede devolver miles de registros con lo que el "ResultSet" no contiene todo los resultados, sino que contiene un "cursor" el cual se recorre con las funciones que ofrece "ResultSet". A continuacin vemos un ejemplo que muestra este funcionamiento: ResultSet rs = stmt.executeQuery(SENTENCIA SQL DE TIPO SELECT); while (rs.next()) { System.out.println(rs.getString(1));
6 de febrero de 2008
Tema 5
} En el cdigo anterior, se supone que la "SENTENCIA SQL" debe devolver un primer campo de tipo "String". Si este primer dato fuera un nmero entero deberamos usar "rs.getInt(1)". Si, por ejemplo, la "SENTENCIA SQL" devolviera como tercer campo un nmero con decimales, usaramos rs.getDouble(3); Los mtodos que ofrece el interfaz "java.sql.ResultSet" es mucho ms amplia para recorrer resultados y obtener los distintos tipos existentes. Para una mayor informacin mirar http://java.sun.com/j2se/1.5.0/docs/api/java/sql/ResultSet.html Con esto tenemos la idea principal de como trabajar sobre una base de datos con java. Ahora veremos algunos otros conceptos importantes y, ms adelante, realizaremos un par de ejemplos muy sencillos que os servirn de base para los desarrollos que tengis que realizar.
2.4 Creacin y Ejecucin de una Sentencia Preparada ("PreparedStatement")
Algunas veces es ms conveniente o eficiente utilizar objetos "PreparedStatement" para enviar sentencias SQL a la base de datos en vez de los antes vistos "Statement". Este tipo especial de sentencias extiende el interfaz "Statement". Es ms conveniente cuando queremos ejecutar muchas veces un objeto "Statement". En ese caso, si usamos "PreparedStatement" reduciremos el tiempo de ejecucin. La caracterstica principal de un objeto "PreparedStatement" es que, al contrario que un objeto "Statement", se le entrega una sentencia SQL cuando se crea. La ventaja de esto es que, en la mayora de los casos, esta sentencia SQL se enviar al controlador de la base de datos inmediatamente donde ser compilada. Como resultado, el objeto "PreparedStatement" no slo contiene una sentencia SQL, sino una sentencia SQL que ha sido precompilada. Esto significa que cuando se ejecuta la PreparedStatement, el controlador de base de datos puede ejecutarla sin tener que compilarla primero. Aunque los objetos "PreparedStatement" se pueden utilizar con sentencias SQL sin parmetros, probablemente nosotros utilizaremos ms frecuentemente sentencias con parmetros. La ventaja de utilizar sentencias SQL que utilizan parmetros es que podemos utilizar la misma sentencia y suministrar distintos valores cada vez que la ejecutemos. A continuacin vemos cdigo que muestra el uso de un "PreparedStatement". PreparedStatement pstmt = con.prepareStatement("SELECT * FROM NOMBRE_TABLA WHERE NOMBRE_CAMPO1=? AND NOMBRE_CAMPO2=?"); pstmt.setString(1,"valor_campo1"); pstmt.setInt(2,78); ResultSet rs = pstmt.executeQuery(); 6 de febrero de 2008 Tema 5 8
Cmo podemos deducir a partir del ejemplo, el primer argumento de un mtodo setXXX indica que "?" queremos asignar, y el segundo argumento el valor que queremos ponerle. En este momento ya hemos visto como usar una base de datos en JAVA, que es lo principal que debemos saber. An as, todava hay un aspecto muy importante a la hora de trabajar sobre bases de datos, la transaccionalidad. Este asunto lo veremos en el siguiente apartado. Tened en cuenta que todo el cdigo escrito hasta el momento, y el que veris en el siguiente apartado, emplea mtodos que lanzan excepciones. No las hemos puesto en el cdigo de ejemplo para no confundir, pero no os preocupis porque en los ejemplos veris este cdigo con el control de excepciones apropiado.
2.5
Transaccionalidad
Como bien conocemos, las operaciones sobre bases de datos tienen un aspecto muy importante, la transaccionalidad. Para gestionarla, una de las principales herramientas de las que disponemos es la propiedad booleana denominada "AutoCommit" que tienen las conexiones que creamos a una base de datos. Si una conexin tiene "AutoCommit" a valor true, automticamente se ejecutar una sentencia "Commit" tras cada operacin de actualizacin en base de datos. En el caso de que "AutoCommit" est asignada a "false", nosotros tendremos que realizar el "Commit" de forma explcita. A continuacin vemos un ejemplo de asignacin del valor de "AutoCommit": //con es la conexin obtenida anteriormente con.setAutoCommit(false); Imaginemos ahora un ejemplo sobre nuestra tienda virtual. Hemos realizado una venta con lo que tenemos que ejecutar dos operaciones, por un lado la insercin de un nuevo pedido en la tabla de pedidos y por otro lado actualizar el almacn eliminando del stock los productos vendidos en el pedido. Evidentemente para que la base de datos no quede inconsistente, estas dos operaciones se tienen que ejecutar, no nos vale, por ejemplo, que se ejecute la primera y la segunda falle. Para resolver este problema, una solucin sencilla es fijar el "AutoCommit" a "false", ejecutar las operaciones, hacer el "Commit" y finalmente establecer de nuevo el AutoCommit a "true".A continuacin se muestra el cdigo que realizara esas operaciones: //con es la conexin obtenida anteriormente con.setAutoCommit(false); Statement stmt = con.createStatement(); stmt.executeUpdate(SENTENCIA SQL DE INSERCIN DEL PEDIDO); stmt.executeUpdate(SENTENCIA SQL DE AJUSTE DE STOCK); con.commit(); con.setAutoCommit(true);
6 de febrero de 2008
Tema 5
Pero imaginemos que se ejecuta correctamente la primera sentencia SQL y la segunda falla (lanzando una excepcin), en este caso deberamos hacer un "rollback" para que se deshagan las operaciones anteriores. A continuacin se muestra un ejemplo de cmo quedara el cdigo: con.setAutoCommit(false); try { Statement stmt = con.createStatement(); stmt.executeUpdate(SENTENCIA SQL DE INSERCIN DEL PEDIDO); stmt.executeUpdate(SENTENCIA SQL DE AJUSTE DE STOCK); con.commit(); } catch (SQLException sqle) { con.rollback(); } con.setAutoCommit(true); Con esto hemos visto la utilidad de las transacciones para lograr que varias operaciones sobre base de datos se ejecuten de forma atmica, que es uno de los principios bsicos del trabajo sobre base de datos.
6 de febrero de 2008
Tema 5
10
3 Instalacion de MySQL
En este momento ya sabemos SQL y sabemos programar en Java para trabajar sobre bases de datos mediante JDBC. Pero, evidentemente, necesitamos una base de datos sobre la que hacer nuestras pruebas y aplicaciones. Sistemas de Gestin de Bases de Datos Relacionales existen muchos (Oracle, DB2, MySQL, etc.) cada uno con sus caractersticas. No confundir "Sistema de Gestin de Bases de Datos Relacionales" con "Base de Datos Relacional". El primero es la aplicacin donde se crean y gestionan las bases de datos. El segundo es el "ente" en el que se especifican y almacenan todos los datos. An as, es muy habitual emplear la expresin "Base de Datos" para ambos conceptos. Para este curso hemos decidido emplear MySQL 5.0 por varias razones: - Tiene versiones gratuitas. - Es sencillo de instalar y usar. - Es ampliamente utilizado incluso en entornos en produccin. Para instalar la base de datos, lo que debemos hacer es descargar el fichero instalador (descrgalo de aqu), descomprimirlo y ejecutarlo. Para tener la instalacin que vamos a utilizar en el curso, sigue los siguientes pasos:
Pulsa "Next".
6 de febrero de 2008
Tema 5
11
Selecciona "Typical" y pulsa "Next".
Pulsa "Install".
6 de febrero de 2008
Tema 5
12
Pulsa "Next".
Pulsa "Next".
6 de febrero de 2008
Tema 5
13
Marca la casilla que te llevar a configurar la base de datos y pulsa "Next".
Pulsa "Next".
6 de febrero de 2008
Tema 5
14
Marca "Detailed Configuration" y pulsa "Next".
Selecciona "Developer Machine" y pulsa "Next".
6 de febrero de 2008
Tema 5
15
Selecciona "Multifunctional Database" y pulsa "Next"
Pulsa "Next".
6 de febrero de 2008
Tema 5
16
Selecciona "Decisin Support" y pulsa "Next".
Marca las dos opciones y no cambies el puerto. Despus pulsa "Next".
6 de febrero de 2008
Tema 5
17
Selecciona "Standard Character Set" y pulsa "Next".
Indica que se instale como servicio y que se arranque automticamente. As no tendrs que levantar la base de datos cada vez que se arranques el ordenador. Pulsa "Next".
6 de febrero de 2008
Tema 5
18
Establece una contrasea, por ejemplo "password", y no habilites el acceso como root desde otras mquinas. Pulsa "Next".
Pulsa "Execute".
6 de febrero de 2008
Tema 5
19
Pulsa "Finish" y ya tenemos el Sistema de Gestin de Bases de Datos instalado. En el siguiente apartado crearemos una base de datos sencilla y haremos una aplicacin sencilla que trabaje sobre esa base de datos.
6 de febrero de 2008
Tema 5
20
4 Ejemplo de JDBC en Aplicaciones JAVA
Hasta el momento hemos visto en qu consiste la tcnica ORM y hemos visto la utilizacin bsica de JDBC. Con estos conceptos y con los conocimientos de SQL que tenemos, ya estamos listos para hacer nuestra primera aplicacin que se comunique con base de datos a travs del API JDBC. Este ejemplo demuestra como conectar una aplicacin JAVA (sin usar J2EE). La idea que vamos a seguir es crear una base de datos con una tabla que tenga unos campos. Despus crearemos una aplicacin JAVA que se conecte a esa base de datos, que inserte unos cuantos registros, que luego los consulte, los escriba en pantalla y luego los elimine. Para ello, lo primero que haremos ser crear la base de datos sobre la MySQL que instalamos antes en el tema. Para hacerlo, conectmonos a ella desde una ventana de MS-DOS, situndonos en el directorio "bin" de nuestra instalacin de MySQL y ejecutando la instruccin "mysql -u root -p" e introduciendo el password de la base de datos como vemos en la imagen:
Una vez dentro de la consola de MySQL ejecutemos los comandos que se muestran en la imagen para crear una base de datos, para activar su uso y para crear una tabla en ella.
6 de febrero de 2008
Tema 5
21
Con esto ya tenemos creada una base de datos llamada "jdbcdbjava" con una tabla llamada "mitabla" con dos campos de tipo texto llamados "nombre" y "apellidos". Para salir de la consola de mysql escribe el comando "exit" y pulsa enter. As volveremos a la ventana de MS-DOS. Ya podemos cerrar esta ventana ya que no nos har falta. Ahora vamos a hacer el programa java que se conectar y operar sobre ella. Para ello sigamos los siguientes pasos: Crea un proyecto Java tal y como se v en la siguiente imagen.
6 de febrero de 2008
Tema 5
22
Selecciona Java - Java Project y pulsa Next.
6 de febrero de 2008
Tema 5
23
Inserta los datos tal y como se muestran en la imagen superior y pulsa Next. En la pantalla siguiente, pulsa Add External JARs y selecciona el jar del driver de mysql (si no lo tienes o no ests seguro pincha aqu para descargar el driver). Finalmente te debe quedar la pantalla como muestra la siguiente imagen.
6 de febrero de 2008
Tema 5
24
Cuando hayas seleccionado el driver, pincha Finish. Una vez creado el proyecto, creemos una clase con el mtodo "main" como se muestra en la siguiente imagen:
6 de febrero de 2008
Tema 5
25
Pincha en Finish. Meter el cdigo apropiado en la clase para que quede como sigue (es suficiente si sustituyes el contenido de la clase con el siguiente): import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class MiClase {
6 de febrero de 2008
Tema 5
26
public static void main(String[] args) { System.out.println("inicio"); try { Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnection("jdbc:mysql://localhost/jdbcdbjava", "root", "password"); Statement stmt = con.createStatement(); stmt.executeUpdate("insert into mitabla values ('Toito','Garcia')"); stmt.executeUpdate("insert into mitabla values ('Pepito','Prez Lpez')"); ResultSet rs = stmt.executeQuery("select * from mitabla"); while (rs.next()) System.out.println("Nombre: " + rs.getString(1) + ", Apellidos: " + rs.getString(2)); stmt.executeUpdate("delete from mitabla"); rs = stmt.executeQuery("select count(*) from mitabla"); while (rs.next()) System.out.println("Nmero de registros tras el borrado: " + rs.getInt(1)); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } System.out.println("fin"); } } Ejecuta la clase pinchando en el editor con el botn derecho, despus Run As - Java Application. En la consola el resultado que debemos obtener es el siguiente: inicio Nombre: Toito, Apellidos: Garcia Nombre: Pepito, Apellidos: Prez Lpez Nmero de registros tras el borrado: 0 fin Pues ya hemos visto un ejemplo sencillo de uso de JDBC. Ahora llega el momento de que experimentes. Prueba con "PreparedStatement", con transacciones, crea campos de tipos distintos a cadenas de texto (fechas, valores enteros, decimales, etc.).
6 de febrero de 2008
Tema 5
27
5 Ejemplo de JDBC en Aplicaciones J2EE
En una aplicacin Web. Perfectamente podramos meter el cdigo del ejemplo anterior en un servlet de modo que se ejecutara cuando es llamado, pero sta no es la forma ms correcta de hacerlo ya que el rendimiento no es el apropiado. Veamos el porqu. PROBLEMA: Una de las operaciones ms lentas al trabajar con bases de datos es crear la conexin. La razn es que cuando se establece una conexin, el sistema de gestin de bases de datos (en nuestro ejemplo MySQL) tiene que realizar una serie de operaciones muy costosas. Adems, en la parte java, se debe cargar el driver, crear un objeto de tipo conexin, inicializarla, abrirla, etc. Por lo tanto, si metiramos ese cdigo en el servlet, todas estas operaciones se ejecutaran en cada llamada al servlet. SOLUCIN: La forma que se emplea para resolver esta problemtica es la definicin de un "pool" de conexiones. Esto es tan sencillo como definir un conjunto de conexiones ya establecidas y guardarlas en un "pool" que mantendr nuestro servidor de aplicaciones (Tomcat en nuestro caso). Por lo tanto, nuestra aplicacin, en lugar de crear la conexin como en el ejemplo anterior, lo que har ser pedirle al servidor de aplicaciones que nos d una y la utilizar, consiguiendo as una optimizacin muy importante y bsica en las aplicaciones actuales. Tras su utilizacin, la aplicacin la devuelve al servidor para que la vuelva a entregar en el momento que nuestra aplicacin, u otra, se la pida de nuevo al servidor. Una vez visto esto, las tareas a realizar para crear este ejemplo son los siguientes: - Crear el pool de conexiones. Esto se hace mediante la creacin de un DataSource que es el interfaz mediante el cual se accede a un pool de conexiones. - Crear la aplicacin Web con un servlet en el que meteremos el cdigo que har el trabajo con base de datos (ya veremos los cambios a introducir para emplear el DataSource) - Probar la aplicacin. Pues empecemos con el ejemplo. Creemos primero una aplicacin Web. Para ello sigamos los siguientes pasos.
6 de febrero de 2008
Tema 5
28
Selecciona en el cuadro de dilogo de "New Project" el tipo "Web-Dynamic Web Project". Luego pulsa Next.
6 de febrero de 2008
Tema 5
29
Pon el nombre que se muestra en la imagen anterior y pulsa Next.
6 de febrero de 2008
Tema 5
30
Asegurate de que las opciones seleccionadas son las que se muestran arriba y pulsa Next.
6 de febrero de 2008
Tema 5
31
Pulsa Finish. Con esto ya tenemos la aplicacin Web pero est vaca. En la aplicacin creemos un servlet llamado "CursoServlet" en el paquete "miServlet". Para ello creemos un paquete como se ve en la siguiente imagen:
6 de febrero de 2008
Tema 5
32
Pulsa Finish
6 de febrero de 2008
Tema 5
33
Asigna los valores de la imagen y pulsa Finish. Con esto ya habremos creado el servlet en el paquete que queremos. En este servlet deberamos meter el cdigo que pedir al servidor de aplicaciones la conexin del pool pero primero creemos el pool mediante la definicin de un datasource. Para ello, creemos el fichero context.xml dentro del directorio META-INF que ser el fichero que leer el servidor de aplicaciones. Mediante este fichero le decimos al servidor que cree el datasource. El contenido del fichero context.xml debe ser el siguiente: <Context path="/cursoJDBCWeb" docBase="cursoJDBCWeb" debug="5" reloadable="true" crossContext="true"> <Resource name="jdbc/mysqlDS" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="root" password="password" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/jdbcdbjava"/> </Context> Al leer este fichero el servidor entiende, de forma resumida, lo siguiente: - En el contexto de aplicacin "/cursoJDBCWeb" (nuestro contexto) se define un recurso (etiqueta 6 de febrero de 2008 Tema 5 34
resource). - El nombre del recurso es "jdbc/mysqlDS" (nombre del recurso que solicitaremos mediante JNDI). - El recurso es de tipo (type) Datasource. - El Datasource usar como driver la clase "com.mysql.jdbc.Driver", que deber encontrarse en el directorio lib del servidor tal y como dice la documentacin de MySQL. - La URL de conexin ser "jdbc:mysql://localhost/jdbcdbjava" y usar como usuario "root" y su contrasea es "password". - El resto de parmetros son de configuracin y optimizacin pero escapan de los objetivos del curso. Con este fichero ya tenemos definido el datasource que nos crea el pool de conexiones, solo nos falta, para que el servidor encuentre la clase del driver, meter el fichero "mysql-connectorjava-5.0.7-bin.jar " (lo debis tener en vuestro disco ya que se ha usado anteriormente en el tema) en el directorio de libreras de tomcat (por ejemplo, "C:\apache-tomcat-6.0.14\lib") tal y como dice la documentacin de MySQL. Pues ya tenemos preparado el servidor para que cree el datasource al arrancar la aplicacin. Ahora tenemos que meter el cdigo para usarlo. Para ello, modificamos el servlet para que quede como el siguiente cdigo: package miServlet; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; /** * Servlet implementation class for Servlet: CursoServlet * */ public class CursoServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { static final long serialVersionUID = 1L; /* (non-Java-doc) * @see javax.servlet.http.HttpServlet#HttpServlet() */ public CursoServlet() {
6 de febrero de 2008
Tema 5
35
super(); } /* (non-Java-doc) * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("Entrada en el servlet"); try { Context ctx = null; try { ctx = new InitialContext(); } catch (NamingException e) { e.printStackTrace(); } if(ctx == null ) throw new ServletException("Boom - No Context"); DataSource ds = null; try { ds = (DataSource)ctx.lookup("java:comp/env/jdbc/mysqlDS"); } catch (NamingException e) { e.printStackTrace(); } if (ds == null) throw new ServletException("Boom - No Datasource"); Connection con = ds.getConnection(); Statement stmt = con.createStatement(); stmt.executeUpdate("insert into mitabla values ('Toito','Garcia')"); stmt.executeUpdate("insert into mitabla values ('Pepito','Prez Lpez')"); ResultSet rs = stmt.executeQuery("select * from mitabla"); while (rs.next()) System.out.println("Nombre: " + rs.getString(1) + ", Apellidos: " + rs.getString(2)); stmt.executeUpdate("delete from mitabla"); rs = stmt.executeQuery("select count(*) from mitabla"); while (rs.next()) 6 de febrero de 2008 Tema 5 36
System.out.println("Nmero de registros tras el borrado: " + rs.getInt(1)); } catch (SQLException e) { e.printStackTrace(); } System.out.println("Salida del servlet"); } } Lo ms reseable es la forma en que se consigue la conexin con la base de datos. Si en el ejemplo de aplicacin java se cargaba el driver y se le peda la conexin, en J2EE, para aprovechar la optimizacin del pool, debemos buscar por JNDI el datasource y a ese datasource le debemos pedir la conexin. Por ahora ya tenemos el datasource creado y el cdigo que lo usa, ahora nos falta definir el servlet y el datasource en el fichero web.xml y despus probar. Para ello, el fichero web.xml debe quedar del siguiente modo: <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>cursoJDBCWeb</display-name> <servlet> <servlet-name>CursoServlet</servlet-name> <servlet-class>miServlet.CursoServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CursoServlet</servlet-name> <url-pattern>/CursoServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <resource-ref> <description>Conexion a MySQL</description> <res-ref-name>jdbc/mysqlDS</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> 6 de febrero de 2008 Tema 5 37
</resource-ref> </web-app> Ya ha llegado el momento de probarlo, para ello aadamos el proyecto al tomcat del siguiente modo:
6 de febrero de 2008
Tema 5
38
Aadir el proyecto y pinchar Finish Y ahora arranquemos el servidor de aplicaciones, recemos y abramos un navegador donde pediremos esta url: http://localhost:8080/cursoJDBCWeb/CursoServlet El resultado deber ser una pantalla en blanco ya que no hemos aadido nada de presentacin pero lo importante es que se ejecutar el cdigo que hemos introducido en el servlet sacando por la consola del servidor las siguientes lneas: Entrada en el servlet Nombre: Toito, Apellidos: Garcia Nombre: Pepito, Apellidos: Prez Lpez Nmero de registros tras el borrado: 0 Salida del servlet Como podemos ver, se insertaron los dos registros y luego se borraron. Al igual que en el ejemplo anterior, sera interesante que ahora hagis pruebas similares al ejemplo de JDBC sobre Java.
6 de febrero de 2008
Tema 5
39
6 Frameworks
6.1 Introduccin
Con lo visto hasta el momento en el tema, ya somos capaces de trabajar sobre una base de datos consiguiendo as que los datos que maneja nuestra aplicacin se persistan. Realmente lo que estamos haciendo es mapear los datos de nuestros objetos de modelo de negocio en una base de datos relacional. La tarea del mapeo de objetos a base de datos dentro de un proyecto de cierta envergadura es una de las ms laboriosas y ms an si no usamos la tecnologa y tcnica apropiadas. Acometer este trabajo empleando solamente el API de JDBC es muy complicado debido a la interrelacin de entidades, control de restricciones en los datos, etc. Y adems, todo se complica en los cambios de requisitos o en el mantenimiento de la aplicacin, cuando aparecen nuevos objetos del modelo de negocio, o cuando los ya existentes cambian sus campos. Para intentar facilitar este mapeo de objetos a base de datos han aparecido infinidad de tecnologas, patrones, frameworks, etc. En este tema vamos a ver, a modo de introduccin, dos de las principales soluciones que existen (Hibernate y JDO).
6.2
JDO
El API Java Data Objects (JDO) es un modelo de abstraccin de persistencia basado en interfaces. La tecnologa JDO, desde el punto de vista del programador, es til para persistir el modelo de negocio en una base de datos. JDO es un modelo que tiene varias implementaciones. Los beneficios que nos proporciona JDO son los siguientes: - Facilidad de uso: Los programadores se centran en el modelo de objetos de la aplicacin delegando la persistencia del mismo a la implementacin de JDO que emplee. - Portabilidad: Las aplicaciones escritas siguiendo el API JDO pueden ser ejecutadas con las diferentes implementaciones sin necesidad de recompilar o cambiar cdigo. - Independencia sobre la base de datos: Las aplicaciones escritas con el API JDO son independientes de la base de datos sobre la que se realice la persistencia. - Rendimiento: Las aplicaciones que emplean el API JDO pueden delegar en ste la optimizacin de las operaciones de persistencia. - Integracin con EJBs: Las aplicaciones que emplean JDO pueden aprovechar los beneficios de los EJBs como, por ejemplo, procesamiento remoto, coordinacin distribuida de transacciones y 6 de febrero de 2008 Tema 5 40
seguridad.
6.3
Hibernate
Trabajar con software orientado a objetos y bases de datos relacionales puede ser un gran problema, llegando a consumir gran parte del tiempo de desarrollo en las aplicaciones actuales. Para ello, al igual que otros muchos frameworks, Hibernate proporciona al programador un entorno que facilita mucho el desarrollo en este tipo de aplicaciones. Hibernate es una herramienta que implementa la tcnica ORMapping en entornos Java. Hibernate no solo se encarga de mapear clases Java en tablas de bases de datos, adems tambin se encarga de gestionar los tipos de datos de Java a los tipos del Sistema de Gestin de Base de Datos que se emplee (Oracle, MySQL, DB2, etc.). Adems, Hibernate proporciona funcionalidades para la manipulacin de datos, reduciendo en gran medida el esfuerzo necesario para el desarrollo de las aplicaciones actuales. Por otro lado, Hibernate no siempre es la solucin apropiada. Por ejemplo, Hibernate no es la mejor solucin cuando las aplicaciones se basan en procedimientos almacenados en base de datos para implementar la lgica de negocio. Otra de las grandes ventajas es que Hibernate te aisla del Sistema de Gestion de Base de Datos. Por ejemplo, el desarrollador puede hacer su aplicacin sobre Hibernate y ste se encarga de utilizar el "dialecto SQL" apropiado sobre la base de datos que situemos bajo l. Para una mayor informacin sobre este framework que implementa la tcnica ORM visitar http://www.hibernate.org/152.html
6 de febrero de 2008
Tema 5
41