Named Queries en Spring Data
En este artículo sobre named queries con ejemplos en Spring Data, vamos a ver una de las maneras que nos proporciona Spring Data para poder realizar queries contra nuestra Base de Datos.
¿Qué es Spring Data?
Cuando nos encontramos implementando nuestras aplicaciones, debemos centrarnos en la lógica de negocio y simplificar y reducir la cantidad de código a utilizar para conectarnos a Base de Datos. En este aspecto es en el que Spring Data nos puede ayudar.
Spring Data JPA no es un proveedor de JPA, sino que es una librería que añade una capa que nos abstrae de esa capa de JPA, por ejemplo Hibernate.
Hibernate es una implementación de JPA, mientras que Spring Data JPA es una abstracción de acceso de datos de JPA.
JPA (Java Persistence API) nos va a ayudar a reducir la complejidad y gestión de conexión a Base de Datos y Spring Data va a reducir la cantidad de código y el boilerplate necesario para conectarnos.
En cuanto a las queries que Spring Data nos proporciona podemos ver:
- JPQL o named Queries
- Haciendo uso de @Query
- Queries de sintaxis de Spring en función del nombre del método.
Características y configuración de una NamedQuery en Spring Data
Cuando creamos una NamedQuery podemos añadir cierta configuración para cuando ejecutemos nuestra query:
- cacheable – si los resultados obtenidos pueden ser cacheados o no.
- cacheMode – el modo cache para esta query, los valores que se admiten son GET, IGNORE, NORMAL, PUT, or REFRESH
- cacheRegion – si el resultado de la query puede ser cacheable, asigna un nombre a la region de la query que se usará.
- comment – comentario de la query.
- flushMode – que modo de flush haremos en la query, podemos elegir entre, Always, Auto, Commit, Manual o Persistence_Context.
Definir una Named Query en JPA
Una Named Query forma parte del core de JPA. Lo que una named query nos proporciona es declarar una query en nuestra capa de persistencia que usaremos en nuestro código de negocio. Lo que nos permite su reutilización.
Para crear una Named Query lo hacemos a través del uso de la anotación @NamedQuery y podemos hacer uso de JPQL o SQL nativo.
Por ejemplo:
@NamedQuery(name = "User_findByUserName", query = "from User where userName = :name")
Cada NamedQuery se corresponde con una entidad, pero hay que tener cuidado con el nombre que le asignamos para evitar colisiones con la capa de persistencia para ello, por ejemplo podemos hacer algo como lo que hemos hecho -> {Entidad_queryName}.
Si queremos definir más Named Queries las podemos concatenar haciendo uso de la anotaciób @NamedQueries
@NamedQueries({ @NamedQuery(name = "User_findByUserName", query = "from User where userName = :name"), @NamedQuery(name = "User_findByUserSurname", query = "from User where surname = :surname"), @NamedQuery(name = "User_findByUserAge", query = "from User where age = :age"), })
Named Query Nativa
Si lo queremos es realizar consultas de manera nativa, también podemos hacer uso de SQL de una manera nativa, al igual que realizaríamos una consulta en nuestro motor de BBDD.
Para realizar una Query Nativa nos apoyaremos en la anotación @NamedNativeQuery, vamos a ver un ejemplo:
@NamedNativeQuery(name = "User_GetUserById", query = "select * from user u where u=:id", resultClass = User.class)
La Query anterior obtiene un usuario por Id y lo que hacemos es mapearlo en la entidad User a través de resultClass.
Con la palabra resultClass lo que le decimos a Hibernate es a que entidad lo vamos a mapear, en este caso es que con la entidad User.
Podemos usar las query nativa con NativeQuery o con Query, siempre a través de la session, vamos a verlo:
Query<User> userQuery = session.createNamedQuery("User_GetUserById", User.class); userQuery.setParameter("id", "1111"); User userResult = userQuery.getSingleResult(); ..... ..... .....
NativeQuery userQuery = session.getNamedNativeQuery("User_GetUserById"); userQuery.setParameter("id", "1111"); User result = (User) userQuery.getSingleResult(); return result;
Procedimientos almacenados con Named Queries
En algunas ocasiones necesitamos hacer uso de funciones o procedimientos con nuestra Base de Datos, para esas ocasiones también podemos hacer uso de Named Queries.
Para hacer uso de procedimientos (siempre y cuando nuestra BBDD lo soporte) utilizaremos la anotación @NamedNativeQuery, al igual que en el caso anterior, y definiremos nuestra función o procedimiento.
@NamedNativeQuery(name = "User_CalculateAge", query = "call CALCULATE_USER_AGE(:currentYear, :birth)", resultClass = User.class)
Conclusión
El uso de Named Queries en Spring Data nos va a ayudar para reutilizar o hacer uso de determinadas queries específicas en diferentes partes de nuestra aplicación. De esta manera vamos a evitar código repetido y podremos simplificar la aplicación.
Si necesitas más información puedes escribirnos un comentario o un correo electrónico a refactorizando.web@gmail.com o también nos puedes contactar por nuestras redes sociales Facebook o twitter y te ayudaremos encantados!