hibernate 3

Post on 13-Nov-2014

323 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Hibernate 3

Ramiro González SánchezOctubre del 2006

información confidencial

Contenido

Sesión 1El problema del mapeo Objeto/RelacionalPatrones de Diseño involucradosQuickStart

Sesión 2O/R MappingConsultasPersistencia

Sesión 3TransaccionesHibernate ToolsEvaluación

El problema del mapeo Objeto/Relacional

información confidencial

Partida

UML E/R

Un Modelo de Clases responde necesidades de modelado que no necesariamente satisfacen las reglas de normalización o integridad de un Modelo de Entidad-Relación.

Factura Partida

Factura Partida

Nada impide que unaPartida aparezca en 2Facturas.

información confidencial

UML E/R

Adicionalmente, un Modelo de Clases posee mecanismos que no tienen una contraparte en E/R como: Herencia, Interfases y Relaciones bidireccionales, Multiplicidad muchos a muchos.

Factura

FacturaElectrónica

FacturaImpresa

información confidencial

Labor tediosa

DAO BDValueObjectSQL

ResultSet

get…()ValueObject

ValueObject

Proceso Iterativo:{ get… get… get… }

información confidencial

Problema n + 1

Los joins de tablas no tienen un mapeo “natural”.

Factura

Partida

Partida

Partida

Select *From Factura join Partida

Select *From Factura-- MergeSelect *From Partida

Select *From FacturaFetch {

Select *From Partida

}

Factura

Partida

Partida

Partida

Factura

Partida

Partida

Partida

Factura

Partida

Partida

Partida

Factura

Partida

Partida

Partida

?

información confidencial

Otros problemas

Caching de Objetos: Problema de igualdad.Objetos compartidosObjetos bloqueadosTransacciones sobre objetos

información confidencial

El mundo ideal…

Factura f = new Factura();f.add(new Partida());domainStore.save(f); //insert into Factura; insert into Partida//commit

//

f = query.find(Factura, 12345);// select * from Factura where id = 12345;// select * from Partida where id = 12345;f.removePartida(1);// delete from Partida where …domainStore.save(f);

Patrones de Diseño involucrados

información confidencial

Data Access Object

información confidencial

Domain Store

Clases de Negocio

AdministradorDe

Persistencia

AdministradorDe

Persistencia

BD

Mapeo

QuickStart

información confidencial

Ambiente utilizado para el Curso

Windows XP Professional Edition Service Pack 2J2SE Development Kit v. 1.5.0_04Eclipse SDK 3.1.2MyEclipse IDE v. 4.1.1 GAJBoss 4.0.3 SP1PostgreSQL v. 8.1

Windows XP Professional Edition SP2Windows XP Professional Edition SP2

J2SE Development Kit 1.5.0_06J2SE Development Kit 1.5.0_06

Eclipse SDK 3.1.2Eclipse SDK 3.1.2

MyEclipse 4.1.1 GAMyEclipse 4.1.1 GA

información confidencial

Descargar

ftp://ssdesa01usuario: cursoPassword: curso

información confidencial

Estructura del Ambiente de Desarrollo

MyEclipseMyEclipse

EclipseEclipse

DeploymentServices

Plugins DB Explorer

JBossJBoss

Java Virtual MachineJava Virtual Machine

Java Virtual MachineJava Virtual Machine

PostgreSQL8.1

información confidencial

Verificación de Ambiente

JDKVariable de entorno JAVA_HOME válida%JAVA_HOME%\bin en el PATHEjecutar en línea de comandos java -version

información confidencial

Verificación de Ambiente

MyEclipseVerificar que existe el menú y qué arranca con la correcta versión.

información confidencial

Verificación de Ambiente

JBossLocalizar la carpeta donde está instalado (usualmente C:\Java\jboss-4.0.3SP1)A esta carpeta le llamaremos de ahora en adelante JBOSS_HOMEPosicionarse en línea de comandos en:

%JBOSS_HOME%\binY ejecutar el comando: run.bat

