Mostrando postagens com marcador spring. Mostrar todas as postagens
Mostrando postagens com marcador spring. Mostrar todas as postagens

quinta-feira, 13 de fevereiro de 2014

Easy-Cassandra, a versão 2.0.1

Lançada a nova versão do Easy-Cassandra, a versão 2.0.1, dentre as novidades podemos citar;
  • Refatoração nos contrutores das fábricas de sessão
  • QueryBuilder (InsertBuilder, UpdateBuilder, DeleteBuilder, SelectBuilder e BatchBuilder)
  • Maior velocidade na leitura e escrita
  • Suporte nos processos assíncronos
  • Maior suporte ao Cassandra com Spring-Data
Um ponto importante é que para facilitar a configuração foi criada uma classe que é passada no parâmetro, a classe ClusterInformation, dessa maneira fica mais simples (além do código mais limpo, afinal sobrecarga de construtores não é uma boa prática) de se criar simples configurações para a fábrica. Como, por exemplo:

ClusterInformation clusterInformation = ClusterInformation.create()
                .addHost(HOST)
                .withDefaultKeySpace(KEY_SPACE).withUser(USER).withPassword(PASS);
        easyCassandraManager = new EasyCassandraManager(clusterInformation);

Criando configuração para a fábrica de conexão
Dessa forma a configuração para usar o Spring no Cassandra também mudou para:





 
 
  
   localhost
  
 



 
 
  
   org.easycassandra.persistence.cassandra.spring.entity.Contact
            org.easycassandra.bean.model.Step
            org.easycassandra.bean.model.Weight
  
 



 



Nova configuração do Spring no Easy-Cassandra
Talvez a melhoria mais marcante nessa versão são os recursos dos QueryBuilders, os queryBuilders são maneiras muito mais fácil de fazer interações com o Cassandra com configurações adversas de uma maneira mais simples, com ele é possível definir o nível de consistência, definir o timeStamp, quais campos serão manipulados.

 SimpleID id = new SimpleID();
    id.setIndex(ONE_HUNDRED_THIRTY);
    id.setKey(ONE_HUNDRED_THIRTY);
    UpdateBuilder update = template.updateBuilder(SimpleQueryBuilder.class, key);
    update.put("map", "name", "otavioMap").value("value", TEN_DOUBLE).execute();

Simples exemplo inserindo valores a partir da chave
UpdateBuilder update = persistence.updateBuilder(SimpleQueryBuilder.class);
 update.whereEq(Constant.KEY, Constant.ONE).whereEq(Constant.INDEX, Constant.ONE).addList("list", "otavioList").execute();

criando toda a query de atualização
 UpdateBuilder update = persistence.updateBuilder(SimpleQueryBuilder.class);
 update.whereEq(Constant.KEY, Constant.ONE).whereEq(Constant.INDEX, Constant.ONE).value("value", 12D).executeAsync(new ResultAsyncCallBack() {
    @Override
    public void result(Boolean bean) {
        // do some action
    }
});
executando uma atualização assincronamente
InsertBuilder insert= persistence.updateBuilder(SimpleQueryBuilder.class);
Set set = new HashSet<>();
set.add("Linda");
Map map = new HashMap<>();
map.put("love", "Otavio and Poliana");
insert.value(Constant.KEY, Constant.ONE_HUNDRED).value(Constant.INDEX,
            Constant.ONE_HUNDRED).value(Constant.LIST_COLUMN, Arrays.asList("Poliana", "Otavio", "Love")).value(Constant.SET_COLUMN, set).value("map", map).execute();

