Persistencia
Persistencia de datos en ataStore
Persistencia
Introducción
Hablamos de persistencia para referirnos a los mecanismos que nos permiten almacenar y recuperar la información de nuestra aplicación, generalmente en sistemas gestores de bases de datos.
Tradicionalmente se ha utilizado JDBC para esta tarea, aunque en los últimos años se han puesto de moda sistemas de mapeo objeto-relacional (ORM) que evitan tener que elaborar el código repetitivo y propenso a errores de acceso a bases de datos.
Estos sistemas ORM permiten trabajar sin código SQL y ellos se encargan de generar código SQL compatible con los diversos sistemas de bases de datos.
Es posible que estas herramientas generen código SQL poco eficiente, por lo que hay que usarlas con cuidado.
Hibernate
El sistema ORM de mayor éxito es Hibernate y es el que hemos configurado en nuestro sistema debido a su facilidad de integración con Spring.
Hibernate se puede usar mediante un lenguage de consultas propio, llamado HSQL, mediante una API de consultas propia, o mediante el estándar JPA.
JPA
La respuesta de Java al éxito de los ORM fue la creación del estándar JPA.
Anotaciones JPA
JPA define una serie de anotaciones con las que podemos especificar como una clase (o varias) se deben guardar en la base de datos.
@Entity @Table(name = "products") public class Product implements Serializable { @Id @GeneratedValue private Long id; @Basic private String description; @Transient private Date readTime; @Embedded @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private LocalizedString name; .... }
En el ejemplo anterior establecemos que:
- JPA debe manejar la persistencia esta clase (@Entity) y en qué tabla debe almacenarla (@Table).
- El campo id es la clave primaria de la tabla (@Id) y MySQL lo genera automáticamente (@GeneratedValue).
- El campo readTime no debe almacenarse (@Transient).
-
El campo name de tipo compuesto (es otra clase Java), debe manejarse conjuntamente, así que cuando se lea o se guarde un producto de la tabla products se debe leer o guardar el nombre de otra tabla.
Una referencia completa de las anotaciones la tenemos en el manual de OpenJPA (comprobar siempre que funciona en Hibernate pues podría no ser 100% compatible).
Lenguaje JPQL
Para hacer consultas a la base de datos usando JPA podemos usar el lenguage de consultas JPQL
Una referencia completa del lenguage JQL la tenemos en el manual de OpenJPA (comprobar siempre que funciona en Hibernate pues podría no ser 100% compatible).
API de consultas
Otra manera de hacer consultas es usando la API de JPA. Esto tiene la ventaja de que es totalmente orientado a objetos, por lo que podremos reutilizar y refactorizar código con mayor facilidad.
Un ejempo de uso de la API es el siguiente:
Product product = (Product) em.getReference(Product.class, productId); em.remove(product);
Podemos consultar la API en el manual de OpenJPA y en el Javadoc (comprobar siempre que funciona en Hibernate pues podría no ser 100% compatible).
Uso de SQL
Siempre podemos recurrir al SQL si queremos, delegando a JPA sólo la parte que queramos (como puede ser, por ejemplo, la construcción del objeto a partir del ResultSet).
Query query = em.createNativeQuery("SELECT * FROM products p"); Listproducts = (List ) query.getResultList();
Clases DAO
Para crear una clase de acceso a base de datos y conseguir que Spring nos injecte automáticamente el EntityManager que necesitamos para usar JPA haremos dos cosas:
-
Declarar la nueva DAO en el archivo WEB-INF/spring/dao.xml de la siguiente manera:
-
Añadir un campo privado de tipo EntityManager con la anotación @PersistenceContext:
public class ProductDAO { @PersistenceContext private EntityManager em; ... }