Geralmente em projetos JavaEE/Spring criamos classes para abstrair métodos comuns de acesso ao banco de dados, como no exemplo demonstrado na figura a seguir, com o objetivo de ganharmos a centralização dessas implementações para uma melhor reusabilidade, no entanto, por serem classes proprietárias no sistema há o risco de alterações indevidas ou de bugs com grande impactos em todo projeto, com isso, o projeto Spring Data trás algumas facilidades em conjunto com alguns padrões de projetos para utilizarmos em nossos projetos.
No código a baixo é demonstrado um exemplo de uma classe proprietária com o objetivo de abstrair os principais métodos de manipulação de banco de dados e restringir o acesso ao entityManager.
public abstract class AbstractService<T extends Model, ID extends Serializable> { ... @PersistenceContext private EntityManager entityManager; public T findById(Long id) { return this.entityManager.find(type, id); } @Transactional public void remove(T object) { this.entityManager.remove(this.entityManager.getReference(this.type, object.getId())); } @Transactional public void save(T object) { if (object.getId() == null) { this.entityManager.persist(object); } else { this.entityManager.merge(object); } } ... }
No entanto, essa implementação não é necessária quando utilizado Spring Data, pois na interface JpaRepository disponibiliza uma série de métodos com operações padrões de acesso ao banco via JPA, basta implementar essa interface utilizando o padrão Repository do Spring, como demonstrado no exemplo a seguir.
Para utilizar o Spring Data, adicionar a dependência spring-data-jpa.
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>1.10.8.RELEASE</version> </dependency>
Após adicionado a dependência do Spring Data é preciso criar uma interface para extender os recursos do JpaRespository, pois essa interface disponibiliza métodos como findAll, save, saveAndFlush, deleteInBatch, entre outros.
import org.springframework.data.jpa.repository.JpaRepository; public interface PessoaRepository extends JpaRepository&amp;amp;lt;Pessoa, Long&amp;amp;gt; {
Ao extender a interface JpaRepository são passados via parâmetro a classe e o tipo do id da entidade gerenciado pelo repositório. No caso do exemplo, é definido o PessoaRepository para gerenciar a entidade Pessoa que possui ID do tipo Long.
Mais detalhes de como usar o JpaRespository pode ser visto na doc do Spring Data.
Após criado a interface PessoaRepository, é preciso habilitar os repositórios JPA no contexto do Spring, isso é feito através da anotação @EnableJpaRepositories.
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackageClasses = {PessoaRepository.class}) @ComponentScan(basePackageClasses = {PessoaService.class}) public class AppConfig {
Após habilitado os repositórios no contexto do Spring, é apenas injetar a interface na classe desejada para ter acesso aos métodos proporcionados pelo Spring Data.
@Service public class PessoaService { @Autowired private PessoaRepository pessoaRepository; public List&amp;amp;lt;Pessoa&amp;amp;gt; findAll() { return pessoaRepository.findAll(); } public void save(Pessoa pessoa) { return pessoaRepository.save(pessoa); } public void findById(Long id) { return pessoaRepository.findOne(id); } public void delete(Long id) { return pessoaRepository.delete(id); } }
Nesse post foi possível ver apenas uma das facilidades que o Spring Data proporciona para nossos projetos, além da interface JpaRepository há outras como CrudRepository e PagingAndSortingRepository, integração com QueryDsl, como exemplo a interface QueryDslPredicateExecutor, integração com base de dados NoSQL, entre outros.
Complemento:
Segue um commit exemplificando a migração de um abstract service para a utilização de JpaRepository do Spring Data: https://github.com/emmanuelneri/springmvc-angularjs/commit/5402edfba70cc35f858727dd5c166ada6064cb58