Cassandra com Spring Data no Easy-Cassandra

Veja nesse artigo mais sobre o Cassandra e o Spring. O Spring é um dos frameworks mais populares dentro do mundo Java. Dentre as extensões está o Spring Data, framework para criar uma API de alto nível para persistência de dados.

O Spring é um framework open source cujo o objetivo sempre foi facilitar a vida do desenvolvedor Java, começou com os recursos para injeção de dependência e hoje atua em diversas atividades triviais para um programador. Entre elas podemos citar a parte social com o Spring social no twitter, facebook, segurança com o Spring security além do já inversão de controle e inversão de dependência. O foco desse pequeno post é falar sobre o Spring Data e seu trabalho com o banco não relacional Cassandra.

O Spring-data é um pequeno módulo ou plugin do Spring e tem como objetivo auxiliar nos processos triviais de persistência criando uma camada entre a base onde se encontra as informações e o seu código java. Dessa maneira é possível, efetuar ações na base, usando como estrutura para as informações, o POJO (simples e velho objetos em java). Dentro do Spring Data já existem diversos tipo de base de informações.

Uma das grandes vantagem do Spring Data é ser filho do Spring. Ele não precisa de um servidor Java EE, ou seja, ele pode rodar em um simples contêiner como o tomcat ou mesmo rodar sem o auxílio do servidor. Sua injeção funciona com auxílio de um arquivo xml, mas não necessariamente toda configuração é feita por lá, existem várias anotações que podem ajudar o desenvolvedor, no entanto, cabe apenas ao mesmo saber em qual momento é mais adequado usar cada um deles.

Com esse foco o Spring Data Cassandra tem o foco de criar uma camada de alto nível para o nosql Cassandra, assim é possível com estruturas de POJOs estabelecer uma conexão no banco e realizar as operações CRUD, tudo isso sem abrir mão da estrutura de dados já conhecida pelo desenvolvedor Java. O Spring Data Cassandra ainda não foi fechada, mas o Easy-Cassandra já possui integração com Spring, agora é possível utilizá-lo com a injeção de dependências do framework Java mais famoso do mundo.

A aplicação será realmente bastante simples seu objetivo será apenas criar uma informação e armazenar no banco, em seguida recuperar pelo id. O primeiro passo será a criação da entidade pessoa, ela terá os campos id, nome e ano, conforme mostra a tabela número1.

@Entity(name = "person") public class Person implements Serializable { @Id private UUID id; @Index @Column(name = "name") private String name; @Column(name = "born") private Integer year; //getter and setter }
Listagem 1. Criando a entidade pessoa

Como pode ser visto os campos são anotados via JPA 2.0, o segundo passo é a criação do xml, é nele que conterá as configurações do banco de dados (host, porta, keyspace padrão, etc.). O próximo passo é a configuração e criação da fábrica de conexões para o Cassandra dentro do spring, isso é, o host, porta e o keyspace padrão, e as classes que serão mapeadas como mostra no arquivo xml abaixo.

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <context:component-scan base-package="org.javabahia.cassandra.spring" /> <bean id="cassandraFactory" class="org.easycassandra.persistence.cassandra.spring.CassandraFactoryAnnotation"> <constructor-arg name="host" value="localhost" /> <constructor-arg name="keySpace" value="spring" /> <property name="annotatedClasses"> <list> <value>org.javabahia.cassandra.spring.entity.Person</value> </list> </property> </bean> <bean id="cassandraTemplate" class="org.easycassandra.persistence.cassandra.spring.SimpleCassandraTemplateImpl" > <constructor-arg name="factory" ref="cassandraFactory" /> </bean> </beans>
Listagem 2. Configuração do Spring-Data, informando as configurações do Banco (host, porta, nesse caso a padrão, e o keySpace) além de criar o Template Cassandra

Com a fábrica de conexões do cassandra é possível retornar uma sessão, a via de comunicação do Cassandra com a aplicação Java, além disso será criado o CassandraTemplate, uma api de alto nível que consegue realizar a comunicação Cassandra sua aplicação a partir de um simples POJO, desse modo é possível realizar a operação CRUD de uma maneira bastante simples, o código abaixo mostra a interface do Cassandra template.

public interface CassandraTemplate{ <T> T save(T entity); <T> Iterable<T> save(Iterable<T> entities); <T> void delete(T entity); <T> void delete(Iterable<T> entities); <K> void delete(K key, Class<?> entity); <K,T> void delete(Iterable<K> keys, Class<T> entity); <T> void deleteAll(Class<T> entity); <T> T update(T entity); <T> Iterable<T> update(Iterable<T> entities); <T,K> T findOne(K key, Class<T> entity); <T,K> List<T> findAll(Iterable<K> keys, Class<T> entity); <T> List<T> findAll(Class<T> entity); <T,I> List<T> findByIndex(String columnName,I index,Class<T> entity); <K,T>boolean exist(K key, Class<T> entity); void executeUpdate(String query);
Listagem 3. Operações que podem ser realizadas com o seu Objeto

Além do CassandraTemplate existe o CassandraRepository, essa classe abstrata implementa o CrudRepository do SpringData, com ela é necessário apenas implementar o método que retornará o CassandraTemplate, conforme mostra a tabela abaixo.

@Repository("personRepository") public class PersonRepository extends CassandraRepository<Person, UUID>{ @Autowired private CassandraTemplate cassandraTemplate; @Override protected CassandraTemplate getCassandraTemplate() { return cassandraTemplate; } }
Listagem 4. Criando o repositório para a classe Person

Como o CassandraReporitory implementa a classe base de operações do Spring todas as suas operações estarão disponíveis para serem utilizadas com o Cassandra.

public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { <S extends T> S save(S entity); <S extends T> Iterable<S> save(Iterable<S> entities); T findOne(ID id); boolean exists(ID id); Iterable<T> findAll(); Iterable<T> findAll(Iterable<ID> ids); long count(); void delete(ID id); void delete(T entity); void delete(Iterable<? extends T> entities); void deleteAll(); }
Listagem 5. Interface CrudRepository do Spring Data que é implementada pela classe abstrata CassandraRepository

Realizado as configurações o próximo passo é executar o projeto como mostra o código a seguir:

public class App { public static void main( String[] args ) { @SuppressWarnings("resource") ApplicationContext ctx = new GenericXmlApplicationContext("SpringConfig.xml"); PersonRepository personService=ctx.getBean(PersonRepository.class); UUID uuid=UUID.randomUUID(); Person person=new Person(); person.setId(uuid); person.setName("Otávio Santana"); person.setYear(25); personService.save(person); Person otavio=personService.findOne(uuid); System.out.println(otavio.getName()); } }
Listagem 6. Rodando o Simples Projeto, salvando e recuperando a informação

Com isso foi demonstrado o conceito do Spring Data e o seu funcionamento com o Cassandra utilizando o Easy-Cassandra, o intuito criar uma interface padrão para que todos os modelos de persistência a utilizem dentro do Spring é um grande e importante passo para utilizar uma nova base ou modelo de dados não haja impacto dentro do Spring, mas é muito importante salientar que mesmo que vários bancos utilizem essa interface é importante considerar uma nova modelagem, já que diferente dos bancos relacionais, a mudança de um banco NOSQL pode significar a mudança estrutura de armazenamento.

Artigos relacionados