FirebrandはJavaオブジェクトからCassandraへの接続の保持やクエリーの発行を行うためのシンプルなCassandraクライアントライブラリです。
■インストール
事前に用意しておくもの
- JDK6
- Maven2 (jarをダウンロードしてくる場合はいらない)
- git (jarをダウンロードしてくる場合はいらない)
jarをダウンロードして使う
ちょっと試すだけならFirebrandが依存しているパッケージもついてくるバージョンが便利です。
CassandraおよびHectorのパッケージがすでにクラスパスに含まれていれば、Firebrandだけで結構です。
wget https://github.com/downloads/47deg/firebrand/firebrand-1.0-SNAPSHOT-jar-with-dependencies.jar or wget https://github.com/downloads/47deg/firebrand/firebrand-1.0-SNAPSHOT.jar
Mavenを使ってビルドする
ソースファイルをもってくる
git clone https://github.com/47deg/firebrand.git cd firebrand
ビルドする
mvn clean install or mvn package
■CRUDしてみる
1. Cassandra側でKeyspaceを用意しておく。
create keyspace TestKS with placement_strategy = 'SimpleStrategy' and strategy_options = {replication_factor:2} create column family TestCF with column_type = 'Standard' and comparator = 'UTF8Type' and default_validation_class = 'UTF8Type' and key_validation_class = 'UTF8Type'
2. エンティティクラスを用意する
TestCF.java
import org.firebrandocm.dao.annotations.*; @ColumnFamily(consistencyLevel = ConsistencyLevel.ALL) @NamedQueries({ @NamedQuery(name = TestCF.QUERY_ALL_TESTCFS, query = "select * from TestCF"), @NamedQuery(name = TestCF.QUERY_ALL_TESTCFS_WITH_NAME, query = "select * from TestCF where name = :name") }) public class TestCF { private String firstProperty; private String nullProperty; public static final String QUERY_ALL_TESTCFS = "TestCF.QUERY_ALL_TESTCFS"; public static final String QUERY_ALL_TESTCFS_WITH_NAME = "TestCF.QUERY_ALL_TESTCFS_WITH_NAME"; @Key private String key; @Column(indexed = true) private String name; @Column(indexed = true) private String description; public String getName() { return name; } public String getDescription() { return description; } public void setName(String data) { name = data; } public void setDescription(String data) { description = data; } public String getKey() { return key; } public void setKey(String data) { key = data; } }
TestCF2.java
import org.firebrandocm.dao.annotations.*; @ColumnFamily(consistencyLevel = ConsistencyLevel.ALL) @NamedQueries({ @NamedQuery(name = TestCF2.QUERY_ALL_TESTCF2S, query = "select * from TestCF2"), @NamedQuery(name = TestCF2.QUERY_ALL_TESTCF2S_WITH_NAME, query = "select * from TestCF2 where name = :name") }) public class TestCF2 { public static final String QUERY_ALL_TESTCF2S = "TestCF2.QUERY_ALL_TESTCF2S"; public static final String QUERY_ALL_TESTCF2S_WITH_NAME = "TestCF2.QUERY_ALL_TESTCF2S_WITH_NAME"; @Key private String key; @Column(indexed = true) private String name; @Column(indexed = true) private String description; public String getName() { return name; } public String getDescription() { return description; } public void setName(String data) { name = data; } public void setDescription(String data) { description = data; } public String getKey() { return key; } public void setKey(String data) { key = data; } }
3. CRUDしてみる
Test.java
import org.firebrandocm.dao.*; import org.firebrandocm.dao.impl.hector.HectorPersistenceFactory; import static org.firebrandocm.dao.cql.QueryBuilder.*; import java.util.*; import org.apache.cassandra.thrift.ConsistencyLevel; import org.firebrandocm.dao.cql.clauses.ConsistencyType; class FBTest { public static void main(String args[]) { // 使用するカラムファミリーのエンティティクラス List<Class<?>> classList = Arrays.asList(TestCF.class, TestCF2.class); // Cassandraノード String[] nodes = {"192.168.1.122"}; try { // HectorのFactoryのやり方で接続設定する PersistenceFactory persistenceFactory = new HectorPersistenceFactory.Builder() .defaultConsistencyLevel(ConsistencyLevel.ONE) .clusterName("Test Cluster") .defaultKeySpace("TestKS") .contactNodes(nodes) .thriftPort(9160) .entities(classList) .build(); /* build()した時に、先ほど指定したエンティティクラスに対応するカラムファミリーに接続される or 無ければ勝手にcreate column familyされる。今回はTestCF2というカラムファミリーはあらかじめ作成して置かなかったため、ここでCassandra側にTestCF2が作られる。 */ /***************************/ /* create, update */ /***************************/ // insertColumns persistenceFactory.insertColumns("TestCF", "000001", new HashMap<String, Object>(){{ put("name", "Keith"); put("description", "This is Keith's data."); }}); TestCF setter1 = persistenceFactory.get(TestCF.class, "000001"); System.out.println(setter1.getDescription()); // This is Keith's data. // getResultList CQLベタ書き persistenceFactory.getResultList(TestCF.class, Query.get("INSERT INTO TestCF (KEY, 'name', 'description') VALUES ('000002', 'Thom', 'This is the data of Thom.') USING CONSISTENCY ONE AND TTL 86400;")); TestCF setter2 = persistenceFactory.get(TestCF.class, "000002"); System.out.println(setter2.getDescription()); // This is the data of Thom. // getResultList Query Builder persistenceFactory.getResultList(TestCF.class, Query.get( insert( columnFamily("TestCF"), into("KEY", "name", "description"), values("000003", "Stevie", "This is the Stevie data."), writeOptions( consistency(ConsistencyType.ONE), ttl(86400) ) ) )); TestCF setter3 = persistenceFactory.get(TestCF.class, "000003"); System.out.println(setter3.getDescription()); // This is the Stevie data. /**************************/ /* read */ /**************************/ /**** rowkey指定 ****/ TestCF getter1 = persistenceFactory.get(TestCF.class, "000001"); System.out.println(getter1.getKey()); // 000001 /**** 全部取得 ****/ // getResultList CQLベタ書き List<TestCF> getter2 = persistenceFactory.getResultList(TestCF.class, Query.get("select * from TestCF")); System.out.println(getter2.get(0).getKey()); // 000001 // getResultList Query Builder List<TestCF> getter3 = persistenceFactory.getResultList(TestCF.class, Query.get(select(allColumns(), from(TestCF.class)))); System.out.println(getter3.get(0).getKey()); // 000001 // getResultList TestCF内でCQLを定義し使用 List<TestCF> getter4 = persistenceFactory.getResultList(TestCF.class, Query.get(TestCF.QUERY_ALL_TESTCFS)); System.out.println(getter4.get(0).getKey()); // 000001 /**** カラム指定 Secondary Index 指定有りのときのみ可 ****/ // getResultList CQLベタ書き List<TestCF> getter5 = persistenceFactory.getResultList(TestCF.class, Query.get("select * from TestCF where name = 'Keith'")); System.out.println(getter5.get(0).getName()); // Keith // getResultList Query Builder List<TestCF> getter6 = persistenceFactory.getResultList(TestCF.class, Query.get(select(allColumns(), from(TestCF.class), where(eq("name", "Keith"))))); System.out.println(getter6.get(0).getName()); // Keith // getResultList TestCF内でCQLを定義し使用 List<TestCF> getter7 = persistenceFactory.getResultList(TestCF.class, Query.get(TestCF.QUERY_ALL_TESTCFS_WITH_NAME, new HashMap<String, Object>(){{ put("name", "Keith"); }})); System.out.println(getter7.get(0).getName()); // Keith /**************************/ /* delete */ /**************************/ TestCF del = persistenceFactory.get(TestCF.class, "000001"); persistenceFactory.remove(del); // persistenceFactory.remove(del, del2, del3...); も可 System.out.println(del); // [] } catch(Exception e) { System.out.println(e); } } }