如何使用同步和异步方法烹饪DataStax访问器?

时间:2016-03-03 09:41:58

标签: java cassandra datastax

当我为实体编写accessor时,我通常会添加同一查询的同步和异步版本。例如:

@Accessor
public interface SourceDataAccessor {
      @Query("select * from source_data where data_id = ?")
      Result<SourceDataCass> get(UUID dataId);

      @Query("select * from source_data where data_id = ?")
      ListenableFuture<Result<SourceDataCass>> getAsync(UUID dataId);
}

但是当访问者被实例化时,警告会出现在日志中:

12:32:49,793  WARN com.datastax.driver.core.Cluster:2109 - Re-preparing already prepared query select * from source_data where data_id = ?. 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.

可能有一种方法可以同时拥有相同查询的同步版本和异步版本,但是没有重新准备吗?

2 个答案:

答案 0 :(得分:2)

这是一个有趣的用例。

目前我们不支持它,因此解决方法是仅使用异步方法编写访问者,然后使用getAsync().getUninterruptibly()作为同步版本(&#39; s&#39&#39 ; s内部完成)。我同意它不是非常用户友好,您可以使用包装类来完成它,但这仍然是一个额外的步骤。

我们可以很容易地做的一件事是在处理方法时缓存预准备语句,因此至少在同一个接口中重复查询时不会准备两次。

如果您有兴趣在驱动程序中看到此信息,请打开JIRA ticket。如果你想自己修复它,你也可以创建一个拉取请求(从快速看,唯一的改变方法是AccessorMapper#prepare)。

答案 1 :(得分:0)

您可以更改访问者以返回Statement

@Accessor
public interface SourceDataAccessor {
  @Query("select * from source_data where data_id = ?")
  Statement get(UUID dataId);
}

然后使用

执行Statement
ResultSet rs = session.execute(statement);

ResultSetFuture rsf = session.executeAsync(statement);

为了将ResultSet映射到您的类,您可以使用Mapper

MappingManager mappingManager = new MappingManager(session);
Mapper mapper = mappingManager.mapper(SourceDataCass.class);
Result<SourceDataClass> sourceDataClass = mapper.map(rs);