2016-11-10 62 views
-1

我正在使用datastax'Cassandra Java驅動程序。我的Cassandra僅支持CQL 2。cassandra java將地圖集合綁定到準備好的語句

我有一個準備好的INSERT語句,需要接受一張地圖列表。

這是我的架構:

CREATE TYPE test.snap_guid (
    l bigint, 
    h bigint 
); 

CREATE TABLE test.t (
    id bigint, 
    snap list<frozen<snap_guid>>, 
    PRIMARY KEY ((id)) 
) 

這是事先準備好的聲明:

PreparedStatement mysttmt = <client>.prepare("INSERT INTO test.t (id, snap) VALUES (?, ?)"); 

我知道,爲了收集綁定到準備好的聲明,我需要創建一個集合,並綁定它。我無法將收集括號放入準備好的查詢中。例如(文字列表):

ArrayList<String> snaps = new ArrayList<>(); 
snaps.add("AEF34GF665"); 
// INSERT INTO test.t (id, snap) VALUES (?, ?) 
BoundStatement bs = mysttmt.bind(12, snaps); 

我的問題是:我怎麼綁定映射列表?我如何創建一個像下一個查詢?

INSERT INTO test.t (id, snap) VALUES (12, [{l:10,h:50}]) 

// I know it is impossible to create the following prepared statement: 
INSERT INTO test.t (id, snap) VALUES (?, [{l:?,h:?}]) 

// The list of maps has to be a single bound variable... how??? 
INSERT INTO test.t (id, snap) VALUES (?, ?) 

回答

-1

我有解決方案。

看來這個問題是錯誤的。我需要添加UDT(用戶定義的tap)列表,而不是哈希列表。對於那些需要使用用戶類型,並UDTValue:

UserType myUDT = <client>.getSession().getCluster(). 
    getMetadata().getKeyspace("test").getUserType("snap_guid"); 
UDTValue mySnap = myUDT.newValue(); 
mySnap.setLong("h", 50); 
mySnap.setLong("l", 10); 

ArrayList<UDTValue> snaps = new ArrayList<>(); 
snaps.add(mySnap); 
// INSERT INTO test.t (id, snap) VALUES (?, ?) 
BoundStatement bs = mysttmt.bind(12, snaps); 
0
  1. 創建表:

    CREATE TYPE my_type (
    user_id text, 
    name text, 
    age bigint 
    ); 
    
    CREATE TABLE my_table_with_set_of_udt (
    my_key text PRIMARY KEY, 
    my_types set<frozen <my_type>> 
    ); 
    
    CREATE INDEX ON my_table_with_set_of_udt(my_types); 
    
  2. 創建映射類和豆類

    @UDT(keyspace = "my_ks", name = "my_type") 
    public class MyType { 
    @Field(name = "user_id") 
    private String userId; 
    
    @Field(name = "name") 
    private String name; 
    
    @Field(name = "age") 
    private int age; 
    
    // getters, setters & constructors 
    // equals & hashCode are required for a set 
    } 
    
    @Table(keyspace = "my_ks", name = "my_table_with_set_of_udt") 
    public class MyTableWithSetOfUDT { 
    
    @PartitionKey 
    @Column(name = "my_key") 
    private String myKey; 
    
    @Column(name = "my_types") 
    @FrozenValue // because of --> set<frozen <my_type>> 
    private Set<MyType> myTypes; 
    
    // getters, setters & constructors 
    // equals & hashCode are required for a set 
    } 
    
    @Bean 
    public Mapper<MyTableWithSetOfUDT> myTableWithSetOfUDTMapper() { 
    return new MappingManager(cassandraClient.getSession()).mapper(MyTableWithSetOfUDT.class); 
    } 
    
    @Bean 
    public UDTMapper<MyType> myTypeMapper() { 
    return new MappingManager(cassandraClient.getSession()).udtMapper(MyType.class); 
    } 
    
  3. 創建預處理語句,例如: addUpdateStatement = cassandraClient.getSession()。prepar e(「更新my_table_with_set_of_udt SET my_types = my_types +? WHERE my_key = ?; 「); deleteUpdateStatement = cassandraClient.getSession()製備(」 UPDATE SET my_table_with_set_of_udt = my_types my_types - WHERE my_key = ?;「);

  4. 綁定參數:

    MyType myType = MyType(userId, name, age); 
    UDTValue value = myTypeMapper.toUDT(myType); 
    cassandraClient.getSession().execute(addUpdateStatement.bind(Sets.newHashSet(value), myKey)); 
    

    cassandraClient.getSession().execute(deleteUpdateStatement.bind(Sets.newHashSet(value), myKey)); 
    
  5. 插入記錄表與「my_key」的值(您可以定製列表直接做到這一點)

  6. 運行代碼,現在我們可以通過使用UDT更新表來添加/刪除元素。