当前位置: 首页 > 知识库问答 >
问题:

使用Datastax Cassandra驱动程序时是否重新使用PreparedStatement?

米景辉
2023-03-14

我目前正在使用Cassandra 2的Datastax Cassandra驱动程序来执行cql3。这是正确的。我开始使用准备声明的:

Session session = sessionProvider.getSession();
try {
    PreparedStatement ps = session.prepare(cql);
    ResultSet rs = session.execute(ps.bind(objects));
    if (irsr != null) {
       irsr.read(rs);
    }
}

有时我会在日志中收到司机的警告:

Re-preparing already prepared query . Please note that preparing the same query more than once is generally an anti-pattern and will likely affect performance. Consider preparing the statement only once.

这个警告很有道理,但我不确定应该如何重用PreparedStatement

我是否应该在构造函数/初始化方法中创建我所有的准备语句,而不是简单地使用它们?

但是,当多个线程同时使用相同的准备声明时(特别是调用准备tatement.bind()来绑定对象),这种情况会很好吗?

共有3个答案

仉昂熙
2023-03-14

如果密钥空间固定,上述解决方案将起作用。在多租户的情况下,这种解决方案是不够的。我只是按照下面的方式做了,其中keyspace作为参数传递。

检查prepared语句中的keyspace,如果它与传递的参数相同,则不要准备语句,因为在本例中它已经准备好了。

 private BatchStatement eventBatch(List<SomeEvent> events, String keySpace) {

    BatchStatement batch = new BatchStatement();
    String preparedStmtKeySpace = propEventPer == null? "" : propEventPer.getQueryKeyspace();
    if(!keySpace.equals("\"" + preparedStmtKeySpace +  "\"")) {
        eventStmt = cassandraOperations.getSession().prepare(colFamilyInsert(keySpace + "." + "table_name"));

    }
    ....
private RegularStatement colFamilyInsert(String colFamilyName) {
    return insertInto(colFamilyName)
            .value(PERSON_ID, bindMarker())
            .value(DAY, bindMarker());

}
曾实
2023-03-14

我们正在Spring的Web应用程序中使用cassandra。在我们的例子中,我们在安装封装针对cf(我们的存储库)的操作的bean时创建PreparedStatements。

下面是我们正在使用的代码片段:

@Repository
public class StatsRepositoryImpl implements StatsRepository {

@SuppressWarnings("unused")
    @PostConstruct
    private void initStatements(){
        if (cassandraSession == null){
            LOG.error("Cassandra 2.0 not available");
        } else {
            GETSTATS_BY_PROJECT = cassandraSession.prepare(SELECTSTATS+" WHERE projectid = ?");
        }

    }       

@Override
    public Stats findByProject(Project project) {
        Stats stats = null;

        BoundStatement boundStatement = new BoundStatement(GETSTATS_BY_PROJECT);

        ResultSet rs = cassandraSession.execute(boundStatement.bind(project.getId()));
        for (Row row : rs){
            stats = mapRowToStats(row);
        }

        return stats;
    } 

通过这种方式,每次执行findByProject方法时,都会重用准备好的语句。

周泰
2023-03-14

你可以只初始化PreparedStatement一次,并在应用程序运行时缓存它。只要Cassandra集群启动,它就应该可以使用。

使用来自多个线程的语句是可以的(只要不通过setXXX()方法修改它)。调用bind()时,下面的代码只读取PreparedStatement,然后创建BoundStatement()的一个新实例,调用线程可以自由地对其进行修改。

如果你好奇,这里是源代码(搜索bind())。

 类似资料:
  • 问题内容: 我目前正在使用Cassandra 2的Datastax Cassandra驱动程序来执行cql3。这可以正常工作。我开始使用: 有时我会在日志中从驱动程序得到警告: 此警告是有道理的,但我不确定如何重用? 我应该只在构造函数/ init方法中创建所有我的函数,而不是简单地使用它们吗? 但是,当多个线程同时使用同一线程时(尤其是调用绑定对象),这样做是否很好? 问题答案: 您可以只初始化

  • 我试图使用servlet上的Java驱动程序连接到托管在mlab上的MongoDB数据库。 问题是我得到以下错误: 这样做对吗?我还应该做什么/代替吗?

  • 问题内容: 我正在尝试使用servlet上的Java驱动程序连接到mlab上托管的MongoDB数据库。 问题是我遇到以下错误: 我看了一个答案(如何解决ClassNotFoundException:com.mongodb.connection.BufferProvider?),该答案向我强调了我需要其他jar,自从我下载了这些jar之后,仍然出现此错误。 我正在使用Eclipse并将这三个jar

  • TL;DR:同时使用Hive和MySql JDBC有问题吗? 我正在开发一个应用程序,它使用MySql JDBC驱动程序执行多个SQL查询,然后它还使用Hive JDBC发送另一个Hive查询。 现在发生的情况是,MySql查询正常工作,当代码尝试执行配置单元查询时,它会抛出以下异常: 现在,在抛出这个异常之后,查询将正确执行。 我的猜测是,由于我同时加载了MySql和Hive驱动程序,MySql

  • 我有一份spark流媒体工作,我正试图由spark-k8运营商提交。我始终保持重启策略。但是,手动删除驱动程序时,驱动程序不会重新启动。我的yaml: Spark版本:2.4.5 apiVersion:“sparkoperator.k8s.io/v1beta2” 我遵循的步骤: 通过kubectl apply-f示例/spark测试创建资源。亚马尔。Pod创建成功。手动删除驱动程序。 预期行为:将

  • < li >感谢您点击这个问题!我已经尽了最大努力让这件事尽可能彻底。 < li >但是,如果您需要进一步澄清,请随时告诉我! < li >如果您认为问题太长。你可以读第三个 Mongodb Java 驱动程序: org.mongodb:mongo-java-driver:3.11.0-rc0 查找具有特定“名称”字段的特定文档 然后更新其他字段或整个文档 从不返回null。 Java只告诉我它返