cassandra-java将Map集合绑定到准备好的语句

r1wp621o  于 2022-09-27  发布在  Cassandra
关注(0)|答案(2)|浏览(163)

我正在使用datastax的Cassandra Java驱动程序。My Cassandra仅支持CQL 2。
我有一个准备好的INSERT语句,需要接受Map列表。
这是我的模式:

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);

我的问题是:如何绑定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 (?, ?)
c6ubokkw

c6ubokkw1#

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);

1.创建Map类和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);
}

1.创建准备好的语句,例如:

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=?;");

1.绑定参数:

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));

1.将具有my_key值的记录插入表中(可以直接在cql中执行此操作)。
1.运行代码,现在我们可以通过使用UDT更新表来向集合添加/删除元素。

gkn4icbw

gkn4icbw2#

我有解决方案。
似乎这个问题是错的。我需要添加一个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);

相关问题