[英]cassandra-driver-core: pass list values to parameterized SimpleStatement
我目前正在使用官方的Datastax驅動程序(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)
我不確定將列表作為第二個參數傳遞時,驅動程序是否采用了該參數,但是也許僅適用於集合類型列上的插入?
您是正確的,您要傳遞的列表被強制放入第二個參數,這會導致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中,事情變得一團糟。 這是因為當您運行這樣的語句(沒有准備)時,驅動程序將無法檢查類型,即代碼注釋 。 相反,如果您通過了
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));
你會沒事的。 否則,如果您首先准備了該語句,則會被警告編譯時錯誤。
為回答您的第一個問題,從建模的角度來看,存儲“具有多個值的事件數據(每個“事件”)是否有意義,這就是為什么我要使用組合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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.