Cassandra 使用Thrift API 操作数据简例--读写单行单列数据

来源:互联网 发布:ios编程呼起app 编辑:程序博客网 时间:2024/06/01 21:45


前些日子刚刚做了一些实验,由于API更改也是很迅速的,很多方法忽然的被淘汰,甚至参数类型都有变化,所以记录下

cassandra 1.2.1 使用Thrift api操作数据的几个例子, 以备自查


cassandra 不同于 RDBMS 查询数据需要了解两个概念 Range 和 Slice

Range 指行范围, Cassandra的行是按照一定的顺序存储在硬盘上的, Range值截取其中的一部分

行的排序在建立column families 的时候用comparator 来指定


Slice 指列切片, 由于列也是按顺序存放的, 所以可以取出某一部分列,在代码中可以指定, 比如a b c d  e 五列, 我取出 a到c 就可以取出a b c列


1, 简单的写操作

要操作cassandra数据库,需要写代码指定IP 端口打开数据库,这里假设有一个client 客户端实例,我们只记录下写数据的代码


Cassandra.Client client=conn.connect("Keyspace1"); //连结数据库的的 Keyspace1String cfName="Standard"; //指定column families 的名字 "Standard"long timestamp=System.currentTimeMillis(); //时间戳byte[] userIDKey="1".getBytes(); // rowkey 相当于 primary key ,写数据的时候需要指定rowkeycolPathName.setColumn("name".getBytes(UTF8));                 // 查询哪个单元列呢? 指定列名, 列名是 byte[] 类型ColumnParent cp=new ColumnParent(cfName);                 //把含有column families 的str传入这个类 cp用来插入数据的时候插入那个cf//Insert the name columnLOG.info("Inserting row for key "+ new String(userIDKey));                //要插入一列, 建立一个列对象Column nameCol=new Column(); nameCol.setName("name".getBytes(UTF8)); //设置列名nameCol.setValue("George Clinton".getBytes());//设置列名对应的值key-valuenameCol.setTimestamp(timestamp);//设置时间戳client.insert(UsefulUtils.toByteBuffer(userIDKey),cp,nameCol,CL);                //插入,需要四个元素,1,Bytebuffer格式的rowkey,(老版本是byte[],我了个小方法把byte转化为ByteBuffer,                //这个例子是书上的,. 2,cp,指定是那个表(column familie),3 nameCol, 指定是那个列, 4,CL 一致性级别                 //CL是我定义的常量 Consistency.ONE)//insert age columnLOG.info("Inserting row for key "+ new String(userIDKey));Column ageCol=new Column();ageCol.setName("age".getBytes(UTF8));ageCol.setValue("69".getBytes(UTF8));ageCol.setTimestamp(timestamp);client.insert(UsefulUtils.toByteBuffer(userIDKey),cp,ageCol,CL);//插入第二列                //这个例子我们总共插入了两列, name="George Clinton" age=69  rowkey=1                  //至此数据已经插入完成 下面是查询LOG.info("Row insert done");                ColumnPath colPathName=new ColumnPath(cfName);  // 这个是用来查询一单元列数据用这个ColumnPath                 //read the name only                 Column col=client.get(UsefulUtils.toByteBuffer(userIDKey), colPathName, CL).getColumn();                //查询的时候需要指定: 1 rowkey 2 Columnpathname 3 一致性级别. 使用client.get得到一个Column对象                 //然后可以用col.name col.value 分别得到名字, 和值 得到的对象是bytebuffer类型,需要转换成stringLOG.info("Column name :"+ UsefulUtils.toString(col.name));LOG.info("Column value :"+ UsefulUtils.toString(col.value));LOG.info("Column timestamp :"+ timestamp);//create a slice predicate representing the columns to read start and finish//用来查询一个区间(多行)SlicePredicate predicate =new SlicePredicate();//定义一个查询切片的 谓词SliceRange sliceRange=new SliceRange();// 定义一个需要查询的列切片 , 这个切片要传入谓词sliceRange.setStart("age".getBytes()); //切片开始sliceRange.setFinish("name".getBytes());//切片结束//这里setStart定义了一个开始区间, setFinish定义一个结束的区间, 这个区间可以想象成一个表列的顺序//比如我们有 age email name sex 是这样的顺序, age -name 就会取出来 a e n散列, sex就被过滤掉了//取出全部列可以把开始结束定义为 "0".getbytes() . 某种意义上是指定select columns from table,但是这个                //columns只能是区间,因为cassandra 的列是有顺序的,这个排序方法是自己在建立表(column families)的时候就定义的.predicate.setSlice_range(sliceRange);//把定义好的一个列切片(from age to name)传入切片谓词 使用setSlice_range()LOG.info("Complete Row:");//read all columns in the row 这里读出所有列,刚才我们定义的切片ColumnParent parent =new ColumnParent(cfName); //有了切片,我们从那个columnfamlie查询这个列, 也要事先定义.List<ColumnOrSuperColumn> results=client.get_slice(UsefulUtils.toByteBuffer(userIDKey), parent, predicate, CL);//使用client,get_slice来得到切片,返回值是一个List<ColumnOrSuperColumn>类型,是普通列或者超列.我们这里是普通咧// 指定四个参数 1 读取哪个rowkey的列切片(where id='1') 2, 从那个列族读 (select from table),3 查询谓词select columns(from na//me to email) 4,一致性级别 ONE, 只要写入一个服务器就算成功,我只有一个节点);//loop over columns,outputting values.//我们得到一个一行(rowkey指定) 的所有列 (指定的切片的列) 然后遍历这些columnsfor (ColumnOrSuperColumn result : results){Column column =result.column;// 定义column, 用resule.column遍历results//挨个输出column的键和值LOG.info(UsefulUtils.toString(column.name) +":" +UsefulUtils.toString(column.value));}conn.close();LOG.info("all DONE");



到这里,我们看到了如何插入一个行, 其实应该是插入属于某个rowkey 的 几列 比如rowkey=1 name='' age='' cassandra的好处在于,你不用实现指定这个行有多少列, 你只管指定一个rowkey=2, 然后列名随便取一个,你也会成功的, 所以说cassandra是无schema的, 第一行的列可以跟第二行完全不同,一行可以有几万个列都不成问题.

然后读取一行数据, 需要指定读取哪一行 rowkey, 然后读取那一列或者几列,

 如果只读取一列,用columnpath,把列族名传入,调用client.get方法,传入四个参数就可以搞定

如果读取一行多列数据,用 columnparent指定表名, 定义Slicerange指定列范围(开始结束), 然后把slicerange传入切片谓词predicate, 然后调用client.get_slice(rowkey,包含表名的parent,谓词,一致性级别) 就能得到包含对应这个rowkey的所有columns. 使用getname getvalue能得到名字和值


如何查询多行数据,查看下一篇