información confidencial

Verificando el Ambiente

PostgreSQL

información confidencial

Arrancar la Base de Datos

información confidencial

Crear Base de Datos

información confidencial

Tabla de Prueba

información confidencial

Nuevo Proyecto

información confidencial

Configuración del Proyecto Java

información confidencial

Finalizando la configuración

información confidencial

Configuración de una conexión

información confidencial

Edición del driver

información confidencial

Agregando el Driver

información confidencial

Driver configurado

información confidencial

Configuración de un Profile de Conexión

información confidencial

Finish…

información confidencial

Abriendo la Conexión

información confidencial

Abrir Conexión…

información confidencial

Habilitando Hibernate en nuestro proyecto

información confidencial

Configuración de Hibernate

información confidencial

Creación de la Configuración

información confidencial

Creación de un SessionFactory

información confidencial

Interfases Hibernate

HibernateHibernate

Session

Transaction

Query

AplicaciónJava

BDjdbc

Cfg(xml)

información confidencial

Elementos Creados

SessionFactory Hibernate.cfg.xml Mappings.hbm.xmlMappings.hbm.xmlMappings.hbm.xml

Session ClasesPersistentes

ClasesPersistentesClases

PersistentesClasesPersistentes

Clase Aplicativa

curr

entS

essi

on()

<<uses>>

<<uses>>

<<uses>>

Query

información confidencial

Configuración de la Conexión en Hibernate

información confidencial

Conexión en Hibernate

información confidencial

Mapping de 1 tabla

información confidencial

ID Generator

información confidencial

Mapping insertado

<?xml version='1.0' encoding='UTF-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools. -->

<hibernate-configuration>

<session-factory>

<property name="myeclipse.connection.profile">qshibernate</property>

<propertyname="connection.url">jdbc:postgresql://localhost:5432/testHibernate</property>

<property name="connection.username">postgres</property>

<property name="connection.password">notiene</property>

<property name="connection.driver_class">org.postgresql.Driver</property>

<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>

<mapping resource="mx/com/ids/qshibernate/Mensajes.hbm.xml" />

</session-factory>

</hibernate-configuration>

información confidencial

Código Generado

información confidencial

Log4J

Hibernate utiliza Log4J para enviar sus mensajes de Log.Por lo que se requiere adicionalmente insertar la configuración de Log4j en el classpath:

log4j.logger.org.hibernate.ce=infolog4j.logger.org.hibernate=info

### log HQL query parser activity#log4j.logger.org.hibernate.hql.ast.AST=debug

### log just the SQLlog4j.logger.org.hibernate.SQL=info

### log JDBC bind parameters ####log4j.logger.org.hibernate.type=debug

información confidencial

Obtención de la Conexión

public static Session currentSession() throws HibernateException {Session session = (Session) threadLocal.get();

if (session == null) {if (sessionFactory == null) {

try {cfg.configure(CONFIG_FILE_LOCATION);sessionFactory = cfg.buildSessionFactory();

}catch (Exception e) {

System.err.println("%%%% Error CreatingSessionFactory %%%%");

e.printStackTrace();}

}session = sessionFactory.openSession();threadLocal.set(session);

}return session;

}

información confidencial

Prueba

public static void main(String[] args) {// Step 1 - Create a new entityMensajes message = new Mensajes();// Step 2 - Set message fieldmessage.setTexto("Hello Hibernate, from MyEclipse!");

try {// Step 3 - Get a Hibernate SessionSession session = HSessionFactory.currentSession();// Step 4 - Persist entity to databaseTransaction tx = session.beginTransaction();session.save(message);tx.commit();System.out.println("Save successful.");

} catch (HibernateException e) {System.out.println("Save failed.");

} finally {try {

// Step 5 - close the sessionHSessionFactory.closeSession();

} catch (HibernateException e1) {// do nothing

}}

}

información confidencial

