gpt4 book ai didi

cassandra - Spring 数据 Cassandra 2.0 Select BLOB 列返回不正确的 ByteBuffer 数据

转载 作者:行者123 更新时间:2023-12-04 14:00:17 25 4
gpt4 key购买 nike

上下文:Spring 数据 cassandra 官方 1.0.2.RELEASE 来自 Maven Central repo、CQL3、cassandra 2.0、datastax 驱动程序 2.0.4
背景:cassandra blob 数据类型映射到 Java ByteBuffer。
下面的示例代码表明您不会使用等效插入旁边的 select 来检索正确的字节。实际检索的数据以大量垃圾字节为前缀,实际上看起来像是整行的序列化。
这个与 Cassandra 1.2 相关的 older post 建议我们可能必须从长度为 ByteBuffer.remaining() 的 ByteBuffer.arrayOffset() 开始,但 arrayOffset 值实际上是 0。
我发现了一个 spring-data-cassandra 2.0.0。 SNAPSHOT 但 CassandraOperations API 有很大不同,它的包名也是:org.springdata... 与 org.springframework...
非常欢迎帮助解决此问题。
同时,看起来我必须将 Base64 二进制数据编码/解码到文本数据类型列/从文本数据类型列解码。
--- 这是我使用的简单表 CQL 元数据 -------------

CREATE TABLE person (
id text,
age int,
name text,
pict blob,
PRIMARY KEY (id)
) ;
--- 遵循映射到 CQL 表的简单数据对象 ---
package org.spring.cassandra.example; 

import java.nio.ByteBuffer;
import org.springframework.data.cassandra.mapping.PrimaryKey;
import org.springframework.data.cassandra.mapping.Table;

@Table
public class Person {

@PrimaryKey
private String id;

private int age;
private String name;
private ByteBuffer pict;

public Person(String id, int age, String name, ByteBuffer pict) {
this.id = id; this.name = name; this.age = age; this.pict = pict;
}

public String getId() { return id; }
public String getName() { return name; }
public int getAge() { return age; }
public ByteBuffer getPict() { return pict; }

}

}
--- 以及简单地插入和检索 person 对象的纯 Java 应用程序代码 --
package org.spring.cassandra.example;

import java.nio.ByteBuffer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.cassandra.core.CassandraOperations;

import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.datastax.driver.core.querybuilder.Select;

public class CassandraApp {

private static final Logger logger = LoggerFactory
.getLogger(CassandraApp.class);

public static String hexDump(ByteBuffer bb) {
char[] hexArray = "0123456789ABCDEF".toCharArray();
bb.rewind();
char[] hexChars = new char[bb.limit() * 2];
for ( int j = 0; j < bb.limit(); j++ ) {
int v = bb.get() & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
bb.rewind();
return new String(hexChars);
}

public static void main(String[] args) {

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app-context.xml");

try {

CassandraOperations cassandraOps = applicationContext.getBean(
"cassandraTemplate", CassandraOperations.class);

cassandraOps.truncate("person");
// prepare data
byte[] ba = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x22, 0x33, 0x44, 0x55, (byte) 0xAA, (byte) 0xCC, (byte) 0xFF };
ByteBuffer myPict = ByteBuffer.wrap(ba);
String myId = "1234567890";
String myName = "mickey";
int myAge = 50;

logger.info("We try id=" + myId + ", name=" + myName + ", age=" + myAge +", pict=" + hexDump(myPict));

cassandraOps.insert(new Person(myId, myAge, myName, myPict ));

Select s = QueryBuilder.select("id","name","age","pict").from("person");
s.where(QueryBuilder.eq("id", myId));

ResultSet rs = cassandraOps.query(s);
Row r = rs.one();

logger.info("We got id=" + r.getString(0) + ", name=" + r.getString(1) + ", age=" + r.getInt(2) +", pict=" + hexDump(r.getBytes(3)));

} catch (Exception e) {
e.printStackTrace();
}

}
}
--- 假设你已经为 cassandra 配置了一个简单的 Spring 项目
http://projects.spring.io/spring-data-cassandra/ 所述
实际执行产生:
[main] INFO org.spring.cassandra.example.CassandraApp - 我们尝试 id=1234567890, name=mickey, age=50, pict= 0001020304051122334455AACCFF5 _0x9204
[主] INFO org.spring.cassandra.example.CassandraApp - 我们得到了ID = 1234567890,名称=米奇,年龄= 50,PICT = 8200000800000073000000020000000100000004000A6D796B657973706163650006706572736F6E00026964000D00046E616D65000D000361676500090004706963740003000000010000000A31323334353637383930000000066D69636B657900000004000000320000000E 0001020304051122334455AACCFF
虽然插入在数据库本身中看起来是正确的,如从 cqlsh 命令行看到的:
cqlsh:mykeyspace> select * from person;

id | age | name | pict
------------+-----+--------+--------------------------------
1234567890 | 50 | mickey | 0x0001020304051122334455aaccff

(1 rows)

最佳答案

我遇到了完全相同的问题,但幸运的是找到了解决方案。
问题是 ByteBuffer 的使用令人困惑。尝试执行以下操作:

ByteBuffer bb = resultSet.one().getBytes("column_name");
byte[] data = new byte[bb.remaining()];
bb.get(data);

感谢 Sylvain 在此提出的建议: http://grokbase.com/t/cassandra/user/134brvqzd3/blobs-in-cql

关于cassandra - Spring 数据 Cassandra 2.0 Select BLOB 列返回不正确的 ByteBuffer 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25359928/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com