java - 如何在 Cassandra 中使用 datastax java 驱动程序有效地使用准备好的语句?

标签 java cassandra prepared-statement datastax-java-driver

我需要使用 Datastax Java 驱动程序查询 Cassandra 中的一个表。下面是我的代码,工作正常-

public class TestCassandra {

        private Session session = null;
        private Cluster cluster = null;

        private static class ConnectionHolder {
            static final TestCassandra connection = new TestCassandra();
        }

        public static TestCassandra getInstance() {
            return ConnectionHolder.connection;
        }

        private TestCassandra() {
            Builder builder = Cluster.builder();
            builder.addContactPoints("127.0.0.1");

            PoolingOptions opts = new PoolingOptions();
            opts.setCoreConnectionsPerHost(HostDistance.LOCAL, opts.getCoreConnectionsPerHost(HostDistance.LOCAL));

            cluster = builder.withRetryPolicy(DowngradingConsistencyRetryPolicy.INSTANCE).withPoolingOptions(opts)
                    .withLoadBalancingPolicy(new TokenAwarePolicy(new DCAwareRoundRobinPolicy("DC2")))
                    .withReconnectionPolicy(new ConstantReconnectionPolicy(100L))
                    .build();
            session = cluster.connect();
        }

    private Set<String> getRandomUsers() {
        Set<String> userList = new HashSet<String>();

        for (int table = 0; table < 14; table++) {
            String sql = "select * from testkeyspace.test_table_" + table + ";";

            try {
                SimpleStatement query = new SimpleStatement(sql);
                query.setConsistencyLevel(ConsistencyLevel.QUORUM);
                ResultSet res = session.execute(query);

                Iterator<Row> rows = res.iterator();
                while (rows.hasNext()) {
                    Row r = rows.next();

                    String user_id = r.getString("user_id");
                    userList.add(user_id);
                }
            } catch (Exception e) {
                System.out.println("error= " + ExceptionUtils.getStackTrace(e));
            }
        }

        return userList;
    }
}

我在我的主应用程序中使用这样的类 -

TestCassandra.getInstance().getRandomUsers();

有什么方法可以有效地在 getRandomUsers 中使用 PreparedStatement 吗?我想我需要确保只创建一次 PreparedStatement 而不是多次创建它。在我当前的架构中,什么是最好的设计?我该如何使用它?

最佳答案

您可以为所需的语句创建缓存(这是一个相当基本的示例,可以让您了解)。让我们从创建将用作缓存的类开始。

private class StatementCache {
    Map<String, PreparedStatement> statementCache = new HashMap<>();
    public BoundStatement getStatement(String cql) {
        PreparedStatement ps = statementCache.get(cql);
        // no statement cached, create one and cache it now.
        if (ps == null) {
            ps = session.prepare(cql);
            statementCache.put(cql, ps);
        }
        return ps.bind();
    }
}

然后给你的单例添加一个实例:

public class TestCassandra {
    private Session session = null;
    private Cluster cluster = null;
    private StatementCache psCache = new StatementCache();
    // rest of class...

最后使用函数中的缓存:

private Set<String> getRandomUsers(String cql) {
// lots of code.    
        try {
            SimpleStatement query = new SimpleStatement(cql);
            query.setConsistencyLevel(ConsistencyLevel.QUORUM);
            // abstract the handling of the cache to it's own class.
            // this will need some work to make sure it's thread safe
            // as currently it's not.
            ResultSet res = session.execute(psCache.getStatement(cql));

关于java - 如何在 Cassandra 中使用 datastax java 驱动程序有效地使用准备好的语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28776172/

相关文章:

java - ARCore——读取叠加图像(AR场景截图)

java - Android,在Java中用px设置WebView尺寸

java - 在保持精度和准确度的同时划分两个大长整型

php - 无法将内爆数组绑定(bind)到 mysql 准备好的语句中

java - 如何使用 datastax java 驱动程序以通用方式将值绑定(bind)到绑定(bind)语句?

cassandra - 您如何确定特定 KairosDB/OpenTSDB 指标占用了多少磁盘空间?

cassandra - 如何在 Cassandra(特别是 CQLSH)中将字符串或文本作为 blob 插入?

cassandra - 在 Cassandra 中重新创建具有相同名称的表/键空间不好吗?

php - 为什么 mysqli 绑定(bind)函数不能正确处理我的字符串?

java - Java 类中的 MySQL 语法错误?