2005-11-10 22:40:49,390 [main] INFO org.hibernate.impl.SessionFactoryImpl -Checking 0 named queries2005-11-10 22:40:49,468 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 42P012005-11-10 22:40:49,468 [main] ERROR org.hibernate.util.JDBCExceptionReporter - ERROR: relation "hibernate_sequence" does not existSave failed.

información confidencial

Especificando el nombre de la secuencia

<id name="id" column="id" type="java.lang.Integer"><generator class="native"><param name="sequence">

mensajes_id_seq</param>

</generator></id>

2005-11-10 22:51:05,328 [main] INFO org.hibernate.impl.SessionFactoryImpl -Checking 0 named queriesSave successful.

información confidencial

Resultado en la base de datos

información confidencial

Prueba 2

public static void main(String[] args) {try {

// Step 1 - Get a Hibernate SessionSession session = HSessionFactory.currentSession();// Step 2 - Crea un queryQuery q = session.createQuery("from Mensajes");

String qSQL = q.getQueryString();System.out.println("Query: " + qSQL);

// Step 3 - Ejecuta el queryList l = q.list();

for (Iterator iter = l.iterator(); iter.hasNext();) {Mensajes element = (Mensajes) iter.next();System.out.println(element.getId() + ":" +

element.getTexto());}

} catch (HibernateException e) {

información confidencial

Prueba 3

public static void main(String[] args) {try {

// Step 1 - Get a Hibernate SessionSession session = HSessionFactory.currentSession();// Step 2 - Crea un query con parametroQuery q = session.createQuery("from Mensajes where id

= :pId");

// Step 3 - Indica el parametroq.setInteger("pId", 1);

// Step 4 - Ejecuta el queryList l = q.list();String qSQL = q.getQueryString();System.out.println("Query: " + qSQL);

for (Iterator iter = l.iterator(); iter.hasNext();) {Mensajes element = (Mensajes) iter.next();System.out.println(element.getId() + ":" +

element.getTexto());}

} catch (HibernateException e) {

O/R Mapping

información confidencial

Modos de Operación

Administrado y No Administrado

HibernateHibernate

Session

Transaction

Query

AplicaciónJava

BDjdbcConnectionPool

HibernateHibernate

Session

Transaction

Query

AplicaciónJava

BDDatasource

TransactionManager

ResourceManager

información confidencial

Propiedades útiles en hibernate.cfg.xml

show_sql = truehibernate.default_schema = ESQUEMAX

información confidencial

Modelo de Pruebas

Factura Partida

Cliente

Producto

Partida

información confidencial

Escritura de POJO’s

Deben Implementar SerializableImplementar un constructor vacío

información confidencial

Escritura de POJO’s

Declarar los métodos set y get de cada propiedad/columna excepto la llave primaria.

información confidencial

Escritura de POJO’s

El tipo de la llave primaria puede ser una clase auxiliar para manejar el caso de llave compuesta.

información confidencial

Escritura de POJO’s

Los campos que representan llaves foráneas deben ser declarados con el tipo de la Clase que representa la entidad foránea.

información confidencial

Asociaciones Bidireccionales

De la Factura al Cliente se puede navegar con la declaración de la columna Cliente en Factura. La operación inversa requiere de declarar un Set de facturas en el cliente.

/** The value of the facturaSet one-to-many association. */private java.util.Set facturaSet;

…public java.util.Set getFacturaSet()

{return this.facturaSet;

}

public void setFacturaSet(java.util.Set facturaSet){

this.facturaSet = facturaSet;}

información confidencial

Cliente.hbm.xml

DTD

Paquete

Clase

PK

Asociación

información confidencial

Factura.hbm.xml

FK

información confidencial

Partida.hbm.xml

LlaveCompuesta

Llave foránea dentro de Llave

Compuesta

información confidencial

Opciones de ID’s

nativeidentitysequence

assigned

Consultas

información confidencial

get()

int clienteId=1;

Cliente cliente = (Cliente) session.get(Cliente.class, new Long(clienteId);

Si el clienteId solicitado no existe, get() regresa null.

información confidencial

Navegando por el Grafo

Una vez cargado un objeto… es posible obtener el resto... siempre y cuando la sesión siga abierta.

Cliente cliente = partida.getFactura().getCliente();

información confidencial

Mediante HQL

Query query = session.createQuery(“from Cliente c where c.email like ‘%ids.com.mx’ ”);List l = query.list();

Esto es idéntico a:

List l = session.find(“from Cliente c where u.email like ‘%ids.com.mx’ ”);

información confidencial

Utilizando SQL Nativo

Query query = session.createQuery(“Select mx.com.ids.qshibernate.Cliente(*)from Cliente where id = :pId”);

List l = query.list();

información confidencial

Query by Criteria

Criteria criteria = session.createCriteria(Cliente.class);criteria.add( Expression.like(“email”, “%ids.com.mx”);criteria.addOrder(Order.asc(“paterno”);

List l = criteria.list();

información confidencial

Query by Example

Cliente clienteX = new Cliente();clientex.setNombre(“Juan”);

Criteria criteria = session.createCriteria(Cliente.class);criteria.add( Example.create(clienteX) );

List l = criteria.list();

información confidencial

Paginación

Utilizando un objeto Query o Criteria

query.setFirstResult(41);query.setMaxResults(20);

información confidencial

Leyendo 1 solo renglón

query.setMaxResult(1);

query.uniqueResult();

información confidencial

Manejo de parámetros

Por nombre(“from Cliente where id = :pId);

Por posición(“from Cliente where nombre = ? and paterno = ?”);La primera posición es 0.

información confidencial

Estrategias de Fetching

Immediate FetchingInmediato (1 por 1)

Lazy FetchingEn el primer acceso (por default)

Eager FetchingEl objeto y sus relaciones

Batch FetchingLectura en lotes (merge)

información confidencial

Estrategia de Acceso

Se puede declarar en el mapeo o durante tiempo de ejecución.

En el mapeo se maneja por Asociación y se tienen 3 parámetros:

lazy = “true” o “false”outer-join = “true” o “false”batch-size = “9”

En una clase solo puede haber una asociación con outer-join=“true”

información confidencial

Profundidad del Fetch

Se debe controlar la profundidad de los joins:hibernate.max_fetch_depth=1,2,3…

Utilizar máximo a 4.

información confidencial

Eager Fetching

Por default, se usa lazy loading…

Para provocar el eager fetching en tiempo de ejecuciónse describe la intención en el query:

from Factura fleft join fetch f.partidaSet

información confidencial

Theta-join

Se utiliza en tablas que no tienen una asociación definida

from User user, LogRecord logwhere user.username = log.username

Esto devuelve pares de los objetos referenciados:

while( i.hasNext() ) {Object[] pair = (Object []) i.next();User user = (User) pair[0];LogRecord log = (LogRecord) pair[1];

}

información confidencial

Report Queries

Tabular

select item.id, item.descriptionorder by item.id

retorna Object[];

Mediante Objeto predefinido

select new Renglon( item.id, item.description )order by item.id

Renglon, debe ser una clase con el constructor apropiado.

información confidencial

Named Queries

En el mapping de la tabla principal:

<sql-query name=“findClientesFacturas”><![CDATA[

select {c.*}, {f.*}from cliente c inner join factura fwhere c.id = f.idcliente

]]><return alias=“c” class=“Cliente” /><return alias=“f” class=“Factura” /></sql-query>

Nota: También funciona para HQL con la etiqueta “query”.

Persistencia

información confidencial

Ciclo de Vida de un Objeto

información confidencial

Creando un objeto persistente

Cliente cliente = new Cliente();

cliente.setNombre(“Juan”);cliente.setPaterno(“Perez”);cliente.setEmail(“x@xxx.org”);

Session session = QSSessionFactory.currentSession();Transaction tx = session.beginTransaction();

session.save(cliente);tx.commit();session.close();

información confidencial

Actualización de Detached con Update

cliente.setMaterno(“Perez”);

Session session = QSSessionFactory.currentSession();Transaction tx = session.beginTransaction();

session.update(cliente);

cliente.setEmail(“xyz@xxx.org”);

tx.commit();session.close();

Cualquier objeto asociado a la base

de datos, se actualiza

automáticamente.

información confidencial

Actualización con Lock

cliente.setMaterno(“Perez”);

Session session = QSSessionFactory.currentSession();Transaction tx = session.beginTransaction();

session.lock(cliente, LockMode.NONE);

cliente.setEmail(“xyz@xxx.org”);

tx.commit();session.close();

READUPGRADE

información confidencial

Borrado de un Objeto

session.delete(objeto)

información confidencial

Ejercicio

Instale el ambiente de desarrolloJDKPostgreSQLEclipseMyEclipse

Cree una base de datos con PGAdminIIICorra el script creaTestHibernate.sqlGenere el proyecto configurado para HibernateGenere los mappings de las tablas recién creadasEscriba código que

Inserte 2 clientes nuevosInserte 2 productos nuevosInserte 1 factura a cada cliente con su respectiva partida y referenciando a 1 productoListe los clientes con sus facturas con sus partidas con sus productos

Transacciones

información confidencial

Manejo de Transacciones

La estructura de código estándar y recomendada es la siguiente:

información confidencial

Transacciones dentro del Contenedor J2EE

HibernateHibernate

Session

Transaction

Query

AplicaciónJava

BDDatasource

TransactionManager

ResourceManager

hibernate.transaction.factory_class = org.hibernate.transaction.JTATransactionFactoryhibernate.transaction.manager_lookup_class = <dependiente del Application Server>

información confidencial

JTA Transaction Manager

Borland ESorg.hibernate.transaction.BESTransactionManagerLookup

JRun4org.hibernate.transaction.JRun4TransactionManagerLookup

JOnASorg.hibernate.transaction.JOnASTransactionManagerLookup

JOTMorg.hibernate.transaction.JOTMTransactionManagerLookup

Resinorg.hibernate.transaction.ResinTransactionManagerLookup

Orion/OC4J/OracleASorg.hibernate.transaction.OrionTransactionManagerLookup

WebSphere 6org.hibernate.transaction.WebSphereExtendedJTATransactionLookup

WebSphereorg.hibernate.transaction.WebSphereTransactionManagerLookup

Weblogicorg.hibernate.transaction.WeblogicTransactionManagerLookup

JBossorg.hibernate.transaction.JBossTransactionManagerLookup

Hibernate Tools

información confidencial

Conversión entre Modelos

UML (XMI)UML (XMI)

POJO’sPOJO’s

O/R MappingO/R Mapping

DDLDDL

AndroMDA

Xdoclet

hbm2ddl Middlegen

hbm2java

ReverseEngineering

información confidencial

Instalación de Hibernate Tools

Simplemente se desempaca el paquete que contiene los Hiberneta Tools en el directorio de Eclipse.

información confidencial

Nuevo proyecto Java…

información confidencial

Configuración Proyecto Java

información confidencial

Nuevo Java Package

información confidencial

Nuevo Hibernate Configuration File

información confidencial

Create Hibernate Console Configuration

información confidencial

Verificando

información confidencial

Artifact Generation

información confidencial

Configuración de Artifact Generation

información confidencial

Setup Reverse Engineering

información confidencial

Selección de carpeta y nombre

información confidencial

Include… Exclude…

información confidencial

Configuración final

información confidencial

Confirmación…

información confidencial

Artefactos Generados

información confidencial

HQL Editor

información confidencial

Modelo Relacional

información confidencial

Preguntas…

información confidencial

Referencias

Hibernate in ActionChristian Bauer, Gaving KingManning(disponible en pdf)

www.hibernate.orgDownloads, documentación de referencia.

http://caveatemptor.hibernate.orgAplicación demo de hibernate

Sun J2EE Patterns Cataloghttp://java.sun.com/blueprints/patterns/catalog.html

top related