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@Repository2public class UserRepository {3
4    @PersistenceContext5    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@Transactional2public 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@Transactional2public 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@Transactional12public 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.
1public 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.