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:

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

https://github.com/otaviojava/Easy-Cassandra/wiki/Builders

https://github.com/otaviojava/Easy-Cassandra/wiki

Artigos relacionados