Realizando inserção
  SimpleID id = new SimpleID();
    id.setIndex(ONE_HUNDRED_TWO);
    id.setKey(ONE_HUNDRED_TWO);
    SimpleBean simpleBean = new SimpleBean();
    simpleBean.setId(id);
    simpleBean.setValue(VALUE);
    InsertBuilder insert2 = persistence.updateBuilder(simpleBean);
    insert2.executeAsync((new ResultAsyncCallBack() {
    @Override
    public void result(Boolean bean) {
        // do some action
    }
    });
realizando inserção de modo assíncrono
  DeleteBuilder delete = persistence.deleteBuilder(SimpleQueryBuilder.class); 
    delete.whereEq(Constant.INDEX, ONE_HUNDRED_TWO).whereEq(Constant.KEY, ONE_HUNDRED_TWO).execute();

    DeleteBuilder delete2 = persistence.deleteBuilder(SimpleQueryBuilder.class,"map", "list", "set"); //Delete specific columns
    delete2 .whereEq(Constant.INDEX, ONE_HUNDRED_TWO).whereEq(Constant.KEY, ONE_HUNDRED_TWO).execute();

primeira query remove todas as colunas a partir da chave, na segunda query remove apenas os campos map, list e set.
 SimpleID id = new SimpleID();
    id.setIndex(ONE_HUNDRED_TWO);
    id.setKey(ONE_HUNDRED_TWO);

    DeleteBuilder delete2 = persistence.deleteBuilder(SimpleQueryBuilder.class, id);
    delete2.executeAsync((new ResultAsyncCallBack() {
    @Override
    public void result(Boolean bean) {
        // do some action
    }
    });
remoção assíncrona
  SelectBuilder select = persistence.selectBuilder(SimpleQueryBuilder.class);
  select.eq("name", "name");
  select.in("index", ONE, TWO, THREE);
  List result = select.execute();

Realizando o select em que o campo nome é igual a nome e o indice está em um, dois e três.
SelectBuilder select = persistence.selectBuilder(SimpleQueryBuilder.class);
select.eq(NAME, NAME).gt("index", THREE).asc(INDEX).executeAsync(new ResultAsyncCallBack>() {

        @Override
        public void result(List beans) {
          // do some thing
        }
    });
Executando query assincronamente em que o indece seja mais que três e seja ordenado de forma descendente no índice.
O Batch é um recurso no cassandra que permite que se execute alterações no banco (inserção, atualização e remoção) de forma atômica, desse forma se pode enviar insert, updates e deletes como se fosse apenas uma requisição.

DeleteBuilder delete = dao.deleteBuilder();
    delete.whereEq(Constant.INDEX, Constant.ONE_HUNDRED_TWO)
            .whereEq(Constant.KEY, Constant.ONE_HUNDRED_TWO);

    InsertBuilder insert = dao.insertBuilder();
    insert.value(Constant.KEY, Constant.ONE_HUNDRED).value(Constant.INDEX,
            Constant.ONE_HUNDRED);
    insert.value(Constant.LIST_COLUMN,
            Arrays.asList("Poliana", "Otavio", "Love"));

    UpdateBuilder update = dao.update();
    update.whereEq(Constant.KEY, Constant.ONE).whereEq(Constant.INDEX, Constant.ONE);
    update.addList("list", "otavioList");

    BatchBuilder batchBuilder = dao.batchBuilder();

    batchBuilder.addOperations(delete, insert, update);
    batchBuilder.executeAsync(new ResultAsyncCallBack() {
        @Override
        public void result(Boolean bean) {
            // do some action
        }
    });
Executando processo de inserção, remoção e atualização de forma atômica com o BatchBuilder.
Vale lembrar que recurso do Batch deve ser usados em casos específicos, já que distribuir as requisições entre os nós, no cassandra, sempre será sua melhor amiga.
Esse artigo tem como objetivo ilustrar as mudanças dentro do Easy-Cassandra, se demonstrou dos recursos e da sua melhoria na velocidade a expectativa é que muitos mais recursos estejam por vir.
  1. https://github.com/otaviojava/Easy-Cassandra/wiki/Builders
  2. https://github.com/otaviojava/Easy-Cassandra/wiki
  3. https://github.com/otaviojava/Easy-Cassandra/
  4. https://github.com/otaviojava/Easy-Cassandra-samples

domingo, 25 de agosto de 2013

Usando Cassandra com Spring Data no Easy-Cassandra

Spring Data no Cassandra com Easy-Cassandra

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.

  • Bancos Relacionais com JPA e JDBC
  • BigData com Apache Hadoop
  • Data-Grid com GermFire
  • HTTP com Rest
  • NOSQL com MongoDB, Neo4J, Redis e Hbase

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

}

Simples Pojo da Classe 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.



 

 
 
 
  
   org.javabahia.cassandra.spring.entity.Person
  
 
 


 





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); 

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;
 }

}

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(); 
}

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());
     
     
    }
}

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.



Links:

Spring Data: http://www.springsource.org/spring-data
Easy-Cassandra: http://otaviojava.github.io/Easy-Cassandra/
Exemplo: https://github.com/otaviojava/Easy-Cassandra-samples