2016-03-03 47 views
0

当我为实体编写accessor时,我通常会添加同一查询的同步和异步版本。例如:如何正确使用同步和异步方法为DataStax访问器做饭?

@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. 

可能有办法有两个同步和相同的查询,但没有异步版本重新准备?

回答

0

您可以更改访问器以返回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中映射到你的类执行语句,那么你可以使用一个映射

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

是的,这是有道理的。谢谢! – sedovav

1

这是一个有趣的用例。

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

我们可以非常轻松地做的一件事是在处理方法时缓存准备好的语句,因此至少在同一接口内重复查询时不会准备两次。

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

+0

感谢奥利弗!我希望我能找到时间来创建拉取请求。 – sedovav