Académique Documents
Professionnel Documents
Culture Documents
Que es ORM ?
compatibles , el grupo LINKS DE INTERES :
JPA
Java EE experto toma En este articulo , modela-
inspiración de estos fra- re un simple libro de di- ♦ EJB3 : http://www.jcp.org/
meworks populares y creo recciones (Address book ) en/jsr/detail?id=220
el api de persistencia de para una compañía de
Java (JPA) , el cual se música ficticia llamada ♦ JPA API : http://
puede usar desde aplica- Watermelon , para guar-
ciones Java EE o SE. dar las direcciones de los java.sun.com/javaee/5/
Mapeo Objeto Relacional clientes en la base de da- docs/api/javax/persistence/
(ORM) ,en otras palabras En pocas palabras JPA , tos . Watermelon vende y package-summary.html
persistir los objetos Java usa el modelo de progra- distribuye artículos de
en una base de datos rela- mación POJO para la música así como instru- ♦ DAO: http://java.sun.com/
cional - ha tenido su ma- persistencia. A pesar de mentos , amplificadores y blueprints/
yor cambio recientemen- que este modelo esta in- libros . Voy a usar una corej2eepatterns/Patterns/
te, gracias, en parte a la cluido en la especificación incremental e iterativa
proliferación de métodos EJB 3 , JPA puede ser aproximación para des- DataAccessObject.html
avanzados que intentan usado fuera de un conte- arrollar y persistir el mo-
hacer esta tarea mas fácil . nedor EJB , y esta es la delo del negocio.
forma que será usada en
Entre estas tecnologías este articulo . “Plain Old
están los Entity Beans Java Objects” ( POJO )
2.x , TopLink , Hiberna- ejecutándose en una apli-
te , JDO , y también cación Java SE.
JDBC con DAO . Con
muchas alternativas in-
// Updates the customer email address persistencia ( water- <persistence-unit name="watermelonPU" transaction-type="RESOURCE_LOCAL">
trans.begin(); melonPU en este ca- <provider>
customer.setEmail("john@beatles.co.uk"); oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider
trans.commit(); so ) . Una unidad de </provider>
// Deletes the customer persistencia es decla- <class>entity.Customer</class>
<properties>
trans.begin();
em.remove(customer);
rada en el archivo <property name="toplink.jdbc.url"
trans.commit(); “persistence.xml” y value="jdbc:mysql://localhost:3306/watermelonDB"/>
<property name="toplink.jdbc.user" value="root"/>
// Closes the entity manager and the factory contiene información <property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
em.close(); como la base de datos <property name="toplink.jdbc.password" value=""/>
emf.close(); <property name="toplink.target-database" value="MySQL4"/>
} a usar y el driver <property name="toplink.ddl-generation" value="create-tables"/>
JDBC . </properties>
</persistence-unit>
</persistence>
Page 3 JAVA PERSISTENCE API
Unidad de Persistencia
En el código arriba , hay solo pLink para generar las tablas fecto hace mas fácil la progra-
una unidad de persistencia , automáticamente si estas no mación para el desarrollador .
llamada watermelonPU ( el existen aun . Esto significa que
archivo persistence.xml puede una vez ejecutado el código
contener muchas unidades de TopLink a creado una tabla
persistencia ) . Usted puede para guardar la información de
pensar en una unidad de persis- “customers”. la tabla 1 muestra
tencia como un conjunto de la información DDL ( data
entidades ( el elemento class ) definition languaje ) de la tabla
que comparten propiedades “customer”.
comunes . En este caso , estas
propiedades son : url de la base Este es el DDL que JPA gene-
de datos , driver JDBC , cre- ra automáticamente de la clase
denciales. Bajo el elemento anotada “Customer” . Gracias
"properties" usted encontrara a la “codificación por defecto”
propiedades especificas para que guía JPA ( y en general
Top-link por ejemplo to- Java EE 5 ) No tengo que
plink.ddl-generation . Esta hacer mucho para generar este
propiedad es usada por To- DDL , la codificación por de-
Customizando
Usted solo necesita añadir dades . Los
código customizado cuando el tipos de da-
código por defecto es inade- tos son tam-
cuado . En mi caso, porque yo bién mapea-
nunca especifico el nombre de dos por de-
la tabla o columnas en la clase fecto ( ejem-
“Customer” JPA asume que el plo String es
nombre de la tablas es igual al mapeado a
nombre de la clase y que el varchar
nombre de la columna tiene el (255) ).
mismo nombre de las propie-
Todos estos pequeños cambios pueden ser hechos con las anotaciones. Para cambiar el nombre
( name ) de la tabla anote la clase con @javax.persistence.Table . La anotación
@javax.persistence.Column es usada para definir las columnas y tienen una serie de atributos lista-
dos en la Tabla 3
Una aplicación
puede ser
notificada antes
o después de
ocurridos estos
eventos JPA
Anotaciones Callback
usando
"callback Ahora con el mapeo entre la actualizada o removida . Una Quiero verificar que el primer
clase Customer y la tabla aplicación puede ser notificada carácter del teléfono es "+" ,
annotations" t_customer quedo mejor gra- antes o después de ocurridos Yo puedo hacer esto antes que
cias a que las anotaciones estos eventos usando anotacio- la entidad sea persistida o actua-
@Column y @Table tienen nes . JPA tiene un conjunto de lizada . solo tengo que crear un
método ( validatePhoneNum-
muchos atributos. "callback annotatios" que pue-
ber en mi ejemplo , pero el
den ser usadas en métodos y nombre es irrelevante ) con
Hay otras dos cosas que quisie-
permiten al desarrollador añadir algo de lógica de negocios y con
ra hacer . Primero asegurarme
que todo
teléfono es
ingresado
usando códi-
gos interna-
cionales .
comenzando
con el
símbolo
'+' . Segun-
cualquier regla de negocios que las anotaciones @PrePersist y
do , calcular la edad del
desee . JPA llamara al método @PreUpdate, JPA hace el re-
“customer” a partir de la fecha
anotado antes o después de sto.
de nacimiento . Tengo muchas
estos eventos . La tabla 4 mues-
alternativas de como hacer estas El código de ejemplo en la si-
tra las "callback anotations"
tareas , pero voy a usar guiente pagina.
"callback annotations" Como uso las “callback annota-
Durante su ciclo de vida , una tios” para mis necesidades ? ,
entidad es cargada , persistida , Primero me encargare del for-
mato del numero de teléfono .
@PrePersist
@PreUpdate
Page 5
private void validatePhoneNumber() {
if (telephone.charAt(0) != '+')
Para la edad del cliente , hare throw new IllegalArgumentException
algo similar, calculare la edad del ("Invalid phone number");
cliente antes que la fecha de na- }
cimiento sea insertada }
( @PostPersist ) o actualizada
( @PostUpdate ) , y claro cada
vez que el cliente es cargado de @PostLoad
la base de datos ( @PostLoad ). @PostPersist
@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;
}
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("John", "Lennon",
Como tu pueden ver en la tabla "+441909", "john@lenon.com", dateOfBirth);
con su “address” Address homeAddress = new Address("Abbey Road",
6 , la clase Address usa la ano-
"London", "SW14", "UK");
tación @Entity para notificar a customer.setHomeAddress(homeAddress);
JPA que es una clase persisten-
te y @Column para customizar // Persists the customer with its address
el mapeo. Creando la relación trans.begin();
em.persist(homeAddress);
entre Customer y Address es em.persist(customer);
simple . Yo simplemente añado trans.commit();
una propiedad Address en la
clase Customer . Para persistir // Deletes the customer and the address
trans.begin();
la dirección de los "customer's" em.remove(customer);
uso el código que sigue : em.remove(homeAddress);
trans.commit();
}
@Entity
que política usar
@Table(name = "t_customer")
public class Customer { cuando
@Id cargamos una
@GeneratedValue
private Long id;
(...) relación
@Transient
private Integer age;
Querying Objects
complejos sobre objetos ( aso- radores para filtrar la data ( IN ,
Hasta ahora yo estoy usando ciaciones , herencia , clases NOT IN , EXIST , LIKE , IS NULL , IS
JPA para mapear mis objetos a abstractas ) NOT NULL ) o para controlar las
una base de datos relacional y colecciones ( IS EMPTY , IS NOT
usar el entity manager para Los querys usan las palabras EMPTY , MEMBER OF ) , También
hacer algunas operaciones SELECT , FROM y WHE- hay funciones para manejar
CRUD (Create, read, update RE , mas un conjunto de ope- Strings ( LOWER , UPPER , TRIM ,
and delete ) , Pero CONCAT , LENGTH , SUBSTRING ) ,
JPA también permite // Finds the customers who are called John números ( ABS ,
que hagas querys SQRT , MOD ) , o
sobre los objetos. colecciones
Query query = em.createQuery("SELECT c ( COUNT , MIN ,
Esto usa "Java Persis- FROM Customer c WHERE
MAX , SUM ). Co-
tence Query Langua- c.firstname='John'");
ge" ( JPQL) , el cual List<Customer> customers = que- mo SQL , tu
es similar a SQL y es ry.getResultList(); también puedes
también independien- ordenar los
Usted tiene que te de la base de da- resultados
// Same query but using a parameter ( ORDER BY) o
tos , Este es un len- //Query query = em.createQuery("SELECT c FROM
hacer querys no guaje rico que nos agruparlos
//Customer c WHERE c.firstname=:param"); (GROUP BY)
permite hacer querys //query.setParameter(":param", "John");
sobre una tabla,