首页 文章

cassandra java将一组映射绑定到一个预处理语句

提问于
浏览
-1

我正在使用datastax'Cassandra Java驱动程序 . 我的Cassandra仅支持CQL 2 .

我有一个准备好的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);

My question is :如何绑定 Map 列表?如何创建下一个查询?

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 (?, ?)

2 回答

  • -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);
    
    • 创建映射类和bean
    @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);
    }
    
    • 创建预准备语句,例如:addUpdateStatement = cassandraClient.getSession() . prepare(“UPDATE my_table_with_set_of_udt SET my_types = my_types?WHERE my_key =?;”); deleteUpdateStatement = cassandraClient.getSession() . prepare(“UPDATE my_table_with_set_of_udt SET my_types = my_types - ?WHERE my_key =?;”);

    • 绑定参数:

    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));
    
    • 使用'my_key'的值将记录插入表中(您可以直接在cql中执行此操作)

    • 运行代码,现在我们可以通过使用UDT更新表来添加/删除元素 .

  • 0

    我有解决方案 .

    似乎这个问题是错误的 . 我需要添加一个UDT列表(用户定义的tap),而不是哈希列表 . 为此,您需要使用UserType和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);
    

相关问题