在使用 Datastax Cassandra 驱动程序时重用 PreparedStatement?

2022-09-03 18:37:41

我目前正在使用 Datastax Cassandra 驱动程序 Cassandra 2 来执行 cql3。这工作正常。我开始使用:PreparedStatement's

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

我应该在构造函数/init方法中创建所有我的所有内容,而不是简单地使用它们吗?PreparedStatement

但是,当多个线程同时使用相同的线程(特别是调用绑定对象)时,这是否顺利?PreparedStatementPreparedStatement.bind()


答案 1

您只需初始化一次预准备状态,并在应用运行时缓存它。只要 Cassandra 集群启动,它就应该可供使用。

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

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


答案 2

我们正在与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 时,都会重用预准备的语句。


推荐