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.
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.- 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. - Um componente muito importante é
NamedParameterJdbcOperations
, que é usado para executar consultas ao banco de dados. - 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?
- 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) }
- 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. - 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 .