Aprenda a configurar e utilizar o Spring MVC junto com o Spring Data no Tomcat, controle transacional, exemplos de uso e boas praticas, uso do spectations do spring data.
Vamos aprender como configurar o Spring Data em conjunto com o Spring MVC, utilizar anotações para controle transacional, usar spectations no Spring Data para termos uma DSL de nossas consultas
Nesse projeto utilizaremos a versão 4.X.X do Spring, Maven para resolução de dependências, e o Tomcat como container
Não vamos entrar na criação do projeto Maven, suponho que já possua o conhecimento, e já tenha o projeto criado, caso não pode dar uma olhada aqui
As dependências que vamos utilizar são as seguintes
Usaremos o Jackson para serialização de nossa entidade em JSON, o hibernate como implementação do JPA, o banco de dados será em memória utilizando o H2
Vamos começar configurando nosso projeto, vamos criar a classe SpringConfig, no pacote "me.efraimgentil.springmvcanddata.config", essa classe irá contér as configurações básicas de beans do Spring
Nessa classe estamos apenas sinalizando ao Spring, por meio da anotação ComponentScan, para escanear a partir do pacote raiz em busca dos components do Spring
Em seguida temos a configuração do Spring MVC, para gerenciar nossas rotas
Aqui, também não temos nada novo, estamos habilitando o MVC com a anotação EnableWebMvc, ela é basicamente o equivalente a configuração xml '', ou seja irá reconhecer nossas anotações Controller e RequestMapping. Estamos também dizendo onde procurar os nossos controllers com a anotação ComponentScan
Vamos configurar agora nossa base de dados, controle transacional e os repositórios com Spring Data
Essa configuração é mais extensa, primeiro temos a anotação @EnableTransactionManagement ela irá permitir que utilizemos a anotação @Transactional em nossos métodos para sinalizar que serão rodados dentro de uma transação, em seguida temos a anotação @EnableJpaRepositories, ela habilita os repositórios do Spring Data, especificamos na anotação em que pacotes esses repositórios residirão.
Temos o nosso datasource, estamos fazendo uma configuração simples utilizando o DriverManagerDataSource, não utilize essa configuração em produção, pois a cada chamada do getConnection será criada uma nova conexão, para simplificar o exemplo estamos utilizando essa implementação.
Temos também a configuração do nosso EntityManagerFactory, aqui apenas configuramos o datasource que será utilizado, o pacote onde nossas entidades estão residindo, o provider que será utilizado no caso HibernatePersistenceProvider, e configuramos o hibernate.
Por fim temos a configuração do nosso transactionManager, aqui utilizamos o JpaTransactionManager, e apontamos para o nosso EntityManagerFactory configurado anteriormente
Veja que na assinatura dos métodos apontam para o DataSource e o EntityManagerFactory, não se preocupe, o Spring vai tratar da injeção desses objetos para você
Com isso vamos finalizar a configuração criando nosso WebInitializer como a seguir
Com isso temos nosso projeto configurado e pronto para rodar, agora vamos criar nossa entidade User e nosso repositório UserRepository como a seguir:
Não precisamos anotar nosso repositório com nenhuma anotação, já marcamos em nossas configurações qual package escanear, o Spring vai verificar a interface e reconhecer que se trata de um repositório, já que a interfece está extendẽndo de JpaRepository
Ok agora vamos criar nosso controller, que irá servir nossa entidade como JSON, veja a seguir
Nos injetamos a interface repository, que irá tratar nossas requisições a base de dados, não se preocupe com a implementação da interface, o Spring Data vai cuidar disso para você, e fornecer alguns métodos padrões necessários para toda aplicação, como save, delete, find etc...
Note o método allActiveUsers no controller, nele estamos fazendo uma chamada ao método findAll do repositório, e passando como parâmetro a chamada where(...), que recebe como parâmetro um Specification, no nosso caso estamos passando um lambda expression e estamos deixando o Java cuidar do resto, o retorno da nossa expressão lambda DEVE retornar uma Prediction ou null ( null simplesmente será ignorado )
O método where esta vindo de um import static org.springframework.data.jpa.domain.Specifications.*;
Perceba que é bem prático utilizar as Specifications, porém como pode ser visto no método allActiveUsersWithRole, com mais critérios para consulta, fica mais complexo ler e entender o que está acontecendo, por isso vamos criar uma classe chamada UserSpecs como a seguir
Com isso podemos usar esses métodos com nomes mais intuitivos, e até encadear suas chamadas, criando assim uma DSL própria do nosso sistema, claro que aqui estamos fazendo um exemplo simples, mas é possível trabalhar com coisas bem mais complexas como sub-queries. Veja a seguir como fica o nosso controller
Veja que temos uma API bem mais fluida, e facilita bastante a leitura do que estamos buscando, na tradução literal seria como "busque tudo onde ativo e com perfil especificado"
Agora basta fazer o deploy no tomcat e começar a experimentar, o UserController está mapeado para a raiz do projeto então provavelmente você vai acessar como na url a seguir "http://localhost:8080/springmvcanddata/". Faça seus próprios testes, crie uma entidade ou tente pegar uma implementação do trabalho e mudar para Spring Data, vai ser divertido!