Mais um post falando sobre persistência em Java com QueryDSL, mas agora explorando também o Spring Data. O Spring Data é uma tecnologia criada para facilitar a criação de componentes de acesso a dados via: bancos relacionais, NoSQL,
map-reduce e serviços baseados em cloud.
Olhando para base de dados relacionais, o Spring Data oferece componentes para JPA e JDBC. Em outro post escrevi sobre o QueryDSL, uma ferramenta para produzir consultas flexíveis encima da JPA (e outros mecanismos de persistência) com uma DSL bem interessante. Evoluindo aquela abordagem, meu objetivo é apresentar outra estratégia para persistência unindo o QueryDSL e Spring Data para JPA / Hibernate.
Compartilhei no Github um projeto que pode ser referência para esse post. Outro detalhe importante é que o projeto foi construído com o Spring Boot, que disponibiliza um Tomcat embutido. A classe Application é o ponto de entrada da aplicação, aonde ficam contidas as configurações do projeto. É o caso da anotação EnableJpaRepositories, que indica o pacote base dos componentes Repositories. O código a seguir demonstra o componente MercadoriaRepository, uma interface anotada como Repository responsável pela operações de persistência da entidade Mercadoria.
1 2 3 4 5 6 | @Repository public interface MercadoriaRepository extends JpaRepository<Mercadoria, Long>, QueryDslPredicateExecutor<Mercadoria> { … } |
JpaRepository é uma interface do Spring que define operações básicas de persistência sobre uma determinada entidade. Operações para CRUD, paginação e ordenação. Já a interface QueryDslPredicateExecutor atua como uma bridge entre o Spring Data e QueryDSL. Através dela é possível usar Predicates construídos via QueryDSL em consultas via Spring Data.
É possível e válido definir uma classe concreta como Repository. Mas prefiro definir esses componentes como contratos, sendo o Spring o responsável por escrever código que implementa (proxy) as interfaces. Mesmo em interface, o Spring Data permite a definição de métodos para consultas customizados.
No controller, o proxy de MercadoriaRepository é injetado pelo Spring, via anotação Autowired. A seguir trecho de código do componente MercadoriaController, com destaque para a definição do Repository e o método list, responsável por realizar a consulta de Mercadorias de acordo com os filtros informados:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | @RestController @RequestMapping (value= "/" ) public class MercadoriaController { @Autowired private MercadoriaRepository repository; @RequestMapping (method = RequestMethod.GET) public PesquisaMercadorias list(FiltrosPesquisaMercadoria filtros) { Pageable page = buildPageRequest(filtros.getPagina(), filtros.getLinhas(), filtros.getOrdem()); Predicate predicate = whereByCriterio(filtros); long total = repository.count(predicate); List<Mercadoria> mercadorias = Lists.newArrayList(repository.findAll(predicate, page)); return new PesquisaMercadorias(total, mercadorias); } ... } |
O primeiro passo é construir Pageable com as configurações para paginação e ordenação via buildPageRequest. Depois construir o Predicate com as condições da consulta, via whereByCriterio, que será utilizado no contador de registros (informação para paginação) e para processar a consulta das mercadorias. Ambos os métodos count(Predicate) e findAll(Predicate) são definidos em QueryDSLPredicatorExecutor.
Os métodos save e delete, definidos em JpaRepository (CrudRepository), também são acionados pelo controller:
1 2 3 4 5 6 7 8 9 | @RequestMapping (method = RequestMethod.POST) public void save(Mercadoria m) { repository.save(m); } @RequestMapping (method = RequestMethod.DELETE) public void delete(Long mercadoriaId) { repository.delete(mercadoriaId); } |
Todas as operações de persistência foram centralizadas na interface MercadoriaRepository, mas ela delega o update em batch e consulta de tuplas para MercadoriaQuery, via métodos default do Java 8.
Outros detalhes sobre o projeto:
- O build e as dependências do projeto são controladas pelo Maven e/ou Gradle;
- Spring MVC atua como framework web;
- JQuery e Foundation no front-end da aplicação
1 comment:
Excelente seu exemplo! Obrigado por compartilhar. Ajudou muito no processo de incluir API queryDSL no meu projeto.
Post a Comment