2011-04-29 45 views
12

爲了讓Android CursorAdapter類正常工作,我找到了一行_id。現在,我有一個特定的命名方案,並且不希望將我的id列(稱爲ID)更改爲_id,以供我需要CursorAdapters的所有表使用。我認爲這會影響我的一些複雜查詢的可讀性 - 再加上「_id」是醜陋的:P。爲CursorAdapter需要一個_id行的解決方法

我在討論使用自定義「TableID as _id」選擇查詢,但我喜歡SQLiteDatabase的很好的查詢方法,並且它看起來並不像他們支持在查詢中重命名列。

總是需要一個特定的表列名稱似乎相當不靈活(和奇怪)。有沒有辦法指定哪些列作爲CursorAdapter的id列使用?或者,也許另一個解決方法我沒有想到?

+1

+1 - '「_id」是醜陋:P' – 2014-04-14 18:47:58

回答

2

兩種替代解決方案是使用CursorWrapper或使用ManagedQueryProjectionMap來映射您的uid to_id。

+0

CursorWrapper可以工作。我不熟悉使用託管查詢,但谷歌搜索帶我到SQLiteQueryBuilder的setProjectionMap方法,它可能會伎倆... ... – Emily 2011-04-29 01:41:00

+0

ManagedQuery與ContentProviders,我在我的項目中實施,因爲我正在嘗試學習儘可能多儘可能......;)另外一個解決方案是在數據庫中創建一個包含_id作爲其中一列的視圖。 – 2011-04-29 02:02:40

+1

我沒有想到發表看法。感謝您的許多建議。沒有一個是我尋找的那麼簡單(當你CursorAdapter!),但我想那就是生活。再次感謝。 – Emily 2011-04-29 17:17:09

10

您的數據庫不需要有一個名爲'_id'的列,但CursorAdaptor確實需要返回一個。你可以在一個rawQuery中用一個別名(比如你的「TableID as _id」的想法)做到這一點。

一個例子是,我有列的表...

uid,name,number 

要查詢此爲SimpleCursorAdapter(例如),我這樣做是與數據庫rawQuery ...

db.rawQuery("SELECT uid as _id,name,number FROM MY_TABLE"); 

這工作正常,並提供必要的'_id'列SimpleCursorAdapter。

+0

是的,我正在考慮,但我傾向於在S​​QLiteDatabase類中使用.query方法而不是.rawQuery。如果沒有其他方法,我只需要選擇兩個惡意中的較小者(重命名該列或者手動構建我的查詢並使用rawQuery)。除了.rawQuery還有其他方法可以讓我重命名列嗎? – Emily 2011-04-29 01:14:06

+0

@Emily:對於我目前的應用程序,我個人發現將我的數據庫列重命名爲最終的邪惡(尤其是當我在遠程系統上鏡像數據庫時),但顯然它會因開發到開發和應用程序而不同。關於使用SQLiteDatabase查詢方法的問題,再次進行個人觀察,但我一直使用「原始」SQL,因爲我使用不同的語言和不同的平臺進行編程。原始SQL是可移植的,我也看到一些真正可怕的例子,這些人嘗試使用SQLiteDatabase查詢方法執行復雜查詢。 – Squonk 2011-04-29 01:33:05

12

沒有必要使用原始查詢,CursorWrapper等。您可以完全按照您提到的內容進行操作:當您爲查詢指定列時,只需指定「TableID as _id」作爲其中一個列。其實,而不是_id我會使用BaseColumns._ID。像這樣的東西應該就好了工作:

static final String[] columns = new String[] { 
    "TableID AS " + BaseColumns._ID, 
    ... 
}; 

然後傳遞到無論你使用的是創建光標(SQLiteDatabase,CursorLoader等)

我也建議把你的列名轉換爲您可以在整個應用中引用的字符串常量,例如MyDatabase.TABLE_ID,所以上面是MyDatabase.TABLE_ID + " AS " + BaseColumns._ID

0

我想出了這個解決方案,從這個職位sequential row numbers from query一些幫助。它使用生成的_id字段。這裏的優點是你不需要混淆你的模式,並且你可以得到很好的順序_id值。

我的代碼加載光標如下:

Cursor c = db.rawQuery(
       "SELECT * " 
       +"FROM Sale " 
       +"ORDER BY orderTime " 
       , null); 

我加入內選擇,這需要在外部的表名稱的別名。 (注意如何T2在內部選擇使用,但在外部創建選擇)

Cursor c = db.rawQuery(
      "SELECT " 
      +"(select COUNT(0) from Sale t1 where t1.orderTime <= t2.orderTime) as _id,t2.* " 
      +"FROM Sale t2 " 
      +"ORDER BY t2.orderTime " 
      , null);