【问题标题】:Querying and working with Cursors in SQLite on Android在 Android 上的 SQLite 中查询和使用游标
【发布时间】:2010-11-10 11:54:31
【问题描述】:

不知道是不是只有我一个人有这种感觉……

我发现在 android 中使用 sqlite api 是一件让人头疼的事情,而且会毁掉漂亮的灵魂。有没有人有任何提示/帮助让我的生活更轻松?

这是我所说的一个例子。

//create code

db.execSQL("CREATE TABLE " + CUSTOMER_TABLE_NAME + " ("
                        + GENERIC_ID_KEY+ " INTEGER PRIMARY KEY NOT NULL, " 
                        + PHONE_KEY + " INTEGER NOT NULL, "
                        + CUSTOMER_NAME_KEY+ " TEXT NOT NULL, "
                        + EMAIL_KEY + " TEXT NOT NULL, "
                        + ADDRESS_KEY +" TEXT);");


//get code
    Cursor mCursor = mDb.query(true, CUSTOMER_TABLE_NAME, new String[] {GENERIC_ID_KEY,
                        ADDRESS_KEY, PHONE_KEY, EMAIL_KEY,CUSTOMER_NAME_KEY}, GENERIC_ID_KEY + "=" + customerDbId, null,
                                null, null, null, null);

        Customer customer = new Customer (customerDbId, (CharSequence)mCursor.getString(mCursor.getColumnIndexOrThrow(CUSTOMER_NAME_KEY)),
                            (CharSequence)mCursor.getString(mCursor.getColumnIndexOrThrow(PHONE_KEY)),
                            (CharSequence)mCursor.getString(mCursor.getColumnIndexOrThrow(EMAIL_KEY)),
                            (CharSequence)mCursor.getString(mCursor.getColumnIndexOrThrow(ADDRESS_KEY)));

这是一个从数据库查询创建简单客户对象的简单示例;我的一些代码比这更糟糕。以这种方式手工制作查询会导致我在运行时才发现的各种错误。

非常感谢任何提示!

好的,在下面的提示之后,我现在有了这个:

  db.execSQL("CREATE TABLE customer (_id INTEGER PRIMARY KEY NOT NULL, " 
                        + "phone_number INTEGER NOT NULL, "
                        + "name TEXT NOT NULL, "
                        + "email TEXT NOT NULL, "
                        + "address TEXT);");


    //get code
String q = "SELECT * FROM customer WHERE _id = " + customerDbId +";"
        Cursor mCursor = mDb.rawQuery(q, null);

        Customer customer = new Customer (mCursor);

在客户中,我访问这样的字段

mName = cursor.getString(2)

啊,我感觉好多了:)

干杯 硅

【问题讨论】:

  • 好吧,无意冒犯,有时您实际上必须编写一些代码 :) 移动平台不提供与桌面操作系统相同的抽象。
  • 啊,那getColumnIndexOrThrow 的东西让我快要死了...他们不能创建一个直接采用列名的getString 重载吗???

标签: android sqlite


【解决方案1】:
  1. 如果没有必要,不要使用模型对象。我得出的结论是,除非存在只能通过模型​​对象表示的重要业务逻辑,否则它们在移动平台中比它们的价值更麻烦。
  2. 假设您被模型对象困住,让它们从Cursor 中加载自己,而不是尝试传入无数参数。
  3. 对于有限的附加值,query()rawQuery() 详细得多,如果您了解 SQL。
  4. 通过串联组装您的 CREATE TABLE 子句是一种自我强加的痛苦,SQLite 或 Android 没有强制要求。
  5. 不要在自定义编写的代码中使用getColumnIndexOrThrow()。您编写了查询,因此您知道列返回的顺序。如果您正在创建一些不知道所提供光标详细信息的抽象库,请仅使用 getColumnIndexOrThrow() 之类的内容。
  6. String 继承自 CharSequence,因此可以删除所有这些转换。

【讨论】:

  • 谢谢,rawQuery()!我错过了,看起来非常有用。我还会重新考虑我的模型对象,因为我不会被它们困住。
  • 几周前,在我自己弄清楚这一切之前,你在哪里?很高兴确认我已经怀疑的内容,但遗憾的是所有 Google 文档似乎都遵循这条极其复杂的路线。
  • 您好 CommonsWare,您能否确认我对您的回答的理解?您是说使用游标作为数据对象时不需要建模对象,除非您需要操作数据,否则只需使用游标?我发现在我的 SQLite 支持的应用程序中建模对象几乎没有用处,因为我已经将我的 SQLite 表建模为“对象”,当我将一个作为光标返回时,这似乎就是我所需要的。你同意吗?如果您关心更多细节,这是我的问题:stackoverflow.com/questions/9791349/…
  • 使用模型的替代方法是什么?
  • @J.K.:首先,请记住,这个问题和答案已经有五年的历史了,这对于 Android 来说是永恒的。假设您愿意处理内存管理,欢迎您手动或通过以 Android 为中心的 ORM 将数据库结果复制到 POJO 模型中。但是你并不一定需要 POJO 模型,只需使用原始的 Cursor 作为模型数据的来源。
【解决方案2】:

我在 SQLite 中测试了很多我的 SQL,然后将它们作为字符串复制到 Android。当我可以直接与命令行交互时,我会更容易调试。

我使用的另一种技术是将尽可能多的查询保存为字符串常量或字符串资源。

您也不需要像INTEGER NOT NULL 这样的SQL,因为SQLite 使用鸭子类型/清单类型。不过,它确实有助于类型亲和力..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 2014-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多