欢迎投稿

今日深度:

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

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



前些日子刚刚做了一些实验,由于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"); //连结数据库的的 Keyspace1
		
		String cfName="Standard"; //指定column families 的名字 "Standard"
		long timestamp=System.currentTimeMillis(); //时间戳
		byte[] userIDKey="1".getBytes(); // rowkey 相当于 primary key ,写数据的时候需要指定rowkey
		
		
		colPathName.setColumn("name".getBytes(UTF8));  
               // 查询哪个单元列呢? 指定列名, 列名是 byte[] 类型
		
		ColumnParent cp=new ColumnParent(cfName); 
                //把含有column families 的str传入这个类 cp用来插入数据的时候插入那个cf
		
		//Insert the name column
		LOG.info("Inserting row for key "+ new String(userIDKey));
                //要插入一列, 建立一个列对象
		Column nameCol=new Column(); 
		nameCol.setName("name".getBytes(UTF8)); //设置列名
		nameCol.setValue("George Clinton".getBytes());//设置列名对应的值key-value
		nameCol.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 column
		LOG.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类型,需要转换成string
		LOG.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指定) 的所有列 (指定的切片的列) 然后遍历这些columns
		for (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能得到名字和值


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

www.htsjk.Com true http://www.htsjk.com/cassandra/28869.html NewsArticle Cassandra 使用Thrift API 操作数据简例--读写单行单列数据,cassandrathrift 前些日子刚刚做了一些实验,由于API更改也是很迅速的,很多方法忽然的被淘汰,甚至参数类型都有变化,所以记录下 c...
相关文章
    暂无相关文章
评论暂时关闭