2011-04-29 46 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);