【问题标题】:How to cook right a DataStax accessor with sync and async methods?如何使用同步和异步方法正确处理 DataStax 访问器?
【发布时间】:2016-06-16 13:20:38
【问题描述】:

当我为实体编写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.

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

【问题讨论】:

    标签: java cassandra datastax


    【解决方案1】:

    这是一个有趣的用例。

    目前我们不支持它,所以解决方法是只使用 async 方法编写访问器,然后使用getAsync().getUninterruptibly() 作为同步版本(内部就是这样做的)。我同意它不是非常用户友好,您可以使用包装类来执行此操作,但这仍然是一个额外的步骤。

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

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

    【讨论】:

    • 谢谢奥利弗!我希望我能找到时间来创建拉取请求。
    【解决方案2】:

    您可以更改访问器以返回 Statement。

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

    然后使用

    执行语句
    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);
    

    【讨论】:

    • 是的,这是有道理的。谢谢!
    猜你喜欢
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 2021-07-15
    相关资源
    最近更新 更多