2016-03-03 90 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