Java Cassandra: novidades da versão 2.0.1 do Easy-Cassandra
Descubra as novidades da nova versão do framework ORM Easy-Cassandra 2.0.1. Dentre as suas novidades podemos destacar maior suporte ao uso do Spring Data, o uso de queryBuilder, além de realizar todas as interações de forma assíncrona.
Recentemente foi lançada a nova versão do Easy-Cassandra - versão 2.0. - e dentre as novidades podemos citar:
- Refatoração nos construtores 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.
Nota: Se você não conhece o projeto, não deixe de conferir esse artigo e entender o que é o Easy Cassandra.
Um ponto importante é que para facilitar a configuração foi criada a classe ClusterInformation, que é passada no parâmetro, de maneira simples, deixando o código mais limpo, afinal, sobrecarga de construtores não é uma boa prática. Um exemplo de configurações pode ser visto na Listagem 1.
Listagem 1. Classe ClusterInformation
ClusterInformation clusterInformation = ClusterInformation.create()
.addHost(HOST)
.withDefaultKeySpace(KEY_SPACE).withUser(USER).withPassword(PASS);
easyCassandraManager = new EasyCassandraManager(clusterInformation);
Dessa forma, a configuração para usar o Spring no Cassandra também mudou. Veja a Listagem 2.
Listagem 2. Configuração para o Cassandra
<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.easycassandra.persistence.cassandra.spring" />
<bean id = "clusterInformation" class="org.easycassandra.persistence.cassandra.ClusterInformation">
<property name="keySpace" value="campus" />
<property name="hosts">
<list>
<value>localhost</value>
</list>
</property>
</bean>
<bean id="cassandraFactory" class="org.easycassandra.persistence.cassandra.spring.CassandraFactoryAnnotation">
<constructor-arg name="clusterInformation" ref="clusterInformation" />
<property name="annotatedClasses">
<list>
<value>org.easycassandra.persistence.cassandra.spring.entity.Contact</value>
<value>org.easycassandra.bean.model.Step</value>
<value>org.easycassandra.bean.model.Weight</value>
</list>
</property>
</bean>
<bean id="cassandraTemplate" class="org.easycassandra.persistence.cassandra.spring.SimpleCassandraTemplateImpl" >
<constructor-arg name="factory" ref="cassandraFactory" />
</bean>
</beans>
A melhoria mais marcante nessa versão são os recursos dos QueryBuilders, que são maneiras muito mais fácil de fazer interações com o Cassandra com configurações adversas de uma maneira mais simples. Com esses recursos, é possível definir o nível de consistência, definir o timeStamp e quais campos serão manipulados.
Nota: Para quem tem dúvidas e problemas com o timestamp, não podem deixar de dar uma olhada nesse tópico que mostra como subtrair hora do timestamp.
Veja na Listagem 3 como inserir valores a partir da chave.
Listagem 3. Simples exemplo inserindo valores a partir da chave
SimpleID id = new SimpleID();
id.setIndex(ONE_HUNDRED_THIRTY);
id.setKey(ONE_HUNDRED_THIRTY);
UpdateBuilder<SimpleQueryBuilder> update = template.updateBuilder(SimpleQueryBuilder.class, key);
update.put("map", "name", "otavioMap").value("value", TEN_DOUBLE).execute();
Na Listagem 4 vemos toda a query de atualização.
Listagem 4. Query de atualização
UpdateBuilder<SimpleQueryBuilder> update = persistence.updateBuilder(SimpleQueryBuilder.class);
update.whereEq(Constant.KEY, Constant.ONE).whereEq(Constant.INDEX, Constant.ONE).addList("list", "otavioList").execute();
Na Listagem 5 temos o código de criação da atualização assíncrona.
Listagem 5. Executando uma atualização assincronamente
UpdateBuilder<SimpleQueryBuilder> update = persistence.updateBuilder(SimpleQueryBuilder.class);
update.whereEq(Constant.KEY, Constant.ONE).whereEq(Constant.INDEX, Constant.ONE).value("value", 12D).executeAsync(new ResultAsyncCallBack<Boolean>() {
@Override
public void result(Boolean bean) {
// do some action
}
});
Nas Listagens 6 e 7 veremos a codificação do processo de inserção do nosso exemplo.
Listagem 6. Realizando inserção
InsertBuilder<SimpleQueryBuilder> insert= persistence.updateBuilder(SimpleQueryBuilder.class);
Set<String> set = new HashSet<>();
set.add("Linda");
Map<String, String> 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();
Listagem 7. Realizando inserção de modo assíncrono
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<SimpleQueryBuilder> insert2 = persistence.updateBuilder(simpleBean);
insert2.executeAsync((new ResultAsyncCallBack<Boolean>() {
@Override
public void result(Boolean bean) {
// do some action
}
});
Na Listagem 8 vemos o código de duas query: a primeira query remove todas as colunas a partir da chave, e a segunda query remove apenas os campos map, list e set.
Listagem 8. Querys de remoção
DeleteBuilder<SimpleBean> delete = persistence.deleteBuilder(SimpleQueryBuilder.class);
delete.whereEq(Constant.INDEX, ONE_HUNDRED_TWO).whereEq(Constant.KEY, ONE_HUNDRED_TWO).execute();
DeleteBuilder<SimpleBean> 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();
Na Listagem 9 vemos o código da remoção assíncrona.
SimpleID id = new SimpleID();
id.setIndex(ONE_HUNDRED_TWO);
id.setKey(ONE_HUNDRED_TWO);
DeleteBuilder<SimpleBean> delete2 = persistence.deleteBuilder(SimpleQueryBuilder.class, id);
delete2.executeAsync((new ResultAsyncCallBack<Boolean>() {
@Override
public void result(Boolean bean) {
// do some action
}
});
Na Listagem 10 realizamos o select em que o campo nome é igual a nome e o índice está em um, dois e três.
Listagem 10. Código select
SelectBuilder<SimpleQueryBuilder> select = persistence.selectBuilder(SimpleQueryBuilder.class);
select.eq("name", "name");
select.in("index", ONE, TWO, THREE);
List<SimpleQueryBuilder> result = select.execute();
Na Listagem 11 temos o código da execução da query assincronamente, em que o índice seja mais que três e seja ordenado de forma descendente no índice.
Listagem 11. Execução da query
SelectBuilder<SimpleQueryBuilder> select = persistence.selectBuilder(SimpleQueryBuilder.class);
select.eq(NAME, NAME).gt("index", THREE).asc(INDEX).executeAsync(new ResultAsyncCallBack<List<SimpleBean>>() {
@Override
public void result(List<SimpleBean> beans) {
// do some thing
}
});
O Batch é um recurso do Cassandra e permite que se executem alterações no banco (inserção, atualização e remoção) de forma atômica. Dessa forma, pode-se enviar insert, updates e deletes como se fosse apenas uma requisição.
Na Listagem 12 temos o código de execução do processo de inserção, remoção e atualização de forma atômica com o BatchBuilder.
Listagem 12. Alterações no banco com BatchBuilder
DeleteBuilder<SimpleBean> delete = dao.deleteBuilder();
delete.whereEq(Constant.INDEX, Constant.ONE_HUNDRED_TWO)
.whereEq(Constant.KEY, Constant.ONE_HUNDRED_TWO);
InsertBuilder<SimpleBean> 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<SimpleBean> 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<Boolean>() {
@Override
public void result(Boolean bean) {
// do some action
}
});
Vale lembrar que recurso do Batch deve ser usado em casos específicos, já que distribuir as requisições entre os nós, no Cassandra, sempre será uma boa prática.
Referências
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Vídeo