Apresentando o Spring Data JDBC

No próximo lançamento do Spring Data, codinome Lovelace, incluiremos um novo módulo: Spring Data JDBC .


A idéia por trás do Spring Data JDBC é fornecer acesso a bancos de dados relacionais sem usar toda a complexidade do JPA .


O JPA oferece recursos como carregamento lento , armazenamento em cache e rastreamento de alterações (rastreamento sujo). Apesar de esses recursos serem muito interessantes, se você realmente precisar deles, é claro, eles podem complicar bastante o entendimento da lógica do acesso a dados.


O mecanismo de carregamento lento pode repentinamente executar solicitações que consomem muitos recursos ou até falhar com uma exceção. O armazenamento em cache pode atrapalhar quando você decide comparar duas versões de uma entidade e, juntamente com as alterações de rastreamento , fica mais difícil entender em que momento todas as operações do banco de dados serão realmente executadas?


Spring Data O JDBC se concentra em um modelo muito mais simples . Não haverá armazenamento em cache, rastreamento de alterações ou carregamento lento. Em vez disso, as consultas SQL serão executadas se e somente se você chamar o método de repositório. O resultado retornado será totalmente carregado na memória após a execução do método. Não haverá mecanismo de "sessão" ou objetos de proxy para entidades. E tudo isso deve tornar o Spring Data JDBC uma ferramenta mais simples e intuitiva para acessar dados.


Obviamente, essa abordagem simplificada se traduz em várias limitações, que discutiremos nas próximas postagens. O próximo lançamento é a primeira versão da biblioteca, temos muitos planos e idéias que queremos implementar, mas precisamos adiá-los para que você tenha a oportunidade de começar a usar o Spring Data JDBC o mais cedo possível.


Exemplo


Para começar, precisamos definir a entidade:


class Customer { @Id Long id; String firstName; LocalDate dob; } 

Observe que não definimos getters ou setters. Claro, você pode adicioná-los, se quiser. Em essência, o único requisito para uma entidade é ter o campo anotado com uma anotação de Id (mas é org.springframework.data.annotation.Id , não javax.persistence one ).

Em seguida, você precisa definir o repositório. A maneira mais fácil de fazer isso é estender a interface CrudRepository .


 interface CustomerRepository extends CrudRepository<Customer, Long> {} 

Por fim, você precisa configurar o ApplicationContext para que a implementação dessa interface seja criada automaticamente:


 @Configuration @EnableJdbcRepositories (1) public class CustomerConfig extends JdbcConfiguration { (2) @Bean NamedParameterJdbcOperations operations() { (3) return new NamedParameterJdbcTemplate(dataSource()); } @Bean PlatformTransactionManager transactionManager() { (4) return new DataSourceTransactionManager(dataSource()); } @Bean DataSource dataSource(){ (5) return new EmbeddedDatabaseBuilder() .generateUniqueName(true) .setType(EmbeddedDatabaseType.HSQL) .addScript("create-customer-schema.sql") .build(); } } 

Vamos analisar a configuração com mais detalhes.


  1. EnableJdbcRepositories a criação automática de repositório. Para que isso funcione, é necessário fornecer vários beans adicionais, o que exigirá o restante de nossa classe de configuração.
  2. Porque se a classe de configuração estender JdbcConfiguration , vários beans serão adicionados ao contexto automaticamente. Você também pode sobrepô-los se precisar alterar o comportamento do Spring Data JDBC. Mas neste exemplo, deixaremos o comportamento padrão.
  3. Um componente muito importante é NamedParameterJdbcOperations , que é usado para executar consultas ao banco de dados.
  4. Um gerenciador de transações, estritamente falando, não é necessário. Mas sem ele, não haverá suporte a transações e poucos vão gostar, certo?
  5. O Spring Data JDBC não usa o DataSource diretamente, mas o TransactionManager e NamedParameterJdbcOperation exigem sua presença no contexto, e é por isso que determinamos o bean desejado.

Isso é tudo o que é necessário para iniciar o Spring Data JDBC. Agora escreva um teste para ver como tudo funciona:


 @RunWith(SpringRunner.class) @Transactional @ContextConfiguration(classes = CustomerConfig.class) public class CustomerRepositoryTest { @Autowired CustomerRepository customerRepo; @Test public void createSimpleCustomer() { Customer customer = new Customer(); customer.dob = LocalDate.of(1904, 5, 14); customer.firstName = "Albert"; Customer saved = customerRepo.save(customer); assertThat(saved.id).isNotNull(); saved.firstName = "Hans Albert"; customerRepo.save(saved); Optional<Customer> reloaded = customerRepo.findById(saved.id); assertThat(reloaded).isNotEmpty(); assertThat(reloaded.get().firstName).isEqualTo("Hans Albert"); } } 

@Query


Somente com métodos CRUD padrão você pode ir longe do repositório de classes CrudRepository . Decidimos deliberadamente adiar a geração automática de consultas - um recurso popular do Spring Data, quando consultas SQL são geradas com base no nome do método - para versões futuras. E, por enquanto, você pode simplesmente usar a anotação familiar @Query para especificar exatamente qual consulta SQL deve ser executada.


 @Query("select id, first_name, dob from customer where upper(first_name) like '%' || upper(:name) || '%' ") List<Customer> findByName(@Param("name") String name); 

Se você deseja modificar ou excluir dados na solicitação, você pode adicionar a anotação @Modifying ao método


Vamos escrever um teste para ver como nosso novo método funciona.


 @Test public void findByName() { Customer customer = new Customer(); customer.dob = LocalDate.of(1904, 5, 14); customer.firstName = "Albert"; Customer saved = customerRepo.save(customer); assertThat(saved.id).isNotNull(); customer.id= null; (1) customer.firstName = "Bertram"; customerRepo.save(customer); customer.id= null; customer.firstName = "Beth"; customerRepo.save(customer); assertThat(customerRepo.findByName("bert")).hasSize(2); (2) } 

  1. Porque Como a conexão entre objetos Java e o registro no banco de dados é apenas por campo e tipo de Id , definir Id como null e salvar esse objeto criará um novo registro.
  2. Na solicitação, usamos como distinção entre maiúsculas e minúsculas e, portanto, encontramos "Albert" e "Bertram", mas não "Beth".

Em conclusão


Obviamente, muito mais pode ser dito sobre o Spring Data JDBC, e certamente o informaremos em artigos futuros.


Enquanto isso, você pode estudar o código de exemplo , a documentação e, é claro, o código-fonte . Se você tiver alguma dúvida, não hesite em perguntar- lhes no StackOverflow . E se você encontrar um bug ou quiser solicitar um novo recurso - crie um ticket .

Source: https://habr.com/ru/post/pt423697/


All Articles