从 Android 中的数据库填充列表

发布于 2024-12-13 23:36:10 字数 1438 浏览 2 评论 0原文

我正在尝试查询我在代码中创建的单个表数据库。据我所知,数据库正在正确创建。该查询应该用于填充 ListView,但是当我尝试使用查询生成的游标来创建 SimpleCursorAdapter 时,它崩溃并显示: java.lang.IllegalArgumentException:列 '_id' 不存在。我假设这可以追溯到光标,而且光标似乎是空的。

在我的 SQLiteOpenHelper 实现的 onCreate() 中以以下方式创建数据库:

db.execSQL("CREATE TABLE " + TABLE_NAME + " (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT NOT NULL, title TEXT NOT NULL, path TEXT NOT NULL);");

然后在我的 DataHelper 类中设置并执行实际查询,该类用于与数据库交互:

public Cursor selectEntryStartsWith(String partialName , String title)
{
    String where = "name LIKE '" + partialName + "%' AND title LIKE '" + title + "'";

    if (title== null || title.equals("")){
        where =  "name LIKE '" + partialName + "%'";
    }
    Cursor cur = mDatabase.query(TABLE_NAME, new String[] {"_id", "name", "title"}, where, null, null, null, "name");

    return cur;
}

使用游标的代码是如下:

Cursor cursor = mDataHelper.selectEntryStartsWith("ex", null); //get all entries that start with "ex"
String [] from = new String [] { "name", "title" };
int [] to = new int [] { R.id.name, R.id.title };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(mContext, R.layout.listview_entry, cursor, from, to);

songList.setAdapter(adapter);

我使用选项卡来查看最后一段代码,该代码来自 Fragment 的 onActivityCreated() 内;我并不是说扩展 ListFragment 可能会更好,但我认为这不是这里的问题。

如果我错过了您可能需要的信息,请提前抱歉,我已经为这个问题苦苦挣扎了一段时间了。

I’m trying to query a single table database that I’ve created in my code. To the best of my knowledge the database is being created correctly. The query is supposed to be used to populate a ListView but when I try to use the resulting cursor from my query to create SimpleCursorAdapter, it crashes with: java.lang.IllegalArgumentException: column '_id' does not exist. I am assuming this can be traced to the cursor, and also the cursor seems to be empty.

The database is created in the following way within the onCreate() of my implementation of a SQLiteOpenHelper:

db.execSQL("CREATE TABLE " + TABLE_NAME + " (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT NOT NULL, title TEXT NOT NULL, path TEXT NOT NULL);");

And then the actual query is set up and executed in my DataHelper Class which is used to interact with the database:

public Cursor selectEntryStartsWith(String partialName , String title)
{
    String where = "name LIKE '" + partialName + "%' AND title LIKE '" + title + "'";

    if (title== null || title.equals("")){
        where =  "name LIKE '" + partialName + "%'";
    }
    Cursor cur = mDatabase.query(TABLE_NAME, new String[] {"_id", "name", "title"}, where, null, null, null, "name");

    return cur;
}

The code that uses the cursor is as follows:

Cursor cursor = mDataHelper.selectEntryStartsWith("ex", null); //get all entries that start with "ex"
String [] from = new String [] { "name", "title" };
int [] to = new int [] { R.id.name, R.id.title };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(mContext, R.layout.listview_entry, cursor, from, to);

songList.setAdapter(adapter);

I'm using tabs to this last piece of code is from within the onActivityCreated() of a Fragment; I not that it might be better to extend a ListFragment, but I don't think this is the problem here in particularity.

Sorry in advance if I have missed an information that you may require, I've been banging my head on this problem for some time now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乞讨 2024-12-20 23:36:10

您知道数据实际上在数据库中吗?运行“adb shell”,cd 到您的数据目录“/data/data/[应用程序包名称]/databases”。然后运行sqlite3 [数据库文件名]。运行一些直接 SQL 查询并确保数据存在。

如果那里有数据,不要直接访问 SimpleCursorAdapter,而是在代码中运行一些文本查询,并查看是否可以访问结果。

一旦所有这些都解决了,添加 ListView 的东西作为最后一步。

有些事情要提一下。如果用户输入查询值,您需要转义这些语句值。在查询语句中使用selectionArgs:

http ://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#query(java.lang.String, java.lang.String[], java.lang.String, java.lang 。细绳[], java.lang.String、java.lang.String、java.lang.String)

或使用我的精简版 apache commons-lang 和 StringEscapeUtils 类

。 /android-mini-commons/" rel="nofollow">http://www.touchlab.co/blog/android-mini-commons/

另一件需要考虑的事情,尽管如果你没有遇到麻烦,这可能不是问题。 “name”和“title”可能是 sql 语句中棘手的关键字。

Do you know the data is actually in the database? Run 'adb shell', cd to your data directory '/data/data/[app package name]/databases'. Then run sqlite3 [db file name]. Run some direct sql queries and make sure data exists.

If there is data there, rather than going right to the SimpleCursorAdapter, run some text queries in code, and see if you can access the results.

Once all of that works out, add the ListView stuff as a last step.

Some things to mention. If the user is typing in query values, you need to escape those statement values. Either use selectionArgs in the query statement:

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#query(java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String)

or use my stripped-down apache commons-lang, and the StringEscapeUtils class.

http://www.touchlab.co/blog/android-mini-commons/

Another thing to consider, although if you're not having trouble, its probably not an issue. 'name' and 'title' might be tricky keywords in sql statements.

行雁书 2024-12-20 23:36:10

问题确实是数据库设置不正确,我尝试了另一种插入数据的方法,即使用 ContentValues 并直接插入数据库,而不是使用我之前使用的预编译插入语句。

插入方法现在看起来像这样:

public long insert(String name, String title) 
{
    ContentValues cv = new ContentValues();
    cv.put("name", name);
    cv.put("title", title);
    return mDatabase.insert(TABLE_NAME, null, cv);

    /* The old code was using this precompiled statement
    mInsertStatement.bindString(1, name);
    mInsertStatement.bindString(2, title);
    return mInsertStatement.executeInsert();
    */
}

The problem was indeed the database was not set up properly, I tried another method of inserting the data i.e. using ContentValues and inserting directly into the database, as opposed to using the precompiled insert statement I was using before.

The insert method now looks like this:

public long insert(String name, String title) 
{
    ContentValues cv = new ContentValues();
    cv.put("name", name);
    cv.put("title", title);
    return mDatabase.insert(TABLE_NAME, null, cv);

    /* The old code was using this precompiled statement
    mInsertStatement.bindString(1, name);
    mInsertStatement.bindString(2, title);
    return mInsertStatement.executeInsert();
    */
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文