Criando o repositório

Após realizar o mapeamento da classe Java com a tabela do banco de dados através das anotações agora é necessário criar a camada que irá realizar os acessos ao banco de dados. Como vimos anteriomente, essa camada é chamada de repositório.

Para criar o repositório, crie um novo arquivo chamado UserRepository.java dentro da pasta de repositórios. Essa classe vai utilizar algumas anotações para indicar ao framework que essa classe é um repositório e que ela deve ser gerenciada pelo Spring.

1
@Repository
2
public class UserRepository {
3
4
@PersistenceContext
5
public EntityManager em;
6
7
public List<User> findAll() {
8
String sql = "SELECT * FROM user";
9
Query q = em.createNativeQuery(sql, User.class);
10
List<User> users = q.getResultList();
11
return users;
12
}
13
14
}

A anotação @Repository indica que essa classe é um repositório e que ela deve ser gerenciada pelo Spring. A anotação @PersistenceContext indica que o Spring deve injetar uma instância de EntityManager nessa classe. O EntityManager é uma classe que gerencia as entidades e realiza as operações de acesso ao banco de dados.

Agora vamos criar o método findAll() que vai realizar a consulta no banco de dados e retornar todos os usuários cadastrados. Para isso, vamos criar uma consulta SQL utilizando a classe Query e o método createNativeQuery() que recebe como parâmetro a consulta SQL e o tipo de entidade que será retornado. Em seguida, vamos utilizar o método getResultList() para retornar a lista de usuários.

A única diferença que temos agora é que a fonte de dados passou a ser o banco de dados e não a lista armazenada em memória, logo os demais passos de criar o controllador e a visão são os mesmos. Se olharmos para o repositório que criamos anteriormente, alémm do método findAll() tinhamos ainda os métodos save(), delete(), update() e findById().

Para que o repositório fique completo, precisamos também criar esses métodos. Lembre-se, esses métodos mapeiam o que chamamos de operações CRUD, de forma que o repositório possa realizar as operações de inserção, atualização, exclusão e consulta de dados.

Vamos então aos próximos métodos, começando pelo save() que irá permitir a inserção de um novo usuário no banco de dados.

1
@Transactional
2
public void save(User user) {
3
String sql = "INSERT INTO user (email, password) VALUES (:nome, :email)";
4
Query query = em.createNativeQuery(sql);
5
query.setParameter("nome", user.getEmail());
6
query.setParameter("email", user.getPassword());
7
query.executeUpdate();
8
}

No método save temos algumas novidades. A primeira delas é a anotação @Transactional que indica que o método deve ser executado dentro de uma transação. Uma transação é um conjunto de operações que devem ser executadas de forma atômica, ou seja, ou todas as operações são executadas com sucesso ou nenhuma delas é executada.

A segunda novidade é a utilização do método setParameter() que recebe como parâmetro o nome do parâmetro e o valor que será atribuído. Esse método é utilizado para evitar ataques de SQL Injection, pois o Spring irá tratar os valores passados como parâmetros e não como parte da consulta SQL. Perceba que na consulta SQL estamos utilizando :nome e :email como parâmetros. Esses parâmetros serão substituídos pelos valores passados no método setParameter().

Por fim, temos o método executeUpdate() que é utilizado para executar operações de inserção, atualização e exclusão de dados. Esse método retorna um inteiro que indica a quantidade de registros afetados pela operação. Mas por enquanto não estamos utilizando esse retorno. As próximas operações de atualização e exclusão de dados são bem parecidas com a operação de inserção.

1
@Transactional
2
public void update(User user) {
3
String sql = "UPDATE user SET email = :email, password = :password WHERE id = :id";
4
Query query = em.createNativeQuery(sql);
5
query.setParameter("id", user.getId());
6
query.setParameter("email", user.getEmail());
7
query.setParameter("password", user.getPassword());
8
query.executeUpdate();
9
}
10
11
@Transactional
12
public void delete(String id) {
13
String sql = "DELETE FROM user WHERE id = :id";
14
Query query = em.createNativeQuery(sql);
15
query.setParameter("id", id);
16
query.executeUpdate();
17
}

O último método do repositório é o findById() que vai retornar um usuário a partir do seu id.

1
public User findById(int id) {
2
String sql = "SELECT * FROM user WHERE id = :id";
3
Query q = em.createNativeQuery(sql, User.class);
4
q.setParameter("id", id);
5
User user = (User) q.getSingleResult();
6
return user;
7
}

A única diferença do método findById() para os demais é que ele utiliza o método getSingleResult() que retorna apenas um registro. Esse método é utilizado quando sabemos que a consulta irá retornar apenas um registro. Caso a consulta retorne mais de um registro, o método getSingleResult() irá lançar uma exceção.

Agora que o repositório está completo, você pode continuar criando o Controlador e as visões para realizar as operações de CRUD. Faça as alterações e rode novamente a aplicação para testar.