JPA (API de Persistencia en Java) es el estándar en Java que define una abstracción que nos permite realizar la integración entre el sistema orientado a objetos de Java y el sistema relacional de nuestra base de datos. Para más detalles consultar la especificación JPA – JSR 338
JPA realiza por nosotros toda la conversión entre nuestros objetos y las tablas de una base de datos. Esta conversión se llama ORM (Mapeo Relacional de Objetos) y puede configurarse a través de metadatos (XML) o anotaciones.JPA establece un interface común que es implementada por un “JPA Provider” concreto. De modo que es el Proveedor JPA el que realiza el trabajo. Entre los proveedores JPA más conocidos se encuentranHibernate, Eclipse Link, TopLink, OpenJPA
Arquitectura JPA
La arquitectura de JPA está diseñada para gestionar Entidades y las relaciones que hay entre ellas. A continuación detallamos los principales componentes de la arquitecturaEntity: Son los objetos persistidos en Base de datos como registros de una tabla. Podemos decir que cada Entidad corresponderá con una tabla de nuestra Base de Datos
Persistence: Clase con métodos estáticos que nos permiten obtener instancias de EntityManagerFactory
EntityManagerFactory: Es una factoría de EntityManager. Se encarga crear y gestionar múltiples instancias de EntityManager
EntityManager: Es una interface que gestiona las operaciones de persistencia de las Entidades. A su vez trabaja como factoría de Query
Query: Es una interface para obtener la relación de objetos que cumplen un criterio
EntityTransaction: Agrupa las operaciones realizadas sobre un EntityManager en una única transacción de Base de Datos
Mapeo con Anotaciones
Las anotaciones nos permiten configurar el mapeo de una entidad dentro del mismo fichero donde se declara la clase, de este modo, es más fácil de visualizar y mantener.Las anotaciones comienzan con el símbolo “@” seguido de un identificador. Las anotaciones son utilizadas antes de la declaración de clase, propiedad o método. A continuación se detallan las principales.@Entity: Declara la clase como una Entidad@Table: Declara el nombre de la Tabla con la que se mapea la Entidad @Id:Declara que la propiedad es la clave primaria de la Tabla@GeneratedValue:Declara como el propiedad va a ser inicializada. Manualmente, Automático o a partir de una secuencia
@SecuenceGenerator: Declara una secuencia que será usada para asignar un valor a la propiedad que representa la clave primaria de la tabla@Column: Declara que la propiedad se mapea con una columna de la tabla
@Entity
@Table(name = "PELICULA")
public class Pelicula {
@Id
@Column(name = "ID_PELICULA")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_PELICULA")
@SequenceGenerator(name = "SEQ_PELICULA",sequenceName = "NOMBRE_SEQUENCIA_BBDD")
private Integer idPelicula;
@Column(name = "TITULO")
private String titulo;
@Column(name = "FECHA_PUBLICACION")
private String fechaPublicacion;
public Pelicula() {
}
public Integer getIdPelicula() {
return idPelicula;
}
public void setIdPelicula(Integer idPelicula) {
this.idPelicula = idPelicula;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public String getFechaPublicacion() {
return fechaPublicacion;
}
public void setFechaPublicacion(String fechaPublicacion) {
this.fechaPublicacion = fechaPublicacion;
}
}
Otras propiedades importantes:
@Transient: Declara que la propiedad no debe persistirse en Base de Datos. Se utiliza para propiedad auto calculadas.
- La propiedad "añosDesdePublicacion" no forma parte de la entidad Pelicula.
- Si esta propiedad no es actualizada anualmente, almacenará un valor erróneo.
- Además esta propiedad puede ser calculada automáticamente a partir de la propiedad "fechaPublicacion"
@Transient
private int anyosDesdePublicacion;
public int getAnyosDesdePublicacion){
// CALCULA LOS AÑOS QUE HAN PASADO DESDE LA PUBLICACION
}
@Temporal: Declara que la propiedad es de tipo temporal. Se utiliza junto al enumerado TemporalType que definirá la precisión de la propiedad (DATE, TIME o TIMESTAMP)
@Temporal(TemporalType.DATE)
@Column(name = "FECHA_PUBLICACION")
private String fechaPublicacion;
@Enumerated: Declara que la propiedad es de alguno de los valores definidos en un Enumerado (lista de valores constantes). Los valores de un tipo enumerado tienen asociado implicitamente un tipo ordinal que será asociada a la propiedad de este tipo
@Column(name= "TIPO_PELICULA")
@Enumerated(EnumType.ORDINAL)
private TipoPelicula tipo;
public enum TipoPelicula {
COMEDIA,
TERROR,
AVENTURAS
}
Si queremos que el valor almacenado sea el valor alfanumerico asociado al enumerado en lugar del valor ordinal utilizaremos EnumType.STRING
@Embedded: Declara que la propiedad hace referencia a un objeto incrustado. Un objeto incrustado no tiene entidad por si mismo pero forma parte de un objeto que es una entidad. Este objeto se suele separa de la entidad para hacerlo más manejable.
@Embedded
private Director director;
public class Director {
private String nombre;
private String apellidos;
private Date fechaNacimiento;
}
Resumen
Hemos aprendido los fundamentos de JPA, su arquitectura básica y como mapear una tabla de Base de Datos con una Entidad Java