CrudRepository, JpaRepository e PagingAndSortingRepository em Spring Data

CrudRepository, JpaRepository e PagingAndSortingRepository em Spring Data

1. Visão geral

Neste artigo rápido, vamos nos concentrar em diferentes tipos de interfaces de repositório Spring Data e sua funcionalidade. Vamos tocar em:

  • CrudRepository

  • PagingAndSortingRepository

  • JpaRepository

Simplificando, cada repositório emSpring Data estende a interface genéricaRepository, mas além disso, cada um deles tem uma funcionalidade diferente.

2. Spring Data Repositories

Let’s start with the JpaRepository - que estendePagingAndSortingRepository e, por sua vez, oCrudRepository.

Cada um deles define sua própria funcionalidade:

E então, por causa dessa relação de herança, oJpaRepository contains the full API of CrudRepository and PagingAndSortingRepository.

Quando não precisamos da funcionalidade completa fornecida porJpaRepositoryePagingAndSortingRepository, podemos simplesmente usar oCrudRepository.

Vamos agora dar uma olhada em um exemplo rápido para entender melhor essas APIs.

Começaremos com uma entidadeProduct simples:

@Entity
public class Product {

    @Id
    private long id;
    private String name;

    // getters and setters
}

E vamos implementar uma operação simples - encontre umProduct com base em seu nome:

@Repository
public interface ProductRepository extends JpaRepository {
    Product findByName(String productName);
}

Isso é tudo. O Repositório de Dados Spring gerará automaticamente a implementação com base no nome que fornecemos.

Este foi um exemplo muito simples, é claro; você pode ir mais fundo no Spring Data JPAhere.

3. CrudRepository

Vamos agora dar uma olhada no código para a interfaceCrudRepository:

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 a funcionalidade CRUD típica:

  • save(…) – salvaIterable de entidades. Aqui, podemos passar vários objetos para salvá-los em um lote

  • findOne(…) - obtém uma única entidade com base no valor de chave primária passado

  • findAll() - obtém umIterable de todas as entidades disponíveis no banco de dados

  • count() – rdefinir a contagem do total de entidades em uma tabela

  • delete(…) - exclui uma entidade com base no objeto passado

  • existe (…) - verifique se existe uma entidade com base no valor da chave primária passado

Essa interface parece bastante genérica e simples, mas, na verdade, fornece todas as abstrações básicas de consulta necessárias em um aplicativo.

4. PagingAndSortingRepository

Agora, vamos dar uma olhada em outra interface de repositório, que estendeCrudRepository:

public interface PagingAndSortingRepository
  extends CrudRepository {

    Iterable findAll(Sort sort);

    Page findAll(Pageable pageable);
}

Esta interface fornece um métodofindAll(Pageable pageable), que é a chave para implementarPagination.

Ao usarPageable, criamos um objetoPageable com certas propriedades e temos que especificar pelo menos:

  1. Tamanho da página

  2. Número da página atual

  3. Ordenação

Então, vamos supor que queremos mostrar a primeira página de um conjunto de resultados classificado porlastName, crescente, não tendo mais do que cinco registros cada. É assim que podemos conseguir isso usando uma definiçãoPageRequesteSort:

Sort sort = new Sort(new Sort.Order(Direction.ASC, "lastName"));
Pageable pageable = new PageRequest(0, 5, sort);

Passar o objeto paginável para a consulta de dados Spring retornará os resultados em questão (o primeiro parâmetro dePageRequest é baseado em zero).

5. JpaRepository

Por fim, daremos uma olhada na interfaceJpaRepository:

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);
}

Novamente, vamos examinar cada um desses métodos em resumo:

  • findAll() - obtém umList de todas as entidades disponíveis no banco de dados

  • findAll(…) - obtenha umList de todas as entidades disponíveis e classifique-as usando a condição fornecida

  • save(…) – salvaIterable de entidades. Aqui, podemos passar vários objetos para salvá-los em um lote

  • flush() – ftransfere todas as tarefas pendentes para o banco de dados

  • saveAndFlush(…) - salvar a entidade e limpar as alterações imediatamente

  • deleteInBatch (…) - excluiIterable de entidades. Aqui, podemos passar vários objetos para excluí-los em um lote

Claramente, a interface acima estendePagingAndSortingRepository, o que significa que tem todos os métodos presentes emCrudRepository também.

6. As desvantagens dos repositórios de dados Spring

Além de todas as vantagens muito úteis desses repositórios, existem algumas desvantagens básicas de depender diretamente também:

  1. acoplamos nosso código à biblioteca e às suas abstrações específicas, comoPage ouPageable; isso, obviamente, não é exclusivo desta biblioteca - mas temos que ter cuidado para não expor esses detalhes de implementação interna

  2. estendendo-se p. CrudRepository, expomos um conjunto completo de métodos de persistência de uma vez. Isso provavelmente é bom na maioria das circunstâncias também, mas podemos nos deparar com situações em que gostaríamos de obter um controle mais refinado sobre os métodos expostos, por exemplo, para criar umReadOnlyRepository que não inclui os métodossave(…)edelete(…) deCrudRepository

7. Conclusão

Este artigo abordou algumas diferenças e recursos breves, mas importantes, das interfaces do repositório Spring Data JPA.

Para obter mais informações, dê uma olhada na série emSpring Persistence.