TopLink Jpa Parte 1 - Leonardo Torres Altez
Upcoming SlideShare
Loading in...5
×
 

TopLink Jpa Parte 1 - Leonardo Torres Altez

on

  • 9,888 views

Tutorial de TopLink Jpa Parte 1

Tutorial de TopLink Jpa Parte 1

Statistics

Views

Total Views
9,888
Views on SlideShare
9,874
Embed Views
14

Actions

Likes
1
Downloads
558
Comments
0

5 Embeds 14

http://www.linkedin.com 8
http://www.lmodules.com 2
http://static.slidesharecdn.com 2
http://www.health.medicbd.com 1
https://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    TopLink Jpa Parte 1 - Leonardo Torres Altez TopLink Jpa Parte 1 - Leonardo Torres Altez Document Transcript

    • CURSO JAVA DEVELOPER - INSTRUCTOR : LEONARDO TORRES ALTEZ Java Persistence Api Que es ORM ? JDBC con DAO . Con LINKS DE INTERES : JPA muchas alternativas ejecutándose en una incompatibles , el gru- aplicación Java SE. ♦ EJB3 : http://www.jcp.org/ po Java EE experto en/jsr/detail?id=220 toma inspiración de estos frameworks po- En este articulo , mo- ♦ JPA API : http:// pulares y creo el api de delare un simple libro persistencia de Java de direcciones java.sun.com/javaee/5/ Mapeo Objeto Relacio- (JPA) , el cual se puede (Address book ) para docs/api/javax/ nal (ORM) ,en otras usar desde aplicaciones una compañía de músi- persistence/package- palabras persistir los Java EE o SE. ca ficticia llamada Wa- summary.html objetos Java en una termelon , para guardar base de datos relacio- En pocas palabras las direcciones de los ♦ DAO: http://java.sun.com/ nal - ha tenido su ma- JPA , usa el modelo de clientes en la base de blueprints/ yor cambio reciente- programación POJO datos . Watermelon corej2eepatterns/Patterns/ mente, gracias, en par- para la persistencia. A vende y distribuye artí- DataAccessObject.html te a la proliferación de pesar de que este mo- culos de música así métodos avanzados delo esta incluido en la como instrumentos , que intentan hacer esta especificación EJB 3 , amplificadores y li- tarea mas fácil . JPA puede ser usado bros . Voy a usar una fuera de un contenedor incremental e iterativa Entre estas tecnologías EJB , y esta es la forma aproximación para des- están los Entity Beans que será usada en este arrollar y persistir el 2.x , TopLink , Hiber- articulo . “Plain Old modelo del negocio. nate , JDO , y también Java Objects” ( POJO ) Como trabaja JPA ? clase y no implemen- tan ninguna interface. Usted no necesita ar- @Entity chivos descriptores public class Customer { XML para hacer los mapeos . Si uno se fija @Id Inspirado en los frame- en el API ( java doc ) private Long id; works como Hiberna- uno observara que esta private String firstname; te , JPA usa anotacio- compuesto de pocas private String lastname; nes para mapear obje- clases e interfaces. private String telephone; tos a la base de datos private String email; relacional. Estos obje- La mayoría del conteni- private Integer age; tos , usualmente llama- do de el paquete ja- // constuctors, getters, vax.persitence son anota- dos entidades, no tie- setters ciones. Con esto expli- nen nada en común } con los Entity Beans cado , veremos el si- 2.x . Las entidades JPA guiente ejemplo de son clases POJOs, no código : extienden de ninguna
    • JAVA PERSISTENCE API Page 2 Lo mínimo necesario ... una clase “Customer” sim- ple . Esta tiene un identifi- cador (id) , un nombre El código que sigue mues- ( firstname) , apellido ( last- tra lo mínimo requerido name) un numero de telé- para definir un quot;persistence fono ( telephone ) , mail objectquot; . Ahora vamos a ( email ) y edad del cliente manipular este objeto, ( age ) . Para ser persistente deseo persistir mi objeto esta clase tiene que seguir “customer” , actualizar algu- algunos reglas JPA simples : na de sus propiedades y borrarlo de la base de da- • La clase tiene que ser identifi- tos. Estas operaciones serán cada como una entidad usan- echas a través de la interfa- @Entity do la anotación ce public class Customer { Esta parte de códi- @javax.persistence.Entity go que vimos javax.persistence.EntityManager de ( constructores , • Una propiedad de la clase JPA. @Id tiene que tener un identifica- getter y setter no private Long id; son mostrados para dor anotado con @javax.persistence.Id Para esto, quienes estén private String firstname; hacer esto mas fácil familiarizados con el patrón private String lastname; de leer ) muestra • Tiene que haber un construc- DAO , el EntityManager private String telephone; tor sin argumentos private String email; private Integer age; // constuctors, EntityManager ... //getters, setters } puede ser visto co- “Customer” ( usando el mail usando los métodos mo una clase DAO operador new como cual- quot;setquot; . que nos provee un quier otro objeto JAVA ) y set de métodos clá- le pasare algo de data co- La interface EntityManger // métodos CRUD sicos ( persist , re- mo el quot;idquot; , quot;last namequot; , no tiene un método upda- move ) y buscado- quot;emailquot; , etc. Usare el méto- te . Los updates se hacen a public void createCustomer() { // Gets an entity manager res ( find ). do EntityManager.persist() través de las propiedades EntityManagerFactory emf = Persisten- Después de crear el para insertar este objeto en quot;settersquot; . Luego borrare el ce.createEntityManagerFactory(quot;watermelonPUquot;); EntityManager em = emf.createEntityManager(); EntityManager la base de datos. Yo puedo objeto usando EntityMana- EntityTransaction trans = em.getTransaction usando un factory luego buscar este objeto ger.remove() , notar que (); ( EntityManagerFac- por su identificador usando este código usa transaccio- // Instantiates a customer object Customer customer = new Customer(1L, quot;Johnquot;, tory ) , instanciare el método EntityMan- nes explicitas . Es por eso quot;Lennonquot;, quot;441909quot;, quot;john@lenon.comquot;, 66); mi objeto ger.find() y actualizar el que los métodos persist , // Persists the customer trans.begin(); em.persist(customer); trans.commit(); // Finds the customer by primary key Persistence.xml customer = em.find(Customer.class, 1L); System.out.println(customer.getEmail()); update , y remove especifica unidad de persistencia ( watermelonPU en este // Updates the customer email address son llamados entre caso ) . Una unidad de persistencia es declarada en el ar- trans.begin(); transacion.begin() y chivo “persistence.xml” y contiene información como la customer.setEmail(quot;john@beatles.co.ukquot;); trans.commit(); transaction.commit base de datos a usar y el driver JDBC . // Deletes the customer (). Vea los métodos trans.begin(); CRUD em.remove(customer); <persistence version=quot;1.0quot; xmlns=quot;http://java.sun.com/xml/ns/persistencequot;> trans.commit(); Que base de datos <persistence-unit name=quot;watermelonPUquot; transaction-type=quot;RESOURCE_LOCALquot;> // Closes the entity manager and the factory <provider> em.close(); usamos ? , La res- oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider emf.close(); } puesta esta en Enti- </provider> <class>entity.Customer</class> tyManagerFactory, <properties> Esta toma un pará- <property name=quot;toplink.jdbc.urlquot; metro que se refiere a una value=quot;jdbc:mysql://localhost:3306/watermelonDBquot;/> <property name=quot;toplink.jdbc.userquot; value=quot;rootquot;/>
    • Page 3 JAVA PERSISTENCE API Unidad de Persistencia <property name=quot;toplink.jdbc.driverquot; piedades comunes . En este de la tabla “customer”. value=quot;com.mysql.jdbc.Driverquot;/> <property na- caso , estas propiedades me=quot;toplink.jdbc.passwordquot; value=quot;quot;/> son : url de la base de da- Este es el DDL que JPA <property name=quot;toplink.target- databasequot; value=quot;MySQL4quot;/> tos , driver JDBC , creden- gene- <property name=quot;toplink.ddl- ciales. Bajo el elemento ra generationquot; value=quot;create-tablesquot;/> </properties> quot;propertiesquot; usted encontra- auto- </persistence-unit> ra propiedades especificas </persistence> para Top-link por ejemplo toplink.ddl-generation . Esta En el código arriba , hay propiedad es usada por solo una unidad de persis- TopLink para generar las tencia , llamada waterme- tablas automáticamente si lonPU ( el archivo persis- estas no existen aun . Esto tence.xml puede contener significa que una vez ejecu- muchas unidades de persis- tado el código TopLink a tencia ) . Usted puede pen- creado una tabla para guar- máticamente de la clase sar en una unidad de per- dar la información de anotada “Customer” . Gra- sistencia como un conjunto “customers”. la tabla 1 cias a la “codificación por de entidades ( el elemento muestra la información DDL defecto” que guía JPA ( y class ) que comparten pro- ( data definition languaje ) en general Java EE 5 ) No Customizando Usted solo necesita añadir lumna tiene String es mapeado a var- código customizado cuando el mismo char(255) ). el código por defecto es nombre de inadecuado . En mi caso, las propie- porque yo nunca especifico dades . Los el nombre de la tabla o tipos de columnas en la clase datos son “Customer” JPA asume que también el nombre de la tablas es mapeados igual al nombre de la clase por defecto y que el nombre de la co- ( ejemplo Añadiendo funcionalidades y customizando el mapeo En este punto yo quisiera primary Key en cuatro posi- quot;identity generatorquot; , ej :una columna definida mejorar algunas cosas. Pri- bles modos: como auto_increment en mero que todo, yo no quie- MySQL. ro setear un identificador • AUTO (default) permite al (primary key)del objeto proveedor de persistencia pero en lugar de esto quie- (TopLink en mi caso) Ahora quiero mejorar mi ro que JPA lo incremente decidir cual de las tres mapeo . Primero cambiar el posibilidades usar. nombre de la tabla a automáticamente. Gracias a • SEQUENCE usar un SQL quot;t_customerquot; en lugar de las anotaciones , esto es sequence para obtener el fácil de hacer. próximo primary key quot;customerquot;. Luego hare el nombre ( first name ) y el • TABLE requiere una tabla apellido ( last name ) obli- Solo necesito anotar mi con dos columnas : el atributo identificador nombre de la secuencia y gatorios. El máximo largo @javax.persitence.GeneratedValue su valor ( esta es la estra- de un numero de teléfono tegia por defecto de To- (telephone) tiene que ser . pLink ) Esta anotación genera un 15 caracteres y la columna • IDENTITY usa un
    • JAVA PERSISTENCE API Page 4 email tiene que ser renombrada a “e_mail” con un quot;underscorequot; . Todos estos pequeños cambios pueden ser hechos con las anotaciones. Para cambiar el Una aplicación puede ser notificada antes nombre ( name ) de la tabla anote la clase con @javax.persistence.Table . La anotación o después de @javax.persistence.Column es usada para definir las columnas y tienen una serie de ocurridos estos eventos JPA Anotaciones Callback usando quot;callback Ahora con el mapeo entre la una entidad es cargada , notatios” para mis necesida- clase Customer y la tabla persistida , actualizada o des ? , Primero me encarga- t_customer quedo mejor removida . Una aplicación re del formato del numero annotationsquot; gracias a que las anotacio- puede ser notificada antes o de teléfono . Quiero verifi- nes @Column y @Table tie- después de ocurridos estos car que el primer carácter del teléfono es quot;+quot; , Yo pue- nen muchos atributos. eventos usando anotacio- do hacer esto antes que la nes . JPA tiene un conjunto entidad sea persistida o ac- Hay otras dos cosas que de quot;callback annotatiosquot; que tualizada . solo tengo que quisiera hacer . Primero ase- pueden ser usadas en méto- gurarme que todo teléfono es ingresado usando códigos internacio- nales . co- menzando con el sím- bolo '+' . dos y permiten al desarrolla- crear un método ( validateP- Segundo , calcular la edad honeNumber en mi ejem- dor añadir cualquier regla del “customer” a partir de plo , pero el nombre es irre- de negocios que desee . JPA la fecha de nacimiento . levante ) con algo de lógica llamara al método anotado Tengo muchas alternativas de negocios y con las anota- antes o después de estos de como hacer estas tareas , ciones @PrePersist y eventos . La tabla 4 muestra @PreUpdate, JPA hace el pero voy a usar quot;callback las quot;callback anotationsquot; resto. annotationsquot; Durante su ciclo de vida , Como uso las “callback an- El código de ejemplo en la
    • siguiente pagina. @PrePersist @PreUpdate Page 5 private void validatePhoneNumber() { if (telephone.charAt(0) != '+') Para la edad del cliente , throw new IllegalArgumentException hare algo similar, calculare la (quot;Invalid phone numberquot;); edad del cliente antes que la } fecha de nacimiento sea in- } sertada ( @PostPersist ) o actualizada ( @PostUpdate ) , y claro cada vez que el clien- @PostLoad te es cargado de la base de @PostPersist datos ( @PostLoad ). @PostUpdate public void calculateAge() { Calendar birth = new GregorianCalendar(); birth.setTime(dateOfBirth); Calendar now = new GregorianCalendar(); now.setTime(new Date()); int adjust = 0; if (now.get(Calendar.DAY_OF_YEAR) - birth.get(Calendar.DAY_OF_YEAR) < 0) { adjust = -1; } age = now.get(Calendar.YEAR) - birth.get(Calendar.YEAR) + adjust; } Anotaciones Callback .. añadir anotaciones Para hacer que esto funcio- TAMP ) . Entonces estoy en tabla no tendrá una colum- ne . necesito añadir un nue- la capacidad de calcular la na edad mas ) ver tabla 5. vo atributo a la clase Custo- edad del cliente pero yo mer : “date of birth” . Para necesito persistir esa infor- notificar a JPA que mapee mación ? , NO , conociendo este atributo a una fecha , que el valor cambia todos uso la anotación @Temporal los años . Para hacer que con el atributo TemporalTy- esta propiedad (age) edad pe.DATE ( las opciones son no sea persistente , usare la DATE , TIME , TIMES- anotación @Transient ( La
    • JAVA PERSISTENCE API Page 6 One to One Relationship Ahora que tengo mapeada Un Customer tiene una y por su cumpleaños . Lo mi clase Customer y tengo solo una representare como una cla- anotaciones callback para “address“ (dirección) enton- se separada, clase Address validar y calcular data , ne- ces Watermelon pueden con un id , una calle cesito añadir una dirección. enviar al cliente un regalo (street) , una ciudad (city) , un có- al persistir o remover “customer” One to One Relationship public void createCustomerWithAddress() { también se hace // Instantiates a Customer and an Address objecy Customer customer = new Customer(quot;Johnquot;, quot;Lennonquot;, Como tu pueden ver en la quot;customer'squot; uso el código quot;+441909quot;, quot;john@lenon.comquot;, dateOfBirth); con su “address” tabla 6 , la clase Address que sigue : homeAddress = new Address(quot;Abbey Roadquot;, Address quot;Londonquot;, quot;SW14quot;, quot;UKquot;); usa la anotación @Entity customer.setHomeAddress(homeAddress); para notificar a JPA que es una clase persistente y // Persists the customer with its address @Column para customizar trans.begin(); el mapeo. Creando la rela- em.persist(homeAddress); ción entre Customer y Ad- em.persist(customer); trans.commit(); dress es simple . Yo simple- mente añado una propie- // Deletes the customer and the address dad Address en la clase trans.begin(); Customer . Para persistir la em.remove(customer); dirección de los em.remove(homeAddress); trans.commit(); } One to One Relationship el customer también remue- por defecto hará las asocia- Como este código muestra , vo el address. ciones opcionales y basa- usted tiene primero que das en mis requerimientos, instanciar un objeto Custo- Pero persistiendo y remo- es decir al persistir o remo- mer y un Adress , Para lin- viendo ambos objetos pare- ver customer también se kear los dos ,uso un méto- ce que se hiciera mas traba- hace con su address. do setter ( set HomeAd- jo que el que necesito. Se- dress ) y luego persistido ria mejor si yo pudiera per- Quiero que un Customer cada objeto , cada uno en sistir o remover justo el tenga exactamente un Ad- la misma transacción. Por- objeto raíz ( el Customer ) y dress , significa que un va- que no tiene sentido tener permitir las dependencias lor null no es permitido . un adress en el sistema que que se persistan o remue- Puedo lograr todo eso no este linkeado a un cus- van automáticamente ? , usando la anotación tomer , cuando yo remuevo TopLink y la codificación
    • Page 7 JAVA PERSISTENCE API One to One Relationship loading LAZY) , o constraint de integri- @OneToOne es usada para quot;eagerlyquot; (EAGER) porque dad ,para la relación entre anotar una relación . Este quiero cargar la dirección tablas t_customer y t_adress tiene muchas propiedades de la casa quot;homeAddressquot; ( ver tabla 7 ) incluyendo un cascade tan pronto como el objeto usado para quot;cascadingquot; de Customer es cargado. cualquier tipo de acción. En este ejemplo , quiero La anotación @JoinColumn quot;cascadequot; la acción de per- tiene los mismos atributos sistir y remover. De esta como @Column , excepto forma , cuando hago remo- que es usado para asociar ve o persist de un objeto atributos , En este ejemplo , customer este automática- Yo renombro la llave forá- mente lleva acabo esta ac- nea en un address_fk y no ción para el quot;addressquot; . El permito ningún valor null atributo fetch dice a JPA ( nullable=false) que política usar cuando cargamos una relación. Esta puede ser una asocia- JPA entonces creara los El atributo ción de carga tardía ( lazy siguientes DDLs con una fetch dice a JPA @Entity que política usar @Table(name = quot;t_customerquot;) public class Customer { cuando @Id cargamos una @GeneratedValue private Long id; (...) relación @Transient private Integer age; @OneToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.REMOVE}) @JoinColumn(name = quot;address_fkquot;, nullable = false) private Address homeAddress; // constuctors, getters, setters }
    • JAVA PERSISTENCE API Page 8 Querying Objects mite hacer querys comple- de operadores para filtrar la Hasta ahora yo estoy usan- jos sobre objetos ( asocia- data ( IN , NOT IN , EXIST , LIKE , IS do JPA para mapear mis ciones , herencia , clases NULL , IS NOT NULL ) o para con- objetos a una base de datos abstractas ) trolar las colecciones ( IS relacional y usar el entity EMPTY , IS NOT EMPTY , MEMBER manager para hacer algunas Los querys usan las pala- OF ) , También hay funcio- operaciones CRUD (Create, bras SELECT , FROM y nes para manejar Strings ( LOWER , UPPER , TRIM , CONCAT , read, update and delete ) , WHERE , mas un conjunto LENGTH , SUBS- Pero JPA también TRING ) , nú- permite que hagas // Finds the customers who are called John meros ( ABS , querys sobre los SQRT , MOD ) , o objetos. Esto usa Query query = em.createQuery(quot;SELECT c colecciones quot;Java Persistence FROM Customer c WHERE ( COUNT , MIN , Query Langua- c.firstname='John'quot;); MAX , SUM ). Co- gequot; ( JPQL) , el List<Customer> customers = que- mo SQL , tu cual es similar a ry.getResultList(); también pue- SQL y es también des ordenar Usted tiene que independiente de // Same query but using a parameter los resultados la base de datos , //Query query = em.createQuery(quot;SELECT c FROM ( ORDER BY) o hacer querys no Este es un lenguaje //Customer c WHERE c.firstname=:paramquot;); agruparlos //query.setParameter(quot;:paramquot;, quot;Johnquot;); (GROUP BY) rico que nos per- sobre una tabla, mas bien sobre Querying Objects, sobre objetos ... un objeto. Para hacer querys sobre los dos formas . De cualquiera objetos se necesita Entity- de las dos formas el string Manager para crear un ob- quot;Johnquot; es buscado : puede jeto Query . Luego tengo el ser parte del query JPQL o resultado del query llaman- puede ser pasado como do el getResultList o gen- parámetro , en este ultimo SingleResult cuando hay caso necesito usar el méto- solo un objeto retornado . do setParameter. En el ejemplo que sigue , quiero buscar todos los “Customers” quienes tienen el primer nombre quot;Johnquot; , Yo puedo hacer esto de JPQL Queries, ejemplos ... objeto “customer” y el to address. SELECT c FROM Como usted puede ver en Customer c WHERE este query JPQL usa la no- “c.firstname” es la primera c.homeAddress.country='US'; tación objeto . Usted tiene propiedad del objeto que hacer query no sobre “customer” . Si ustedes Acá hay un conjunto de una tabla, mas bien sobre quieren buscar todos los querys que nosotros pode- un objeto. El carácter “customers” que viven en mos hacer con JPQL . Ver “c” ( el nombre es irrele- U.S. , ustedes pueden usar tabla 8 vante ) es el alias de un esta notación , para obtener al atributo country del obje-