1. Información general
En este artículo rápido, nos centraremos en diferentes tipos de interfaces de repositorio de Spring Data y su funcionalidad. Tocaremos en:
- CrudRepository
- PagingAndSortingRepository
- JpaRepository
En pocas palabras, cada repositorio en Spring Data extiende la interfaz del repositorio genérico , pero más allá de eso, cada uno tiene una funcionalidad diferente.
2. Repositorios de datos de Spring
Comencemos con JpaRepository , que extiende PagingAndSortingRepository y, a su vez, CrudRepository .
Cada uno de estos define su propia funcionalidad:
- CrudRepository proporciona funciones CRUD
- PagingAndSortingRepository proporciona métodos para realizar paginación y ordenar registros
- JpaRepository proporciona métodos relacionados con JPA, como vaciar el contexto de persistencia y eliminar registros en un lote
Y así, debido a esta relación de herencia, JpaRepository contiene la API completa de CrudRepository y PagingAndSortingRepository .
Cuando no necesitamos la funcionalidad completa proporcionada por JpaRepository y PagingAndSortingRepository , simplemente podemos usar CrudRepository .
Veamos ahora un ejemplo rápido para comprender mejor estas API.
Comenzaremos con una entidad de producto simple :
@Entity public class Product { @Id private long id; private String name; // getters and setters }
E implementemos una operación simple: busque un producto según su nombre:
@Repository public interface ProductRepository extends JpaRepository { Product findByName(String productName); }
Eso es todo. Spring Data Repository generará automáticamente la implementación según el nombre que le proporcionamos.
Este fue un ejemplo muy simple, por supuesto; puede profundizar en Spring Data JPA aquí.
3. CrudRepository
Echemos ahora un vistazo al código de la interfaz CrudRepository :
public interface CrudRepository extends Repository { S save(S entity); T findOne(ID primaryKey); Iterable findAll(); Long count(); void delete(T entity); boolean exists(ID primaryKey); }
Observe la funcionalidad típica de CRUD:
- guardar (…) - guardar un Iterable de entidades. Aquí, podemos pasar varios objetos para guardarlos en un lote
- findOne (…) : obtenga una única entidad basada en el valor de clave principal pasado
- findAll () : obtiene un Iterable de todas las entidades disponibles en la base de datos
- count (): devuelve el recuento de entidades totales en una tabla
- eliminar (…) : elimina una entidad basada en el objeto pasado
- existe (…): verifica si una entidad existe según el valor de clave primaria pasado
Esta interfaz parece bastante genérica y simple, pero en realidad, proporciona todas las abstracciones de consulta básicas necesarias en una aplicación.
4. PagingAndSortingRepository
Ahora, echemos un vistazo a otra interfaz de repositorio, que extiende CrudRepository :
public interface PagingAndSortingRepository extends CrudRepository { Iterable findAll(Sort sort); Page findAll(Pageable pageable); }
Esta interfaz proporciona un método findAll (paginable) , que es la clave para implementar la paginación.
Cuando usamos Pageable , creamos un objeto Pageable con ciertas propiedades y tenemos que especificar al menos:
- Tamaño de página
- Número de página actual
- Clasificación
Entonces, supongamos que queremos mostrar la primera página de un conjunto de resultados ordenado por apellido, ascendente, que no tenga más de cinco registros cada uno. Así es como podemos lograr esto usando una PageRequest y una definición de clasificación :
Sort sort = new Sort(new Sort.Order(Direction.ASC, "lastName")); Pageable pageable = new PageRequest(0, 5, sort);
Pasar el objeto paginable a la consulta de datos de Spring devolverá los resultados en cuestión (el primer parámetro de PageRequest es de base cero).
5. JpaRepository
Finalmente, veremos la interfaz de JpaRepository :
public interface JpaRepository extends PagingAndSortingRepository { List findAll(); List findAll(Sort sort); List save(Iterable entities); void flush(); T saveAndFlush(T entity); void deleteInBatch(Iterable entities); }
De nuevo, veamos brevemente cada uno de estos métodos:
- findAll () : obtenga una lista de todas las entidades disponibles en la base de datos
- findAll(…) – get a List of all available entities and sort them using the provided condition
- save(…) – save an Iterable of entities. Here, we can pass multiple objects to save them in a batch
- flush() – flush all pending task to the database
- saveAndFlush(…) – save the entity and flush changes immediately
- deleteInBatch(…) – delete an Iterable of entities. Here, we can pass multiple objects to delete them in a batch
Clearly, above interface extends PagingAndSortingRepository which means it has all methods present in the CrudRepository as well.
6. Downsides of Spring Data Repositories
Beyond all the very useful advantages of these repositories, there are some basic downsides of directly depending on these as well:
- we couple our code to the library and to its specific abstractions, such as `Page` or `Pageable`; that's of course not unique to this library – but we do have to be careful not to expose these internal implementation details
- by extending e.g. CrudRepository, we expose a complete set of persistence method at once. This is probably fine in most circumstances as well but we might run into situations where we'd like to gain more fine-grained control over the methods exposed, e.g. to create a ReadOnlyRepository that doesn't include the save(…) and delete(…) methods of CrudRepository
7. Conclusion
Este artículo cubrió algunas diferencias y características breves pero importantes de las interfaces del repositorio Spring Data JPA.
Para obtener más información, consulte la serie sobre Spring Persistence.