准备好的语句可以开箱即用吗?
Can prepared statements be enabled out of the box?
我想在我的应用程序中执行 CQL
时使用准备好的语句。此功能看起来是由 ReactiveCqlTemplate
class 提供的,我已在此处的 Cassandra 配置中将其传递到 ReactiveCassandraTemplate
:
@Configuration
@EnableReactiveCassandraRepositories(
basePackages = "com.my.app",
includeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {ScyllaPersonRepository.class})
})
public class CassandraConfiguration extends AbstractReactiveCassandraConfiguration {
@Value("${cassandra.host}")
private String cassandraHost;
@Value("${cassandra.connections}")
private Integer cassandraConnections;
@Override
public CassandraClusterFactoryBean cluster() {
PoolingOptions poolingOptions = new PoolingOptions()
.setCoreConnectionsPerHost(HostDistance.LOCAL, cassandraConnections)
.setMaxConnectionsPerHost(HostDistance.LOCAL, cassandraConnections*2);
CassandraClusterFactoryBean bean = super.cluster();
bean.setJmxReportingEnabled(false);
bean.setPoolingOptions(poolingOptions);
bean.setLoadBalancingPolicy(new TokenAwarePolicy(new RoundRobinPolicy()));
return bean;
}
@Override
public ReactiveCassandraTemplate reactiveCassandraTemplate() {
return new ReactiveCassandraTemplate(reactiveCqlTemplate(), cassandraConverter());
}
@Bean
public CassandraEntityInformation getCassandraEntityInformation(CassandraOperations cassandraTemplate) {
CassandraPersistentEntity<Person> entity =
(CassandraPersistentEntity<Person>)
cassandraTemplate
.getConverter()
.getMappingContext()
.getRequiredPersistentEntity(Person.class);
return new MappingCassandraEntityInformation<>(entity, cassandraTemplate.getConverter());
}
@Override
public SchemaAction getSchemaAction() {
return SchemaAction.CREATE_IF_NOT_EXISTS;
}
public String getContactPoints() {
return cassandraHost;
}
public String getKeyspaceName() {
return "mykeyspace";
}
}
这是我的 Cassandra 配置过滤器中引用的 ScyllaPersonRepository
。
public interface ScyllaPersonRepository extends ReactiveCassandraRepository<Person, PersonKey> {
@Query("select id, name from persons where id = ?0")
Flux<Object> findPersonById(@Param("id") String id);
}
执行一些查询后,我的 Scylla Monitoring Dashboard 中的 CQL 非准备语句指标显示我根本没有使用准备语句。
在遵循文档 here 之后,我能够使用准备好的语句,该文档引导我自己创建 CQL
。
public class ScyllaPersonRepository extends SimpleReactiveCassandraRepository<Person, PersonKey> {
private final Session session;
private final CassandraEntityInformation<Person, PersonKey> entityInformation;
private final ReactiveCassandraTemplate cassandraTemplate;
private final PreparedStatementCache cache = PreparedStatementCache.create();
public ScyllaPersonRepository(
Session session,
CassandraEntityInformation<Person, PersonKey> entityInformation,
ReactiveCassandraTemplate cassandraTemplate
) {
super(entityInformation, cassandraTemplate);
this.session = session;
this.entityInformation = entityInformation;
this.cassandraTemplate = cassandraTemplate;
}
public Flux<ScyllaUser> findSegmentsById(String id) {
return cassandraTemplate
.getReactiveCqlOperations()
.query(
findPersonByIdQuery(id),
(row, rowNum) -> convert(row)
);
}
private BoundStatement findPersonByIdQuery(String id) {
return CachedPreparedStatementCreator.of(
cache,
QueryBuilder.select()
.column("id")
.column("name")
.from("persons")
.where(QueryBuilder.eq("id", QueryBuilder.bindMarker("id"))))
.createPreparedStatement(session)
.bind()
.setString("id", id);
}
private Person convert(Row row) {
return new Person(
row.getString("id"),
row.getString("name"));
}
}
但是,我真的希望 ORM 能为我处理所有这些。是否可以开箱即用地配置此行为,这样我就不需要自己手动编写 CQL
,而是只需在我的 Cassandra 配置中将其作为一个选项启用,然后让 ORM 在后面进行编排场景?
坦率地说,我认为这是一个错误(请求增强),应该在 Springs Jira 中提交。
似乎存储库根本不支持开箱即用(我也没有找到任何配置选项如何翻转它,但我可能错过了)。
其实我的理论是正确的:
https://jira.spring.io/projects/DATACASS/issues/DATACASS-578?filter=allopenissues
所以只需添加您自己并尝试向他们寻求解决方案。
我想在我的应用程序中执行 CQL
时使用准备好的语句。此功能看起来是由 ReactiveCqlTemplate
class 提供的,我已在此处的 Cassandra 配置中将其传递到 ReactiveCassandraTemplate
:
@Configuration
@EnableReactiveCassandraRepositories(
basePackages = "com.my.app",
includeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {ScyllaPersonRepository.class})
})
public class CassandraConfiguration extends AbstractReactiveCassandraConfiguration {
@Value("${cassandra.host}")
private String cassandraHost;
@Value("${cassandra.connections}")
private Integer cassandraConnections;
@Override
public CassandraClusterFactoryBean cluster() {
PoolingOptions poolingOptions = new PoolingOptions()
.setCoreConnectionsPerHost(HostDistance.LOCAL, cassandraConnections)
.setMaxConnectionsPerHost(HostDistance.LOCAL, cassandraConnections*2);
CassandraClusterFactoryBean bean = super.cluster();
bean.setJmxReportingEnabled(false);
bean.setPoolingOptions(poolingOptions);
bean.setLoadBalancingPolicy(new TokenAwarePolicy(new RoundRobinPolicy()));
return bean;
}
@Override
public ReactiveCassandraTemplate reactiveCassandraTemplate() {
return new ReactiveCassandraTemplate(reactiveCqlTemplate(), cassandraConverter());
}
@Bean
public CassandraEntityInformation getCassandraEntityInformation(CassandraOperations cassandraTemplate) {
CassandraPersistentEntity<Person> entity =
(CassandraPersistentEntity<Person>)
cassandraTemplate
.getConverter()
.getMappingContext()
.getRequiredPersistentEntity(Person.class);
return new MappingCassandraEntityInformation<>(entity, cassandraTemplate.getConverter());
}
@Override
public SchemaAction getSchemaAction() {
return SchemaAction.CREATE_IF_NOT_EXISTS;
}
public String getContactPoints() {
return cassandraHost;
}
public String getKeyspaceName() {
return "mykeyspace";
}
}
这是我的 Cassandra 配置过滤器中引用的 ScyllaPersonRepository
。
public interface ScyllaPersonRepository extends ReactiveCassandraRepository<Person, PersonKey> {
@Query("select id, name from persons where id = ?0")
Flux<Object> findPersonById(@Param("id") String id);
}
执行一些查询后,我的 Scylla Monitoring Dashboard 中的 CQL 非准备语句指标显示我根本没有使用准备语句。
在遵循文档 here 之后,我能够使用准备好的语句,该文档引导我自己创建 CQL
。
public class ScyllaPersonRepository extends SimpleReactiveCassandraRepository<Person, PersonKey> {
private final Session session;
private final CassandraEntityInformation<Person, PersonKey> entityInformation;
private final ReactiveCassandraTemplate cassandraTemplate;
private final PreparedStatementCache cache = PreparedStatementCache.create();
public ScyllaPersonRepository(
Session session,
CassandraEntityInformation<Person, PersonKey> entityInformation,
ReactiveCassandraTemplate cassandraTemplate
) {
super(entityInformation, cassandraTemplate);
this.session = session;
this.entityInformation = entityInformation;
this.cassandraTemplate = cassandraTemplate;
}
public Flux<ScyllaUser> findSegmentsById(String id) {
return cassandraTemplate
.getReactiveCqlOperations()
.query(
findPersonByIdQuery(id),
(row, rowNum) -> convert(row)
);
}
private BoundStatement findPersonByIdQuery(String id) {
return CachedPreparedStatementCreator.of(
cache,
QueryBuilder.select()
.column("id")
.column("name")
.from("persons")
.where(QueryBuilder.eq("id", QueryBuilder.bindMarker("id"))))
.createPreparedStatement(session)
.bind()
.setString("id", id);
}
private Person convert(Row row) {
return new Person(
row.getString("id"),
row.getString("name"));
}
}
但是,我真的希望 ORM 能为我处理所有这些。是否可以开箱即用地配置此行为,这样我就不需要自己手动编写 CQL
,而是只需在我的 Cassandra 配置中将其作为一个选项启用,然后让 ORM 在后面进行编排场景?
坦率地说,我认为这是一个错误(请求增强),应该在 Springs Jira 中提交。 似乎存储库根本不支持开箱即用(我也没有找到任何配置选项如何翻转它,但我可能错过了)。
其实我的理论是正确的: https://jira.spring.io/projects/DATACASS/issues/DATACASS-578?filter=allopenissues 所以只需添加您自己并尝试向他们寻求解决方案。