Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
HIBERNATE
HIBERNATEÍNDICE1     INTRODUCCIÓN ...........................................................................................
HIBERNATE   1. INTRODUCCIÓN   1.1.OBJECT-RELATIONAL MAPPINGHibernate es una implementación de mapeo Objeto-Relacional (ORM...
HIBERNATEEste tipo de sistema facilita todas las operaciones de persistencia y acceso a los datos desde laaplicación al pr...
HIBERNATE    1.2.HIBERNATE Y MVC EN ENTORNOS WEBEn una arquitectura MVC genérica como la siguiente, Hibernate juega un pap...
HIBERNATEController (Controlador):        Servlet central que recibe las peticiones, procesa la URL recibida y delega el  ...
HIBERNATE    2. MI PRIMERA APLICACIÓN CON HIBERNATEEsta parte del manual es una guía paso a paso para realizar una aplicac...
HIBERNATE2.3.DESARROLLO PASO A PASO1. Determinar el modelo de datos de la aplicación.   Este ejemplo se trata de una senci...
HIBERNATEcon la gestión de Drivers NO es propio de Hibernate, se está configurando el entornode Netbeans para la utilizaci...
HIBERNATE   Los datos que se completan son los correspondientes a la conexión con la base de   datos que se encuentra en e...
HIBERNATEAl crear el proyecto, Netbeans crea un fichero hibernate.cfg con los valores para conectarcon la Base de datos qu...
HIBERNATE    3. Definir las clases de persistencia.        El paso siguiente es añadir clases para representar a los eleme...
HIBERNATE        funcionalidades de Hibernate. El constructor sin argumentos también es un requisito        para todas las...
HIBERNATEEl nombre del fichero (Event.hbm.xml) coincidirá con el nombre de la clase que mapeay se guardará habitualmente e...
HIBERNATE      Solamente queda seleccionar la clase y la tabla a mapear. En este caso no se puede      especificar ninguna...
HIBERNATEAlgunos detalles sobre este archivo:       <class name="events.Event" table="EVENTS">       Aunque inicialmente e...
HIBERNATE              <property name="date" type="timestamp" column="EVENT_DATE"/>              La siguiente propiedad en...
HIBERNATE   5. Configurar Hibernate.       Hasta el momento se han creado las clases para representar los objetos de la Ba...
HIBERNATE        <session-factory name="session1">        Indica el session factory utilizado en la aplicación. Si la apli...
HIBERNATE6. Crear clases de ayuda.   Una vez que se ha configurado Hibernate, ya se puede escribir el código Java para el ...
HIBERNATEpackage util;import org.hibernate.cfg.Configuration;import org.hibernate.SessionFactory;public class HibernateUti...
HIBERNATE       Cuando una clase de la aplicación quiera acceder a la sesión actual, simplemente       invocará al método ...
HIBERNATELos métodos que se han definido son los siguientes, los cuales se describen paracomprobar la sencillez de las acc...
HIBERNATE         3. Obtener el conjunto de resultados: se obtiene una colección (List) de instancias de la             cl...
HIBERNATEA continuación se crea el Servlet que se encargará de la lógica de la aplicación. Paracrear un Servlet Netbeans t...
HIBERNATE        Para ejecutar la aplicación simplemente usar la opción Run       Run Main Project (F6).public class Servl...
HIBERNATE9. Asociar clases.   La asociación entre clases es uno de los aspectos más importantes de Hibernate, así   como l...
HIBERNATEprivate Set events = new HashSet();public Set getEvents() {        return events;}public void setEvents(Set event...
HIBERNATEPerson aPerson = (Person) session.load(Person.class, personId);aPerson.getEvents();       Esta utilidad es sufici...
HIBERNATE         Para ello, en la clase Event se establece también una propiedad de tipo Set que         almacenará los d...
HIBERNATE        Gracias a esta nueva relación se pueden conocer las personas que pertenecen a un        determinado event...
HIBERNATEpublic class ServletP extends HttpServlet {        protected void processRequest(HttpServletRequest request,     ...
HIBERNATE         private void mostrarTabla(PrintWriter out, Set lista) {                 out.println("<table>");         ...
HIBERNATEEl código del Servlet resulta sencillo ya que toda la lógica de interacción con Hibernate seencuentra en las clas...
HIBERNATEpublic class EventManager {       /**        * Almacenar un evento        * @param title título        * @param t...
HIBERNATE          Event anEvent = (Event) session.createCriteria(Event.class).              setFetchMode("participants", ...
HIBERNATE         (setFetchMode("participants", FetchMode.JOIN)) y para cada uno de dichos         participantes, que en s...
HIBERNATE   3. FRAMEWORK HIBERNATE   3.1.INTRODUCCIÓNEn el desarrollo de una aplicación J2EE se trabaja continuamente con ...
HIBERNATE   3.2.INSTALACIÓNIMPORTANTE:Este apartado sirve como guía de ayuda de instalación manual de Hibernate para su us...
HIBERNATE<?xml version=”1.0” encoding=”UTF-8”?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configurat...
HIBERNATEEste archivo es leído por el framework cuando arranca y contiene los siguientes elementos:       Sesiones: sessio...
HIBERNATE               Propiedades de conexión: otras propiedades de la conexión.hibernate.jdbc.fetch_size               ...
HIBERNATE       Propiedades de caché: gestión de la caché de segundo nivel.                                           Nomb...
HIBERNATE        Otras propiedades.                                        Estrategia para          jta                   ...
HIBERNATELos ficheros de mapeo normalmente incluyen el nombre de la tabla y clase relacionadas, y eldetalle del mapeo entr...
HIBERNATE             d. default-access (opcional – property por defecto): estrategia de acceso a las                  pro...
HIBERNATEa. name (opcional): nombre completo de la clase o interfaz Java. También se     pueden hacer persistentes clases ...
HIBERNATE              o. optimistic-lock (opcional – version por defecto): determina la estrategia de                   b...
HIBERNATE           d. unsaved-value (opcional): valor del identificador que indica que la instancia es               nuev...
HIBERNATE                viii. native: selecciona identity, sequence o hilo dependiendo de la base de                     ...
HIBERNATE          e. key-property: dentro de la etiqueta composite-id, indica cada uno de los campos               que fo...
HIBERNATE      a. name: nombre de la propiedad (primera letra siempre en minuscule).      b. column (opcional – nombre de ...
HIBERNATE<many-to-one      name="propertyName" (a)      column="column_name" (b)      class="ClassName" (c)      cascade="...
HIBERNATE          h. property-ref (opcional): nombre de la propiedad de la clase asociada relacionada               con e...
HIBERNATE       c. cascade (opcional): operaciones que deben ejecutarse en cascada desde el            padre al objeto aso...
HIBERNATE<set         name="propertyName" (a)         table="table_name" (b)         schema="schema_name" (c)         lazy...
HIBERNATE           h. order-by (opcional): solo en JDK 1.4, especifica un nombre de columna que                define el ...
HIBERNATE                      v. update (opcional): las claves foráneas no se pueden actualizar.                     vi. ...
HIBERNATE        detached: persistente previamente, no asociado con ninguna sesión. Se encuentra en        la Base de dato...
HIBERNATE//Obtener la sesión actualSession session = HibernateUtil.getSessionFactory().getCurrentSession();try{          /...
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Manual hibernate v2
Prochain SlideShare
Chargement dans…5
×

Manual hibernate v2

5 229 vues

Publié le

  • Soyez le premier à commenter

Manual hibernate v2

  1. 1. HIBERNATE
  2. 2. HIBERNATEÍNDICE1 INTRODUCCIÓN .................................................................................................................... 3 1.1 Object-Relational Mapping.......................................................................................... 3 1.2 Hibernate y MVC en entornos web ............................................................................. 52 MI PRIMERA APLICACIÓN CON HIBERNATE ......................................................................... 7 2.1 Pasos para crear una aplicación Hibernate ................................................................. 7 2.2 Desarrollo paso a paso................................................................................................. 83 FRAMEWORK HIBERNATE .................................................................................................. 38 3.1 Introducción............................................................................................................... 38 3.2 Instalación.................................................................................................................. 39 3.3 Configuración............................................................................................................. 39 3.4 El interfaz Session ...................................................................................................... 584 ASOCIACIONES.................................................................................................................... 62 4.1 Relaciones en Bases de datos .................................................................................... 63 4.2 Many-to-one .............................................................................................................. 65 4.3 Many-to-many ........................................................................................................... 67 4.4 One-to-one................................................................................................................. 695 RECUPERACIÓN DE DATOS ................................................................................................. 71 5.1 HQL ............................................................................................................................ 73 5.2 Criteria ....................................................................................................................... 83 5.3 SQL ............................................................................................................................. 89 [2]
  3. 3. HIBERNATE 1. INTRODUCCIÓN 1.1.OBJECT-RELATIONAL MAPPINGHibernate es una implementación de mapeo Objeto-Relacional (ORM – Object-RelationalMapping). El objetivo de un ORM es hacer corresponder el modelo de datos de la aplicacióncon el modelo de clases de la misma, los cuales no son tan distintos como se pueda pensar.Para ello, Hibernate realiza el mapeo de elementos (tablas, columnas) entre una Base de datosrelacional y objetos de la aplicación en cuestión: Base de Datos Relacional Modelo de Objetos TABLA Persona Persona Nombre Apellido Teléfono Juan López 666111122 -String nombre -String apellido Ana Hurtado 959121212 -String teléfono Francisco Soria 889121212 Belén Jiménez 789456123 instance: Persona nombre = Juan apellido = López teléfono = 666111122 [3]
  4. 4. HIBERNATEEste tipo de sistema facilita todas las operaciones de persistencia y acceso a los datos desde laaplicación al presentar las siguientes características principales: Independiente de SQL: Hibernate incorpora funcionalidades para las operaciones simples de recuperación y actualización de datos para las cuales no será necesario utilizar las sentencias SELECT, INSERT, UPDATE o DELETE habituales, siendo sustituidas por llamadas a métodos (list, save, update, delete, …). Hibernate se encarga de generar la sentencia SQL que se encargará de realizar tales operaciones. De cualquier modo, se pueden especificar consultas SQL en caso necesario o incluso consultas en el dialecto de Hibernate, el HQL, con sintaxis similar a SQL pero que establece una serie de elementos propios del sistema ORM que gestiona. Independiente del SGBD: al aislar las funciones de manipulación de datos del lenguaje SQL, se consigue que la aplicación pueda comunicarse con cualquier SGBD ya que no existirán dependencias o particularidades en las sentencias de consulta o actualización de datos que harían a la aplicación dependiente de un SGBD en cuestión. El encargado de realizar la traducción final entre las operaciones Objeto-relacionales y las sentencias SQL es Hibernate, con lo cual el problema de la compatibilidad queda solventado. Incorpora soporte para la mayoría de los sistemas de bases de datos existentes. Independiente de JDBC: Hibernate contiene una API completa que aísla a la aplicación, no solamente de las operaciones con lenguaje SQL, sino también la utilización de objetos propios de la gestión de Bases de datos JDBC (Statement, ResultSet, …). Este tipo de objetos habituales en la programación Java de acceso a Bases de datos, se sustituye por el uso de objetos mucho más sencillos como colecciones de clases tipo JavaBeans que contendrán los datos de los almacenes de datos. [4]
  5. 5. HIBERNATE 1.2.HIBERNATE Y MVC EN ENTORNOS WEBEn una arquitectura MVC genérica como la siguiente, Hibernate juega un papel primordialcomo capa de persistencia de la aplicación. Como aparece en el esquema, los JavaBeansencargados de ejecutar la lógica de la aplicación interacturán con datos habitualmentealmacenados en una Base de datos. Hibernate se introduce en este contexto para dar soportede acceso y gestión de los datos a la capa de Modelo.El patrón MVC se utiliza de forma amplia en el desarrollo de aplicaciones web.Fuente: http://java.sun.com/blueprints/patterns/MVC-detailed.html [5]
  6. 6. HIBERNATEController (Controlador): Servlet central que recibe las peticiones, procesa la URL recibida y delega el procesamiento a los JavaBeans. Servlet que almacena el resultado del procesamiento realizado por los JavaBeans en el contexto de la petición, la sesión o la aplicación. Servlet que transfiere el control a un JSP que lleva a cabo la presentación de resultados.Model (Modelo): JavaBeans (o EJBs para aplicaciones más escalables) que desempeñan el rol de modelo: Algunos beans ejecutan lógica. Otros guardan datos. Normalmente: El Servlet Controller invoca un método en un bean de lógica y éste devuelve un bean de datos. El programador del JSP tiene acceso a beans de datos.View (Vista): Rol ejecutado por JSPs. El Servlet Controller transfiere el control al JSP después de guardar en un contexto el resultado en forma de un bean de datos. JSP usa jsp:useBean y jsp:getProperty para recuperar datos y formatear respuesta en HTML o XML.En resumen: Los JavaBeans o EJBs ejecutan la lógica de negocio y guardan los resultados. Los JSPs proporcionan la información formateada. Los servlets coordinan/controlan la ejecución de los beans y los JSPs. [6]
  7. 7. HIBERNATE 2. MI PRIMERA APLICACIÓN CON HIBERNATEEsta parte del manual es una guía paso a paso para realizar una aplicación sencilla, es tal vez lamejor manera de introducirse con Hibernate y es recomendable realizarla antes de leer elresto del manual ya que mejorará la comprensión de éste.Esta aplicación será desarrollada haciendo uso del IDE Netbeans 6.7. Se puede descargar dehttp://netbeans.org/. 2.2.PASOS PARA CREAR UNA APLICACIÓN HIBERNATEEstos son los pasos mínimos que se deberán seguir para desarrollar la aplicaciónsatisfactoriamente. 1. Determinar el modelo de datos de la aplicación. 2. Añadir las librerías Java de Hibernate. 3. Definir las clases de persistencia. 4. Crear los ficheros de mapeo. 5. Configurar Hibernate. 6. Crear clases de ayuda. 7. Cargar y guardar objetos. 8. Ejecutar la primera versión. 9. Asociar clases. 10. Ejecutar la aplicación. [7]
  8. 8. HIBERNATE2.3.DESARROLLO PASO A PASO1. Determinar el modelo de datos de la aplicación. Este ejemplo se trata de una sencilla introducción donde únicamente se dispone de dos clases Event y Person tanto en la base de datos del sistema como en el modelo de objetos de la aplicación. También se usarán clases auxiliares para la gestión del acceso y operaciones con los datos. En primer lugar, es necesario crear la Base de datos en MySQL. Su nombre será FirstApp pero no se van a crear tablas en la misma ya que se configurará una opción en el fichero de configuración de Hibernate (hibernate.cfg.xml) para que genere el esquema de la Base de datos al desplegar la aplicación. Como se ha comentado, la aplicación se creará a través de Netbeans. Este entorno de desarrollo dispone de herramientas para la configuración del acceso a la Base de datos. En primer lugar es posible que sea necesario configurar el driver de la base de datos que se va a utilizar en la aplicación, en este caso MySQL. Para ello es necesario seleccionar la opción New Connection… del menú del botón derecho del ratón sobre la opción Drivers. A continuación se selecciona el fichero .jar que contiene el driver de MySQL y se dejan el resto de campos con los valores que aparecen al seleccionarlo. Todo lo relacionado [8]
  9. 9. HIBERNATEcon la gestión de Drivers NO es propio de Hibernate, se está configurando el entornode Netbeans para la utilización de los Asistentes existentes.Ahora hay que crear la conexión desde la pestaña Services seleccionando la opciónNew Connection… del menú del botón derecho del ratón sobre la opción Databases. [9]
  10. 10. HIBERNATE Los datos que se completan son los correspondientes a la conexión con la base de datos que se encuentra en el servidor MySQL.2. Añadir las librerías Java de Hibernate. Netbeans dispone de un asistente para la creación de aplicaciones Web donde se puede indicar que la aplicación empleará Hibernate. De esta forma, Netbeans realiza una serie de acciones de forma automática que ayudarán al desarrollo mediante este Framework. Se deberá crear un nuevo proyecto web con Netbeans, para ello dirigirse al menú: File New Project Web Web Application. No se debe olvidar añadir el Framework, como muestran las imágenes siguientes. [10]
  11. 11. HIBERNATEAl crear el proyecto, Netbeans crea un fichero hibernate.cfg con los valores para conectarcon la Base de datos que se ha establecido al crear el proyecto. Dicho archivo se encuentraen la carpeta Source Packagesdefault package de la aplicación. [11]
  12. 12. HIBERNATE 3. Definir las clases de persistencia. El paso siguiente es añadir clases para representar a los elementos de la Base de datos. La clase Event (paquete events) es una clase tipo JavaBean sencilla, cuyas propiedades coinciden con los campos de la tabla Events que existirá en la Base de datos.package events;import java.util.Date;public class Event { private Long id; private String title; private Date date; public Event() { } public Long getId() { return id; } private void setId(Long id) { this.id = id; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }} La propiedad id representa el identificador único para un evento. Todas las clases de persistencia deben tener un identificador si se quiere utilizar el conjunto completo de [12]
  13. 13. HIBERNATE funcionalidades de Hibernate. El constructor sin argumentos también es un requisito para todas las clases persistentes. Se recomienda en la mayoría de las ocasiones utilizar clases para representar los tipos de los atributos en lugar de utilizar tipos básicos, debido a que para aquellos campos que se permitan valores nulos en la Base de datos, la representación del valor del campo será natural en la representación Java (null), mientras que con tipos básicos podría resultar en un error. En el paquete events también se introducirá la clase Person, la cual se representará de forma similar por el momento:package events;public class Person { private Long id; private int age; private String firstname; private String lastname; public Person() { } // getters y setters para todas las propiedades} 4. Crear los ficheros de mapeo. Para cada una de las clases de persistencia tiene que existir un fichero de mapeo que se encarga de definir la relación entre las tablas y columnas de éstas en la Base de datos, y las clases y sus propiedades en el modelo de objetos. En Netbeans existe una utilidad para mapear las clases con las tablas de la Base de datos de forma automática. Para ello, seleccionar la opción New Other Hibernate Hibernate Mapping File [13]
  14. 14. HIBERNATEEl nombre del fichero (Event.hbm.xml) coincidirá con el nombre de la clase que mapeay se guardará habitualmente en el mismo paquete donde se encuentra dicha clase. [14]
  15. 15. HIBERNATE Solamente queda seleccionar la clase y la tabla a mapear. En este caso no se puede especificar ninguna tabla ya que la Base de datos se encuentra vacía. Al pulsar Finish se genera un archivo de mapeo, al cual es necesario añadir el nombre de la tabla que está mapeando, y completar con los datos del mapeo de las columnas.<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="events.Event" table="EVENTS"> <id name="id" column="EVENT_ID"> <generator class="native"/> </id> <property name="date" type="timestamp" column="EVENT_DATE"/> <property name="title"/> </class></hibernate-mapping> [15]
  16. 16. HIBERNATEAlgunos detalles sobre este archivo: <class name="events.Event" table="EVENTS"> Aunque inicialmente el archive se crea con una serie de propiedades para el mapeo (dynamic-insert="false" dynamic-update="false" …) se han eliminado para simplificar el ejemplo. Realmente las únicas propiedades imprescindibles son name (nombre de la clase) y table (nombre de la tabla). <id name="id" column="EVENT_ID"> En primer lugar se declara el identificador. Esta definición se destaca porque se identifica con la etiqueta id. La propiedad name representa el nombre del atributo en la clase, y la propiedad column el nombre del campo en la tabla. <generator class="native"/> Dentro del identificador se declara cómo se gestiona la asignación de ésta. En este caso se ha elegido el valor native, que delega la gestión de la clave en el SGBD utilizado, es decir, que no es necesario preocuparse de la gestión/asignación de claves de forma manual. Existen otras posibilidades de generadores de clave que se estudiarán más adelante en este documento. [16]
  17. 17. HIBERNATE <property name="date" type="timestamp" column="EVENT_DATE"/> La siguiente propiedad en declararse es date. En este caso también name representa el nombre del atributo en la clase, y column el nombre del campo en la tabla. La propiedad type representa el tipo de datos que se va a utilizar, ya que aunque Hibernate es capaz de detectar que este campo se refiere a un valor de tipo Date, es necesario especificar si esa fecha se gestionará como time, date o timestamp. Esta propiedad type sirve para realizar conversiones de tipos si es necesario en la aplicación, de forma que un campo que en la base de datos es numérico se trate como String, o Boolean, … <property name="title"/> Por último se declara el campo title. En este caso solamente se especifica el nombre del atributo de la clase porque el nombre coincide con el nombre de la columna de la tabla de Base de datos, si no sería necesario especificar el nombre de dicha columna. El fichero de mapeo para la clase Person quedará de la siguiente forma:<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="events.Person" table="PERSON"> <id name="id" column="PERSON_ID"> <generator class="native"/> </id> <property name="age"/> <property name="firstname"/> <property name="lastname"/> </class></hibernate-mapping> [17]
  18. 18. HIBERNATE 5. Configurar Hibernate. Hasta el momento se han creado las clases para representar los objetos de la Base de datos y los ficheros de mapeo para las mismas. Para que la aplicación funcione de forma correcta, es necesario configurar Hibernate a través de su fichero de configuración hibernate.cfg.xml. En este fichero se establecerá al menos la conexión con la base de datos, y se especificarán cuáles son los ficheros de mapeo que se están empleando en la aplicación, es decir, que si un fichero de mapeo no aparece en hibernate.cfg el mapeo no funcionará. El fichero hibernate.cfg se encuentra en el paquete por defecto de la aplicación. Si se abre este fichero con Netbeans, en primer lugar aparece la vista Diseño. Al seleccionar la vista XML (esquina superior izquierda de la ventana) aparecerá el código que Netbeans introdujo por defecto al crear la aplicación y especificar la conexión a la Base de datos que se iba a emplear en la misma:<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration> <session-factory name="session1"> <property name="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property> <property name="hibernate.connection.url"> jdbc:mysql://localhost:3306/firstapp </property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <mapping resource="events/Event.hbm.xml"/> <mapping resource="events/Person.hbm.xml"/> </session-factory></hibernate-configuration> [18]
  19. 19. HIBERNATE <session-factory name="session1"> Indica el session factory utilizado en la aplicación. Si la aplicación accede a más de una Base de datos es necesario declarar más de un session-factory, cada uno de ellos identificado por un nombre distinto. <property name="hibernate.dialect"> La propiedad dialect indica la variante de SQL que Hibernate genera a la hora de acceder a la Base de datos. Además de los datos de la conexión a la Base de datos y los ficheros de mapeo de la aplicación (que Netbeans ha introducido de forma automática al crear los propios ficheros hbm), en hibernate.cfg deben aparecer propiedades importantes que definen los siguientes aspectos: current_session_context_class: Hibernate funciona con sesiones para acceder a los datos. Es necesario definir una clase de gestión de sesiones para poder realizar operaciones con la Base de datos. cache.provider_class: especifica el comportamiento de la Caché de 2º nivel. show_sql: mostrar en los logs las sentencias SQL que Hibernate lanza cada vez que realiza una operación con la Base de datos. hbm2ddl.auto: crear el esquema de la Base de datos de forma automática al desplegar la aplicación. Los valores a añadir a hibernate.cfg para el ejemplo son los siguientes:<!-- Enable Hibernates automatic session context management--><property name="current_session_context_class">thread</property><!-- Disable the second-level cache --><property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property><!-- Echo all executed SQL to stdout --><property name="show_sql">true</property><!-- Drop and re-create the database schema on startup --><property name="hbm2ddl.auto">create</property> [19]
  20. 20. HIBERNATE6. Crear clases de ayuda. Una vez que se ha configurado Hibernate, ya se puede escribir el código Java para el acceso a los datos. Como se ha comentado anteriormente, Hibernate utiliza el concepto de sesión para acceder a los datos, de forma que cualquier operación de consulta o manipulación de los datos debe estar enmarcada en una sesión. Para que la gestión de sesiones quede aislada del resto de operaciones de acceso a datos, y para evitar la duplicidad de código, es habitual generar una clase de ayuda que se encarga de la inicialización de sesiones. Netbeans permite la generación de esta clase a través del menú New Other Hibernate HibernateUtil. En este caso la clase HibernateUtil se incorporará al paquete util. [20]
  21. 21. HIBERNATEpackage util;import org.hibernate.cfg.Configuration;import org.hibernate.SessionFactory;public class HibernateUtil { private static final SessionFactory sessionFactory; static { try { // Create the SessionFactory from hibernate.cfg.xml sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { // Log the exception. System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; }} [21]
  22. 22. HIBERNATE Cuando una clase de la aplicación quiera acceder a la sesión actual, simplemente invocará al método estático getSessionFactory() (HibernateUtil.getSessionFactory()). 7. Cargar y guardar objetos. Para manipular los datos de la Base de datos se va a crear una clase EventManager en el paquete event para el almacenamiento y recuperación de eventos:public class EventManager { public void createAndStoreEvent(String title, Date theDate) { //Obtener la sesión actual Session session = HibernateUtil.getSessionFactory().getCurrentSession(); //Comenzar la transacción session.beginTransaction(); //Crear el evento Event theEvent = new Event(); theEvent.setTitle(title); theEvent.setDate(theDate); //Almacenarlo session.save(theEvent); //Confirmar transacción session.getTransaction().commit(); } public List listEvents() { //Obtener la sesión actual Session session = HibernateUtil.getSessionFactory().getCurrentSession(); //Comenzar la transacción session.beginTransaction(); //Obtener la lista de eventos List result = session.createQuery("from Event").list(); //Confirmar transacción session.getTransaction().commit(); return result; }} [22]
  23. 23. HIBERNATELos métodos que se han definido son los siguientes, los cuales se describen paracomprobar la sencillez de las acciones que realizan: createAndStoreEvent: crea y almacena un evento realizando los siguientes pasos: 1. Acceder a la sesión actual: a través del método estático getSessionFactory() de la clase HibernateUtil creada anteriormente en el proyecto. 2. Abrir una transacción: utilizando la sesión actual. 3. Crear el objeto: de la forma habitual en Java. 4. Almacenar el objeto: simplemente invocando al método save del interfaz Session (sesión actual). 5. Confirmar la transacción: utilizando también la sesión actual. En la siguiente imagen se muestra un esquema del funcionamiento de Hibernate basado en sesiones: listEvents: obtiene una lista de todos los eventos de la Base de datos realizando los siguientes pasos: 1. Acceder a la sesión actual: a través del método estático getSessionFactory() de la clase HibernateUtil creada anteriormente en el proyecto. 2. Abrir una transacción: utilizando la sesión actual. Las consultas a bases de datos también requieren de una transacción en Hibernate. [23]
  24. 24. HIBERNATE 3. Obtener el conjunto de resultados: se obtiene una colección (List) de instancias de la clase Event cuyos datos coincidirán con los datos de los registros existentes en la Base de datos. Existen varias formas de obtener datos de una tabla en Hibernate, en este caso se ha utilizado un Query HQL. Posteriormente se tratarán en profundidad los aspectos relacionados con los distintos tipos de consultas en Hibernate. 4. Confirmar la transacción: utilizando también la sesión actual. 8. Ejecutar la primera versión. Para probar lo que se ha implementado hasta el momento se va a crear una sencilla aplicación Web. Para ello en primer lugar se modificará la página index.jsp del proyecto para que funcione como formulario para introducir los datos:<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <title>JSP Page</title> </head> <body> <form action="Servlet"> <table> <tr> <td>title</td><td><input type="text" name="title"></input></td> </tr> <tr> <td>date</td><td><input type="text" name="date"></input></td> </tr> <tr> <td><input type="submit"/></td> </tr> </table> </form> </body></html> [24]
  25. 25. HIBERNATEA continuación se crea el Servlet que se encargará de la lógica de la aplicación. Paracrear un Servlet Netbeans también dispone de un Asistente a través de la opción New Other Web ServletSu nombre será Servlet y se almacenará en el paquete servlet. En la siguiente pantallase dejan por defecto los parámetros que se añadirán al fichero web.xml. [25]
  26. 26. HIBERNATE Para ejecutar la aplicación simplemente usar la opción Run Run Main Project (F6).public class Servlet extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { EventManager mng = new EventManager(); //Parsear la fecha Date date = new SimpleDateFormat("dd/MM/yyyy"). parse(request.getParameter("date")); mng.createAndStoreEvent(request.getParameter("title"), date); //Mostrar los datos almacenados this.mostrarTabla(out, mng.listEvents()); } catch (Exception ex) { out.println(ex); } finally { out.close(); } } private void mostrarTabla(PrintWriter out, List lista) { out.println("<table>"); Iterator it = lista.iterator(); //Iterar sobre todos los eventos while (it.hasNext()) { Event event = (Event) it.next(); out.println("<tr>"); out.println("<td>" + event.getTitle() + "</td>"); out.println("<td>" + event.getDate() + "</td>"); out.println("</tr>"); } out.println("</table>"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }} [26]
  27. 27. HIBERNATE9. Asociar clases. La asociación entre clases es uno de los aspectos más importantes de Hibernate, así como la asociación entre tablas es la base del modelo relacional de Bases de datos. Este aspecto puede resultar complejo en algunas ocasiones. Posteriormente se tratarán en profundidad los aspectos relacionados con los distintos tipos de asociaciones en Hibernate. En los pasos 3 y 4 se definieron las clases Event y Person a través de código Java y ficheros de mapeo. Ahora es necesario modelar la relación que existe entre ambas a través de una asociación Hibernate. La relación que existe entre ambas tablas es una relación M a M, de forma que a un Evento acudirán varias Personas, y una Persona puede acudir a diversos Eventos. A nivel de Bases de datos, esta relación dará lugar a una tabla intermedia PERSON_EVENT. Esta relación en Hibernate se puede modelar de diversas maneras, y además se puede reflejar de distintas formas en las clases implicadas. En primer lugar, la relación más sencilla que se puede establecer es la relación Unidireccional entre 2 tablas, en este caso entre las tablas Person y Person_Event. Para el ejemplo, el tipo de relación escogido es algo complejo, denominado en Hibernate como relación con tabla intermedia (join table). En el capítulo 4 se explicarán los tipos de relaciones más generales, y la forma de eludir las relaciones complejas, pero es bueno presentar en el ejemplo otro tipos de relaciones que pueden encontrarse en aplicaciones Hibernate. Las relaciones se modelan con colecciones, normalmente conjuntos (Set) de forma que se agregan los fragmentos de código que aparecen a continuación. En la clase simplemente se crea el atributo de la clase Set y se generan los métodos get/set para el mismo. [27]
  28. 28. HIBERNATEprivate Set events = new HashSet();public Set getEvents() { return events;}public void setEvents(Set events) { this.events = events;}<set name="events" table="PERSON_EVENT"> <key column="PERSON_ID"/> <many-to-many column="EVENT_ID" class="events.Event"/></set> En Person.hbm.xml se genera una nueva propiedad para la tabla de tipo conjunto. Los atributos de esa propiedad son los siguientes: name: nombre de la propiedad de la clase a la que hace referencia. table: tabla intermedia de la base de datos. key: clave de la tabla intermedia (PERSON_EVENT) que aporta la clase actual. La propiedad columna es el nombre de la columna de la tabla de Base de datos. Es decir, esta etiqueta significa que el nombre del campo que relaciona a la tabla que modela la clase Person (PERSON) y a la tabla intermedia (PERSON_EVENT) es PERSON_ID, el cual estará relacionado con el campo id de la clase Person (en este caso también se denomina PERSON_ID). many-to-many: indica para la tabla intermedia (PERSON_EVENT) cuál es la otra clase que está implicada en la relación (la clase Event) y cuál es la clave foránea que esta clase aporta a la relación. Con todo esto únicamente se ha posibilitado que a través de una persona concreta, es decir, una instancia de la clase Person, se pueda conocer de forma directa los eventos a los cuales está asociada. En Hibernate esto se traduce en acceder simplemente a los atributos de dicha clase. Por ejemplo, el método getEvents devuelve un Set con los eventos asociados a una persona: [28]
  29. 29. HIBERNATEPerson aPerson = (Person) session.load(Person.class, personId);aPerson.getEvents(); Esta utilidad es suficiente, pero se pueden realizar cosas más avanzadas, como manipular objetos persistentes y luego transformarlos en acciones contra la base de datos. Por ejemplo, el siguiente método asigna un evento a una persona de forma sencilla, sin gestionar claves ni relaciones entre tablas, simplemente a través de la relación normal entre conjuntos:public void addPersonToEvent(Long personId, Long eventId) { //Obtener la sesión actual Session session = HibernateUtil.getSessionFactory().getCurrentSession(); //Comenzar la transacción session.beginTransaction(); //Cargar la persona por clave Person aPerson = (Person) session.load(Person.class, personId); //Cargar el evento por clave Event anEvent = (Event) session.load(Event.class, eventId); //Agregar el evento a la persona aPerson.getEvents().add(anEvent); //Confirmar transacción session.getTransaction().commit();} La línea aPerson.getEvents().add(anEvent) es donde se crea la relación entre ambos elementos, y al realizar la confirmación en la Base de datos se crean los registros necesarios para satisfacer dicha relación. A continuación se va a modelar la relación inversa. Una relación en Hibernate se puede modelar de forma unidireccional o bidireccional. Para el segundo de los casos, se establecen en los ficheros de configuración 2 relaciones, por una parte la relación directa (que corresponde con la que ya se ha generado en el ejemplo), y por la otra parte se modela la relación inversa. Es decir, si en el ejemplo la relación directa servía para conocer cuáles eran los eventos a los que estaba asociada una persona, la relación inversa proporciona información sobre cuáles son las personas que participan en un determinado evento. [29]
  30. 30. HIBERNATE Para ello, en la clase Event se establece también una propiedad de tipo Set que almacenará los datos de las personas asociadas a un evento concreto:private Set participants = new HashSet();public Set getParticipants() { return participants;}public void setParticipants(Set participants) { this.participants = participants;} El mapeo es muy similar al que se estableció para la clase Person, teniendo en cuenta que hay que incluir la propiedad inverse (con valor true): name: nombre de la propiedad de la clase a la que hace referencia. table: tabla intermedia de la base de datos. inverse: en toda relación bidireccional uno de los 2 extremos debe ser inverse=true, lo cual es utilizado por Hibernate a la hora de construir las sentencias SQL para interactuar con la Base de datos. key: el nombre del campo que relaciona a la tabla que modela la clase Event (EVENT) y a la tabla intermedia (PERSON_EVENT) es EVENT_ID, el cual estará relacionado con el campo id de la clase Event (EVENT_ID). many-to-many: indica para la tabla intermedia (PERSON_EVENT) cuál es la otra clase que está implicada en la relación (la clase Person) y cuál es la clave foránea que esta clase aporta a la relación (PERSON_ID).<set name="participants" table="PERSON_EVENT" inverse="true"> <key column="EVENT_ID"/> <many-to-many column="PERSON_ID" class="events.Person"/></set> [30]
  31. 31. HIBERNATE Gracias a esta nueva relación se pueden conocer las personas que pertenecen a un determinado evento. La pregunta es, ¿funcionará correctamente un método como el siguiente?public void addPersonToEvent(Long personId, Long eventId) { //Obtener la sesión actual Session session = HibernateUtil.getSessionFactory().getCurrentSession(); //Comenzar la transacción session.beginTransaction(); //Cargar la persona por clave Person aPerson = (Person) session.load(Person.class, personId); //Cargar el evento por clave Event anEvent = (Event) session.load(Event.class, eventId); //Agregar la persona al evento anEvent.getParticipants().add(aPerson); //Confirmar transacción session.getTransaction().commit();} 10. Ejecutar la aplicación. Para probar todos los conceptos vistos hasta el momento, se crea un nuevo Servlet de la misma forma especificada en el paso 8, donde se realizarán las siguientes pruebas: Cargar eventos por clave (emng.loadEvent(new Long(1))), para comprobar si existe un evento con identificador igual a 1. Almacenar personas (mng.createAndStorePerson(…): almacena una persona de prueba. Agregar personas a eventos (mng.addPersonToEvent(new Long(1), e.getId())): agrega la persona creada anteriormente al evento. Listar participantes de un evento (e.getParticipants()): obtiene la lista de participantes al evento para mostrar sus nombres y la lista de eventos. [31]
  32. 32. HIBERNATEpublic class ServletP extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { PersonManager mng = new PersonManager(); //Comprobar que existe el evento con id=1 EventManager emng = new EventManager(); Event e = emng.loadEvent(new Long(1)); if (e == null) { //No existe el evento out.println("Debe crear un evento"); } else { //Almacenar mng.createAndStorePerson(new Integer(30), "José", "Guardiola"); //Agregar un evento como prueba (id=1) mng.addPersonToEvent(new Long(1), e.getId()); //Refrescar los datos e = emng.loadEvent(new Long(1)); //Mostrar los datos almacenados en el evento this.mostrarTabla(out, e.getParticipants()); } } catch (Exception ex) { out.println(ex); } finally { out.close(); } } [32]
  33. 33. HIBERNATE private void mostrarTabla(PrintWriter out, Set lista) { out.println("<table>"); Iterator it = lista.iterator(); //Iterar sobre todos los eventos while (it.hasNext()) { Person p = (Person) it.next(); out.println("<tr>"); out.println("<td>" + p.getAge() + "</td>"); out.println("<td>" + p.getFirstname() + "</td>"); out.println("<td>" + p.getLastname() + "</td>"); out.println("<td>" + p.getEvents() + "</td>"); out.println("</tr>"); } out.println("</table>"); }}Ejemplo: 1. En primer lugar se crea un evento. 2. A continuación se pulsa el enlace Prueba relaciones. 3. Tras la ejecución del código del Servlet se muestra la lista de participantes en el evento inicial. Para el ejemplo, la persona que se almacena como prueba estará al menos en el evento creado inicialmente. [33]
  34. 34. HIBERNATEEl código del Servlet resulta sencillo ya que toda la lógica de interacción con Hibernate seencuentra en las clases PersonManager y EventManager, destacando la forma en que sehan realizado las operaciones basadas en relaciones: Agregar personas a eventos (mng.addPersonToEvent(new Long(1), e.getId())): la persona se agrega al evento a través del conjunto de eventos en los que participa una persona (ver PersonManager). Listar participantes de un evento (e.getParticipants()): los participantes a un evento se obtienen a través del conjunto de personas que participa en un evento. Para ello se carga el evento, se obtienen sus participantes, y para cada uno de ellos se muestra su nombre y la lista de eventos en los cuales participa.El método loadPerson carga una persona a través del valor de su campo clave (id). Para ellose utiliza el método load del interfaz Session. El procedimiento de recuperación de unainstancia también sigue el esquema de sesiones y transacciones explicado con anterioridad.El método listPerson devuelve un listado de todas las personas a través de un Criteria. Estaforma de recuperar datos se explica en el capítulo 5.2 con detenimiento, pero por elmomento destacar que el método setFetchMode posibilita la recuperación de datosrelacionados, es decir, Hibernate por defecto no cargará los datos de los conjuntos queestén relacionados con una instancia (por ejemplo, los eventos a los que está asociada unapersona) para no sobrecargar innecesariamente al sistema, así que en caso de quererrecuperarlos hay que notificarlo de esta forma, entre otras. [34]
  35. 35. HIBERNATEpublic class EventManager { /** * Almacenar un evento * @param title título * @param theDate fecha */ public void createAndStoreEvent(String title, Date theDate) { //Obtener la sesión actual Session session = HibernateUtil.getSessionFactory().getCurrentSession(); //Comenzar la transacción session.beginTransaction(); //Crear el evento Event theEvent = new Event(); theEvent.setTitle(title); theEvent.setDate(theDate); //Almacenarlo session.save(theEvent); //Confirmar transacción session.getTransaction().commit(); } /** * Cargar un evento * @return evento */ public Event loadEvent(Long eventId) { //Obtener la sesión actual Session session = HibernateUtil.getSessionFactory().getCurrentSession(); //Comenzar la transacción session.beginTransaction(); //Cargar el evento por clave [35]
  36. 36. HIBERNATE Event anEvent = (Event) session.createCriteria(Event.class). setFetchMode("participants", FetchMode.JOIN). setFetchMode("participants.events", FetchMode.JOIN). add(Restrictions.eq("id", eventId)). uniqueResult(); //Confirmar transacción session.getTransaction().commit(); return anEvent; } /** * Listar los eventos * @return lista de eventos */ public List listEvents() { //Obtener la sesión actual Session session = HibernateUtil.getSessionFactory().getCurrentSession(); //Comenzar la transacción session.beginTransaction(); //Obtener la lista de personas List result = session.createCriteria(Event.class). setFetchMode("participants", FetchMode.JOIN). list(); //Confirmar transacción session.getTransaction().commit(); return result; }} El método loadEvent carga un evento a través del valor de su campo clave (id). Para ello se utiliza un Criteria al cual se le añade una restricción de igualdad (Restrictions.eq) para filtrar por el campo clave (id). Además se utilizan los métodos necesarios para que se carguen los participantes de un evento [36]
  37. 37. HIBERNATE (setFetchMode("participants", FetchMode.JOIN)) y para cada uno de dichos participantes, que en su propiedad events (ver clase Person) se carguen los datos de sus eventos (setFetchMode("participants", FetchMode.JOIN)). De esta forma, para cada evento se podrían conocer los datos completos de las personas asociadas (edad, nombre, apellidos y eventos a los que se encuentra asociada). El método uniqueResult indica que la consulta deberá devolver un único valor, el cual es una instancia de la clase solicitada. Para estas 2 clases, los ficheros de mapeo quedan configurados según los cambios que se han comentado al introducir las relaciones entre ambas. Para ejecutar el proyecto simplemente queda modificar la página JSP de inicio, para que incluya la opción Prueba relaciones:<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <title>JSP Page</title> </head> <body> <form action="Servlet"> <table> <tr> <td>title</td><td><input type="text" name="title"></input></td> </tr> <tr> <td>date</td><td><input type="text" name="date"></input></td> </tr> <tr> <td><input type="submit"/></td> </tr> </table> </form> <a href="ServletP">Prueba relaciones</a> </body></html> [37]
  38. 38. HIBERNATE 3. FRAMEWORK HIBERNATE 3.1.INTRODUCCIÓNEn el desarrollo de una aplicación J2EE se trabaja continuamente con objetos. Sin embargo, lasbases de datos relacionales no trabajan con ellos, sino con conjuntos y relaciones entreconjuntos. Entonces ¿Cómo se almacena un objeto en una base de datos? ¿Y cómo semantienen las relaciones cuando se convierte un elemento de una base de datos en un objetoJava? La causa de esta disparidad es la llamada diferencia Objeto-Relacional.El problema se agrava cuanto más complejo sea el material a trasladar de un paradigma a otro.En estos casos se hace necesario un puente entre ambos conceptos. Es lo que se llama unmapeador objeto-relacional, también conocido por sus siglas en inglés ORM (Object-RelationalMapping).Un ORM permite al programador aislarse de los detalles básicos. Basta definir cómo se debentrasladar los datos entre ambos modelos y el mapeador se encargará de aplicarlo en cadaocasión.Hibernate es un potente servicio de consulta y persistencia objeto/relacional con el cual esposible desarrollar clases persistentes mediante lenguajes orientados a objetos manteniendosus características básicas (incluyendo herencia, polimorfismo, colecciones, etc...). Permiteexpresar consultas tanto en SQL como en su propia extensión de este lenguaje, denominadaHSQL.Hibernate es un proyecto de software libre con código abierto, por lo que su desarrollo seencuentra en continua evolución. La página del proyecto:http://www.hibernate.org/ [38]
  39. 39. HIBERNATE 3.2.INSTALACIÓNIMPORTANTE:Este apartado sirve como guía de ayuda de instalación manual de Hibernate para su usodentro de una aplicación.No es recomendable realizar la instalación de Hibernate “a mano”. Normalmente, se utilizanentornos de desarrollo integrados como Netbeans, con los que se puede elegir durante lacreación del proyecto que añada los frameworks deseados, entre ellos Hibernate, de formaque el entorno los configurará adecuadamente de forma automática.En caso de que se descargue la última versión, se recomienda seguir la ayuda oficial ya queestas instrucciones pueden estar obsoletas. 1. Descargar la distribución de Hibernate Core de: https://www.hibernate.org/344.html 2. Descomprimir el fichero 3. Copiar los archivos jar necesarios a la carpeta lib de nuestra aplicación: a. hibernate3.jar b. librequired*.jar c. liboptional*.jar 4. Crear el fichero hibernate.cfg.xml en el paquete por defecto de la aplicación. 3.3.CONFIGURACIÓNHibernate se configura a través hibernate.cfg.xml. En el paso 5 del ejemplo anterior seexplicaron algunos de los elementos de configuración que se pueden encontrar en estefichero: [39]
  40. 40. HIBERNATE<?xml version=”1.0” encoding=”UTF-8”?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory name="session1"> <property name="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property> <property name="hibernate.connection.url"> jdbc:mysql://localhost:3306/firstapp </property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <!-- Enable Hibernates automatic session context management--> <property name="current_session_context_class">thread</property> <!-- Disable the second-level cache --> <property name="cache.provider_class"> org.hibernate.cache.NoCacheProvider </property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">create</property> <mapping resource="events/Event.hbm.xml"/> <mapping resource="events/Person.hbm.xml"/> </session-factory></hibernate-configuration> [40]
  41. 41. HIBERNATEEste archivo es leído por el framework cuando arranca y contiene los siguientes elementos: Sesiones: session factory utilizados en la aplicación. Si la aplicación accede a más de una Base de datos es necesario declarar más de un session-factory, cada uno de ellos identificado por un nombre distinto. Propiedades: dentro de cada sesión se declaran una serie propiedades para la conexión y configuración del acceso a la Base de datos: Datos de la conexión: datos para conectar con la Base de datos. hibernate.connection.driver_class Driver JDBC de la Base de datos hibernate.connection.url URL de conexión a la Base de datos hibernate.connection.username Usuario hibernate.connection.password Clave hibernate.connection.pool_size Máximo número de conexiones del pool Propiedades de configuración: parámetros de configuración generales. hibernate.max_fetch_depth Profundidad máxima de joins para relaciones simples hibernate.default_batch_fetch_size Tamaño por defecto para el fetching de asociaciones hibernate.default_entity_mode Modo por defecto para la dynamic-map representación de entidades dom4j pojo hibernate.order_updates Ordenar las actualizaciones true por clave primaria false hibernate.generate_statistics Generar estadísticas de true rendimiento false hibernate.use_identifier_rollback Resetea el identificador true asociado en caso de false eliminación hibernate.use_sql_comments Genera comentarios en las true sentencias SQL false [41]
  42. 42. HIBERNATE Propiedades de conexión: otras propiedades de la conexión.hibernate.jdbc.fetch_size Tamaño de búsquedahibernate.jdbc.batch_size Actualización batch de JDBC2 Utilizar el rowcount que devuelve truehibernate.jdbc.batch_versioned_data executeBatch() false Seleccionar unhibernate.jdbc.factory_class org.hibernate.jdbc.Batcher propio Uso de resultsets scrollables de truehibernate.jdbc.use_scrollable_resultset JDBC2 false Uso de streams para la escritura truehibernate.jdbc.use_streams_for_binary de tipos de datos serializables false Uso de getGeneratedKeys() de truehibernate.jdbc.use_get_generated_keys JDBC3 false Uso de un ConnectionProviderhibernate.connection.provider_class propio truehibernate.connection.autocommit Habilita el Autocommit false auto Modo de Liberación de conexiones on_closehibernate.connection.release_mode JDBC after_transaction after_statement Propiedad específica de JDBC parahibernate.connection.<propertyName> la conexión Propiedad específica de JNDI parahibernate.jndi.<propertyName> la conexión Nivel de aislamiento dehibernate.connection.isolation transacciones [42]
  43. 43. HIBERNATE Propiedades de caché: gestión de la caché de segundo nivel. Nombre de CacheProviderhibernate.cache.provider_class propio. Optimizar la operación de la truehibernate.cache.use_minimal_puts caché al mínimo número de false escrituras. truehibernate.cache.use_query_cache Habilitar la cache de consultas false Deshabilitar completamente la truehibernate.cache.use_second_level_cache cache false Nombre de un interfazhibernate.cache.query_cache_factory QueryCache propio Prefijo de los nombreshibernate.cache.region_prefix regionales de la caché truehibernate.cache.use_structured_entries Usar entradas de cache legibles false Propiedades de transacciones: gestión de transacciones. Nombre de la factoría dehibernate.transaction.factory_class transacciones Nombre para obtener lajta.UserTransaction transacción JTA Nombre delhibernate.transaction.manager_lookup_class TransactionManagerLookup La sesión se lanza antes de truehibernate.transaction.flush_before_completion concluir la transacción false Cierra la sesión tras concluir la truehibernate.transaction.auto_close_session transacción false [43]
  44. 44. HIBERNATE Otras propiedades. Estrategia para jta obtener la sesión threadhibernate.current_session_context_class actual managed custom Class org.hibernate.hql.ast. ASTQueryTranslatorFactory Implementación delhibernate.query.factory_class HQL Parser org.hibernate.hql.classic. ClassicQueryTranslatorFactory Mapeo a consultashibernate.query.substitutions SQL validate Genera el esquema updatehibernate.hbm2ddl.auto automáticamente al create crear la Sesión create-drop Utilización de CGLIB truehibernate.cglib.use_reflection_optimizer en lugar de reflexión false Mapeos: ficheros de mapeo de clases (hbm.xml) que se utilizan en la aplicación. 3.3.1. MAPEOSLos ficheros de mapeo que se utilizan en la aplicación se definen en hibernate.cfg, indicando laruta donde se encuentran los mismos. Cada uno de estos ficheros con extensión hbm.xmlmapean una clase de la aplicación con una de las tablas de la Base de datos especificada en laconexión, y contienen los detalles de dicho mapeo. [44]
  45. 45. HIBERNATELos ficheros de mapeo normalmente incluyen el nombre de la tabla y clase relacionadas, y eldetalle del mapeo entre columnas de la tabla y propiedades de la clase, como puedeobservarse en la ilustración anterior. Un fichero de mapeo puede contener varias clasesmapeadas, aunque habitualmente se realiza con una sola clase (cuyo nombre debería coincidircon el nombre del fichero de mapeo).Los elementos básicos de un fichero de mapeo aparecen a continuación. Se marcarán ennegrita aquellos elementos importantes para su utilización: 1. hibernate-mapping: datos generales del mapeo.<hibernate-mapping schema="schemaName" (a) catalog="catalogName" (b) default-cascade="cascade_style" (c) default-access="field|property|ClassName" (d) default-lazy="true|false" (e) auto-import="true|false" (f) package="package.name" (g)/> a. schema (opcional): nombre del esquema de bases de datos. b. catalog (opcional): nombre del catálogo de la base de datos. c. default-cascade (opcional – none por defecto): estilo de cascada por defecto. [45]
  46. 46. HIBERNATE d. default-access (opcional – property por defecto): estrategia de acceso a las propiedades. e. default-lazy (opcional – true por defecto): valor por defecto del atributo lazy de los mapeos de clases y colecciones. f. auto-import (opcional – true por defecto): permite usar nombres de clases sin calificar en el lenguaje SQL. Si hay dos clases con el mismo nombre sin calificar, esta propiedad tiene que tener el valor false. g. package (opcional): prefijo de paquete para los nombres de clases sin cualificar. 2. class: datos de la clase persistente y su relación con la tabla de la base de datos.<class name="ClassName" (a) table="tableName" (b) discriminator-value="discriminator_value" (c) mutable="true|false" (d) schema="owner" (e) catalog="catalog" (f) proxy="ProxyInterface" (g) dynamic-update="true|false" (h) dynamic-insert="true|false" (i) select-before-update="true|false" (j) polymorphism="implicit|explicit" (k) where="arbitrary sql where condition" (l) persister="PersisterClass" (m) batch-size="N" (n) optimistic-lock="none|version|dirty|all" (o) lazy="true|false" (p) entity-name="EntityName" (q) check="arbitrary sql check condition" (r) rowid="rowid" (s) subselect="SQL expression" (t) abstract="true|false" (u) node="element-name"/> [46]
  47. 47. HIBERNATEa. name (opcional): nombre completo de la clase o interfaz Java. También se pueden hacer persistentes clases estáticas internas.b. table (opcional – por defecto el nombre de la clase sin cualificar): nombre de la tabla de la base de datos.c. discriminator-value (opcional – por defecto el nombre de la clase): distingue subclases individuales, se usa para comportamiento polimórfico.d. mutable (opcional – true por defecto): especifica si las instancias son mutables o no. Las clases inmutables no se pueden modificar ni eliminar.e. schema (opcional): sobreescribe el nombre de esquema especificado por <hibernate-mapping>.f. catalog (opcional): sobreescribe el nombre de catálogo especificado por <hibernate-mapping>.g. proxy (opcional): interfaz de proxy para la incialización perezosa.h. dynamic-update (opcional – false por defecto): la sentencia SQL UPDATE se genera en tiempo de ejecución y solamente contiene las columnas cuyos valores hayan cambiado.i. dynamic-insert (opcional – false por defecto): la sentencia SQL INSERT se genera en tiempo de ejecución y solamente contiene las columnas cuyos valores son distintos a null.j. select-before-update (opcional – false por defecto): se produce una sentencia SELECT antes de actualizar para comprobar si un objeto ha sido modificado. Si no no se produce dicha actualización.k. polymorphism (opcional – implicit por defecto): determina si se utiliza polimorfismo implícito o explícito a la hora de recuperar objetos en las consultas.l. where (opcional): condición WHERE a utilizar cuando se recuperan objetos de esta clase.m. persister (opcional): especifica un ClassPersister propio, permitiendo la redefinición de la estrategia de almacenamiento persistente.n. batch-size (opcional – 1 por defecto): tamaño batch para la búsqueda de instancias de esta clase por campo clave. [47]
  48. 48. HIBERNATE o. optimistic-lock (opcional – version por defecto): determina la estrategia de bloqueo optimista. p. lazy (opcional): búsqueda perezosa. q. entity-name (opcional – por defecto el nombre de la clase): Hibernate3 permite mapear una misma clase distintas veces (con distintas tablas), y este nombre será el utilizado. r. check (opcional): expression SQL para generar una comprobación en la generación automática de esquemas. s. rowid (opcional): utilización de ROWID. t. subselect (opcional): mapea una entidad immutable de solo lectura con una subconsulta de la base de datos, por ejemplo para usar vistas en lugar de tablas. u. abstract (opcional): marca superclases abstractas en jerarquías con <union- subclass>. 3. id: dentro de la etiqueta class, se debe mapear la clave primaria de la tabla.<id name="propertyName" (a) type="typename" (b) column="column_name" (c) unsaved-value="null|any|none|undefined|id_value" (d) access="field|property|ClassName"> (e) node="element-name|@attribute-name|element/@attribute|." <generator class="generatorClass"/></id> a. name (opcional): nombre de la propiedad. b. type (opcional): indica el tipo. c. column (opcional –nombre de la propiedad por defecto): nombre de la columna. [48]
  49. 49. HIBERNATE d. unsaved-value (opcional): valor del identificador que indica que la instancia es nueva, para distinguir de instancias guardadas o cargadas en sesiones anteriores. Casi nunca se utiliza en Hibernate 3. e. access (opcional – property por defecto): estrategia de acceso al valor de la propiedad. 4. generator: dentro del id, es necesario definir un generador de identificadores únicos para la clase.<generator class="org.hibernate.id.TableHiLoGenerator"> <param name="table">uid_table</param> <param name="column">next_hi_value_column</param></generator> a. class: nombre de la clase que implementa el interfaz org.hibernate.id.IdentifierGenerator, a la cual se pueden pasar parámetros a través de los elementos <param>. Asimismo, existe una serie de clases predefinidas: i. increment: identificadores únicos siempre que no existan otros procesos insertando en la tabla. ii. identity: columna de tipo identity (autonumérica) para aquellos sistemas que la soportan. iii. sequence: asignación basada en secuencia para aquellos sistemas que la soportan. iv. hilo: genera identificadores con un algoritmo hi/lo dado un nombre de tabla y de columna. v. seqhilo: genera identificadores con un algoritmo hi/lo dado un nombre de secuencia. vi. uuid: genera claves de tipo uuid de tamaño 32. vii. guid: usa una cadena guid generada por la base de datos para aquellos sistemas que la soportan. [49]
  50. 50. HIBERNATE viii. native: selecciona identity, sequence o hilo dependiendo de la base de datos en uso. ix. assigned: asignado por la aplicación. Es la opción por defecto si no se incluye generator. x. select: asignación por trigger. xi. foreign: usa el identificador de otro objeto asociado, normalmente a través de un <one-to-one>. xii. sequence-identity: usa una secuencia y el método getGeneratedKeys de JDBC3 para la generación. 5. composite-id: utilizado en el caso que la clave primaria esté compuesta por más de una columna.<composite-id name="propertyName" (a) class="ClassName" (b) mapped="true|false" (c) access="field|property|ClassName"> (d) node="element-name|." <key-property name="propertyName" type="typename" column="column_name"/>(e) <key-many-to-one name="propertyName class="ClassName"column="column_name"/> (f) ......</composite-id> a. name (opcional): nombre de la propiedad. b. class (opcional): la forma de implementar una clave compuesta en Hibernate es a través de una clase. Esta propiedad indica el nombre de dicha clase, que contendrá atributos para cada una de las columnas que componen la clave. c. mapped (opcional – false por defecto): utilización de un identificador compuesto mapeado. d. access (opcional – property por defecto): estrategia de acceso al valor de la propiedad. [50]
  51. 51. HIBERNATE e. key-property: dentro de la etiqueta composite-id, indica cada uno de los campos que forman la clave y que no corresponden a claves foráneas de otras tablas: i. name: nombre de la propiedad (de la clase que implementa el identificador). ii. type (opcional): tipo Hibernate de la propiedad. iii. column (opcional – nombre de la propiedad por defecto): nombre de la columna. f. key-many-to-one: dentro de la etiqueta composite-id, indica cada uno de los campos que forman la clave y que corresponden a claves foráneas de otras tablas: i. name: nombre de la propiedad (de la clase que implementa el identificador). ii. class: nombre de la clase relacionada a través de la clave foránea. iii. column (opcional – nombre de la propiedad por defecto): nombre de la columna. 6. property: declaración de propiedades de la clase.<property name="propertyName" (a) column="column_name" (b) type="typename" (c) update="true|false" (d) insert="true|false" (e) formula="arbitrary SQL expression" (f) access="field|property|ClassName" (g) lazy="true|false" (h) unique="true|false" (i) not-null="true|false" (j) optimistic-lock="true|false" (k) generated="never|insert|always" (l) node="element-name|@attribute-name|element/@attribute|." index="index_name" unique_key="unique_key_id" length="L" precision="P" scale="S"/> [51]
  52. 52. HIBERNATE a. name: nombre de la propiedad (primera letra siempre en minuscule). b. column (opcional – nombre de la propiedad por defecto): nombre de la columna de base de datos mapeada. También puede ser especificado a través de etiquetas <column>. c. type (opcional): indica el tipo Hibernate, que puede tratarse de uno de los siguientes, aunque en caso de no especificar Hibernate lo asignará automáticamente en función del tipo de la columna de base de datos: i. Tipo básico Hibernate (integer, string, character, date, …). ii. Clase Java o tipo básico (int, float, java.util.Date, …). iii. Clase Java serializable. iv. Clase propia. d. update (opcional – true por defecto): las columnas mapeadas deben incluirse en las sentencias UPDATE. e. insert (opcional – true por defecto): las columnas mapeadas deben incluirse en las sentencias INSERT. f. formula (opcional): expresión SQL que define el valor de una propiedad calculada. Las propiedades calculadas no se mapean a ninguna columna. g. access (opcional – property por defecto): estrategia utilizada para acceder a la propiedad. h. lazy (opcional – false por defecto): indica si esta propiedad debe ser buscada de forma perezosa cuando la instancia se accede por vez primera. i. unique (opcional): restricción unique para esta columna. j. not-null (opcional): restricción not-null para esta columna. k. optimistic-lock (opcional – true por defecto): las actualizaciones de esta propiedad requieren la adquisición del bloqueo optimista. l. generated (opcional – never por defecto): esta propiedad es generada por la base de datos.7. many-to-one [52]
  53. 53. HIBERNATE<many-to-one name="propertyName" (a) column="column_name" (b) class="ClassName" (c) cascade="cascade_style" (d) fetch="join|select" (e) update="true|false" (f) insert="true|false" (g) property-ref="propertyNameFromAssociatedClass" (h) access="field|property|ClassName" (i) unique="true|false" (j) not-null="true|false" (k) optimistic-lock="true|false" (l) lazy="proxy|no-proxy|false" (m) not-found="ignore|exception" (n) entity-name="EntityName" (o) formula="arbitrary SQL expression" (p) node="element-name|@attribute-name|element/@attribute|." embed-xml="true|false" index="index_name" unique_key="unique_key_id" foreign-key="foreign_key_name"/> a. name: nombre de la propiedad. b. column (opcional): nombre de la columna de clave foránea. También puede ser especificado a través de etiquetas <column>. c. class (opcional): nombre de la clase asociada. d. cascade (opcional): operaciones que deben ejecutarse en cascada desde el padre al objeto asociado. e. fetch (opcional – select por defecto): elige entre búsqueda mediante outer- join o select secuencial. f. update (opcional – true por defecto): las columnas mapeadas deben incluirse en las sentencias UPDATE. g. insert (opcional – true por defecto): las columnas mapeadas deben incluirse en las sentencias INSERT. [53]
  54. 54. HIBERNATE h. property-ref (opcional): nombre de la propiedad de la clase asociada relacionada con esta foreign key. Si no se especifica se utiliza la clave de la clase asociada. i. access (opcional – property por defecto): estrategia utilizada para acceder a la propiedad. j. unique (opcional): restricción unique para la clave foránea. k. not-null (opcional): restricción not-null para la clave foránea. l. optimistic-lock (opcional – true por defecto): las actualizaciones de esta propiedad requieren la adquisición del bloqueo optimista. m. lazy (optional – proxy por defecto): indica si esta propiedad debe ser buscada de forma perezosa cuando la instancia se accede por vez primera. n. not-found (opcional – exception por defecto): cómo se tratan las claves foráneas que referencian a filas inexistentes. o. entity-name (opcional): nombre de entidad de la clase asociada. p. formula (opcional): expresión SQL que define el valor de una propiedad calculada. 8. one-to-one<one-to-one name="propertyName" (a) class="ClassName" (b) cascade="cascade_style" (c) constrained="true|false" (d) fetch="join|select" (e) property-ref="propertyNameFromAssociatedClass" (f) access="field|property|ClassName" (g) formula="any SQL expression" (h) lazy="proxy|no-proxy|false" (i) entity-name="EntityName" (j) node="element-name|@attribute-name|element/@attribute|." embed-xml="true|false" foreign-key="foreign_key_name"/> a. name: nombre de la propiedad. b. class (opcional): nombre de la clase asociada. [54]
  55. 55. HIBERNATE c. cascade (opcional): operaciones que deben ejecutarse en cascada desde el padre al objeto asociado. d. constrained (opcional): una clave foránea de la clave primaria de la tabla mapeada referencia a la tabla de la clase asociada. e. fetch (opcional – select por defecto): elige entre búsqueda mediante outer- join o select secuencial. f. property-ref (opcional): nombre de la propiedad de la clase asociada relacionada con esta foreign key. Si no se especifica se utiliza la clave de la clase asociada. g. access (opcional – property por defecto): estrategia utilizada para acceder a la propiedad. h. formula (opcional): expresión SQL que define el valor de una propiedad calculada. i. lazy (optional – proxy por defecto): indica si esta propiedad debe ser buscada de forma perezosa cuando la instancia se accede por vez primera. j. entity-name (opcional): nombre de entidad de la clase asociada.9. set: las relaciones inversas normalmente se modelan a través de un conjunto (set), pero existen otros elementos que se pueden usar como list, map, bag, array o primitive-array. [55]
  56. 56. HIBERNATE<set name="propertyName" (a) table="table_name" (b) schema="schema_name" (c) lazy="true|extra|false" (d) inverse="true|false" (e) cascade="all|none|save-update|delete|all-delete-orphan|delete-orphan" (f) sort="unsorted|natural|comparatorClass" (g) order-by="column_name asc|desc" (h) where="arbitrary sql where condition" (i) fetch="join|select|subselect" (j) batch-size="N" (k) access="field|property|ClassName" (l) optimistic-lock="true|false" (m) mutable="true|false" (n) node="element-name|." embed-xml="true|false" > <key .... /> (o) <map-key .... /> <element .... /></map> a. name: nombre de la propiedad. b. table (opcional – nombre de la propiedad por defecto): nombre de la tabla de la colección (no se usa para one-to-many). c. schema (opcional): nombre del esquema para sobreescribir el esquema definido en el elemento raíz. d. lazy (opcional – true por defecto). e. inverse (opcional – false por defecto): indica el lado inverso en una asociación bidireccional. f. cascade (opcional - none por defecto): permite operaciones en cascada sobre los elementos hijos. g. sort (opcional): especifica una colección ordenada mediante orden natural o especificando una clase comparadora. [56]
  57. 57. HIBERNATE h. order-by (opcional): solo en JDK 1.4, especifica un nombre de columna que define el orden de iteración. i. where (opcional): condición WHERE a utilizar cuando se recuperan o eliminan objetos de la colección. j. fetch (opcional – select por defecto): elige entre búsqueda mediante outer- join o select secuencial. k. batch-size (opcional – 1 por defecto): tamaño batch para la búsqueda de instancias de esta clase por campo clave. l. access (opcional – property por defecto): estrategia utilizada para acceder a la propiedad. m. optimistic-lock (opcional – true por defecto): las actualizaciones del estado de la colección requieren la adquisición del bloqueo optimista. n. mutable (opcional – true por defecto): los elementos de la colección nunca cambian. o. key: dentro de la etiqueta set indica la clave foránea de la colección:<key column="columnname" (i) on-delete="noaction|cascade" (ii) property-ref="propertyName" (iii) not-null="true|false" (iv) update="true|false" (v) unique="true|false" (vi)/> i. column (opcional): nombre de la columna que actúa como clave foránea. También puede especificarse a través de elementos <column>. ii. on-delete (opcional – noaction por defecto): la clave foránea tiene activado el borrado en cascada en la base de datos. iii. property-ref (opcional): la clave foránea se refiere a columnas que no son la clave primaria de la tabla original. iv. not-null (opcional): las claves foráneas no se pueden establecer como null. [57]
  58. 58. HIBERNATE v. update (opcional): las claves foráneas no se pueden actualizar. vi. unique (opcional): la clave foránea debería tener una restricción unique. p. one-to-many: indica<one-to-many class="ClassName" (i) not-found="ignore|exception" (ii) entity-name="EntityName" (iii) node="element-name" embed-xml="true|false"/> i. class: nombre de la clase asociada. ii. not-found (opcional – exception por defecto): cómo se tratan las claves foráneas que referencian a filas inexistentes. iii. entity-name (opcional): nombre de entidad de la clase asociada. 3.4.EL INTERFAZ SESSIONEl interfaz Session es la principal vía de interacción entre la aplicación Java e Hibernate. Representaa la sesión actual, donde se producen transacciones para la interacción con la Base de datos,efectuando operaciones de lectura, creación, modificación y eliminación de instancias de clasesmapeadas. Las instancias de tales clases se pueden encontrar en tres estados posibles: transient: no es persistente, no está asociada a ninguna sesión. Se pueden convertir en persistent invocando a los métodos save, persist o saveOrUpdate. Se encuentra en la aplicación pero no en la Base de datos. persistent: asociado a una única sesión. Se encuentra en la aplicación y en la Base de datos. [58]
  59. 59. HIBERNATE detached: persistente previamente, no asociado con ninguna sesión. Se encuentra en la Base de datos, pero no se ha recuperado desde la aplicación.En la siguiente ilustración aparecen estos estados, y cuáles son los métodos que provocan latransición de uno a otro.Para poder operar con una sesión es necesario obtener una instancia de la misma y comenzaruna transacción. Cualquier operación sobre dicha instancia debe contenerse dentro de unatransacción.Si se produce una excepción dentro de la transacción, ésta debe ser cancelada (rollback), si nohay que confirmarla para hacer persistentes los cambios (commit): [59]
  60. 60. HIBERNATE//Obtener la sesión actualSession session = HibernateUtil.getSessionFactory().getCurrentSession();try{ //Comenzar la transacción session.beginTransaction(); //Operaciones con session …}catch (Exception ex){ //Deshacer transacción session.getTransaction().rollback();}finally{ //Confirmar transacción session.getTransaction().commit();}Los métodos que se invocan sobre la instancia de Session producen operaciones sobre la Basede datos a través de sentencias SQL, generadas en el dialecto concreto configurado enhibernate.cfg. De esta forma, las siguientes sentencias se producen para los métodosenumerados anteriormente: INSERT: save, persist, saveOrUpdate, replicate. UPDATE: update, merge, saveOrUpdate, replicate. DELETE: delete.A continuación se exponen algunos métodos de la clase Session utilizados habitualmente. Paramayor información se puede acceder a la API de Hibernate:http://www.hibernate.org/hib_docs/v3/api/ [60]

×