我目前正在使用官方数据驱动程序驱动程序(V2.0)编写一个非常基本的CQL访问层,并在将参数值传递给语句时苦苦挣扎。
这是一个例子
列系列(简化)
USE myKeyspace;
CREATE TABLE MyTable (
myId timeuuid,
myTypeId int,
myVal varchar,
PRIMARY_KEY( myId, myTypeId )
);
CREATE INDEX MyTable_myTypeID
ON MyTable( myTypeId );
基本思想是存储一些具有多个值的事件数据(每个"事件"),这就是我使用组合PK的原因。每个事件都有基于时间的UUID,每个typeId可能有多个条目。 从建模的角度来看,这是否有意义?
我现在要做的只是获取一个选择' typeIds'的事件的条目。
public void myQueryCode() {
Cluster.Builder builder = Cluster.builder();
builder.withPort( 9142 );
builder.addContactPoints( "127.0.0.1" );
cluster = builder.build();
Session session = cluster.connect( "myKeyspace" );
List<Integer> typeFilter = new ArrayList<> ();
typeFilter.add( 1 );
typeFilter.add( 2 );
Statement stmt = new SimpleStatement(
"SELECT * FROM MyTable where myId = ?" +
" AND myTypeId IN (?,?)" +
" ALLOW FILTERING",
UUID.randomUUID(),
typeFilter );
ResultSet result = session.execute( stmt );
// do something with results
}
但是,我只是在声明的值序列化中深入了解异常。
com.datastax.driver.core.exceptions.InvalidQueryException: Expected 4 or 0 byte int (8)
at com.datastax.driver.core.exceptions.InvalidQueryException.copy(InvalidQueryException.java:35)
at com.datastax.driver.core.DefaultResultSetFuture.extractCauseFromExecutionException(DefaultResultSetFuture.java:256)
at com.datastax.driver.core.DefaultResultSetFuture.getUninterruptibly(DefaultResultSetFuture.java:172)
at com.datastax.driver.core.AbstractSession.execute(AbstractSession.java:52)
我不确定将列表作为第二个参数传递,驱动程序是否正在获取参数,但是这可能仅适用于集合类型列上的插入?
答案 0 :(得分:2)
您正在传递的List被强制插入第二个参数,这是正确的,这会导致InvalidQueryException。
Statement stmt = new SimpleStatement(
"SELECT * FROM MyTable where myId = ?#1" +
" AND myTypeId IN (?#2,?#3)" +
" ALLOW FILTERING",
#1 UUID.randomUUID(),
#2 typeFilter );
由于typeFilter是一个列表,因此驱动程序会尝试将List Collection对象放入参数2中,并且事情变得很糟糕。这是因为当您运行此类语句(未准备好)时,驱动程序无法检查类型Comment in code。相反,如果您传入
Statement stmt = new SimpleStatement(
"SELECT * FROM MyTable where myId = ?#1" +
" AND myTypeId IN (?#2,?#3)" +
" ALLOW FILTERING",
#1 UUID.randomUUID(),
#2 typeFilter.get(0)
#3 typeFilter.get(1));
你会没事的。或者,如果您已经准备好了语句,那么您将收到编译时错误警告。
答案 1 :(得分:1)
在回答您的第一个问题时,从建模的角度来看,存储“一些具有多个值的事件数据(每个”事件“)是否有意义,这就是我使用组合PK的原因。每个事件都有其时间 - 基于UUID,每个typeId可能有多个条目,“是绝对的。这与Cassandra团队在音乐服务的数据建模示例中使用的场景类似:http://www.datastax.com/documentation/cql/3.1/cql/ddl/ddl_music_service_c.html。
在代码中查找一个小错误,因为我可以在命令行上执行您的示例:
CREATE TABLE MyTable ( myId timeuuid, myTypeId int, myVal varchar, PRIMARY_KEY( myId, myTypeId ) ); CREATE INDEX MyTable_myTypeID ON MyTable( myTypeId ); insert into mytable( myid, mytypeid, myval) VALUES (d2177dd0-eaa2-11de-a572-001b779c76e3, 100, 'somechar') insert into mytable( myid, mytypeid, myval) VALUES (d2177dd0-eaa2-11de-a572-001b779c76e3, 200, 'anotherchar') SELECT * FROM MyTable where myId = d2177dd0-eaa2-11de-a572-001b779c76e3 AND myTypeId IN (100,200) ALLOW FILTERING;
输出是:
myid | mytypeid | myval --------------------------------------+----------+------------- d2177dd0-eaa2-11de-a572-001b779c76e3 | 100 | somechar d2177dd0-eaa2-11de-a572-001b779c76e3 | 200 | anotherchar