簡體   English   中英

cassandra-driver-core:將列表值傳遞給參數化的SimpleStatement

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM