2011-09-29 24 views
2

在我的Android應用程序中,我想對內容提供者執行查詢,然後優化搜索(我有兩個WHERE子句字符串)。應該由第二個查詢返回的記錄是第一個查詢返回的行的子集。在Android中改進現有搜索查詢的結果

我目前的解決辦法是這樣的:

Cursor cursor1 = query (myUri, myProjection, where1, null, null); 
//do stuff 
Cursor cursor2 = query (myUri, myProjection, where2, null, null); 
//do other stuff 

如果我這樣做,第二個查詢的運行效率不高,在所有(它搜索的完整數據庫,就像第一)。我想第二個查詢只針對cursor1中返回的行來運行。可以這樣做,以及如何?

如果我使用相同(參數化)的字符串和不同的參數,android文檔指出可以緩存查詢。這可能有用嗎?還是有一種完全不同的方式來做到這一點?

+0

只是爲了澄清,我試圖找到一種不涉及我自己的數據結構複製數據的解決方案。 –

回答

1

檢查CursorAdapter。它實現了Filterable接口幷包含一些有趣的方法:setFilterQueryProvider和getFilterQueryProvider。我沒有使用CursorAdapter,但是如果它與其他適配器(或實現Filterable的自定義適配器)類似,那麼它正是您需要的。

UPDATE下面是一個例子:http://www.outofwhatbox.com/blog/2010/11/android-simpler-autocompletetextview-with-simplecursoradapter/

你感興趣的部分是這樣的:

adapter.setFilterQueryProvider(new FilterQueryProvider() { 
     public Cursor runQuery(CharSequence constraint) { 
      // Search for states whose names begin with the specified letters. 
      Cursor cursor = mDbHelper.getMatchingStates(
        (constraint != null ? constraint.toString() : null)); 
      return cursor; 
     } 
    }); 

因爲它返回新光標比如我認爲它不會打DB一次。您可以通過迭代遊標並查找匹配來實現自己的搜索邏輯。你將不得不編寫一些基準測試,看看是否值得避免使用新的查詢命中數據庫,因爲通過手動迭代Cursor你將會更加難以達到數據庫。請記住,除非明確要求(通過調用Cursor上的任何readXXX()),否則實際上不會從DB檢索數據(行/記錄)。

順便說一句,你可能會感興趣的ORMLite

+0

我認爲你的假設是正確的 - runQuery應該返回一個新的Cursor,這意味着對數據庫的新查詢。我沒有看到CursorAdapter是如何解決我的問題的 - 它只是定義了一個框架來將數據從一個Cursor綁定到一個ListView。 –

+0

手動迭代遊標是一種解決方案,但我不知道如何基於符合新條件的數據(或從現有遊標中刪除行)手動創建新的遊標。有任何想法嗎? –

+0

我仍然堅持這個想法,對數據庫執行新的查詢是一個更好的解決方案。 DB被設計爲被查詢。執行後的光標實際上並不包含數據庫中的任何數據(延遲加載),因此它非常無害,或者比嘗試過濾現有光標更加無害,在這種情況下,您實際上是將數據從數據庫讀取到應用程序。 – Audrius