3

我正在创建一个应用程序作为学习工具,但在连接查询方面遇到了困难。

我有一个包含两个表的数据库——马和封面——声明如下;

    private static final String HORSES_CREATE = "create table horses (_id integer primary key autoincrement, "
        + "name text not null, type integer not null, birthDate text not null, vaccineDate text not null, "
        + "inFoal integer not null, notes text not null);";

“类型”字段指的是种马、母马、阉割等,并且是从微调器中选择的(从 XML 字符串数组中填充)。

private static final String COVERS_CREATE = "create table covers (_id integer primary key autoincrement, "
        + "stallionName integer not null, mareName integer not null, firstCoverDate text not null, lastCoverDate text not null, "
        + "scan14Date text not null, scan28Date text not null, foalingDate text not null, inFoal integer not null, notes text not null);";

种马名称实际上存储为马表中马的 _id 字段。它是从仅显示马匹表中类型定义为“种马”的马匹的微调器中选择的。(同样适用于马雷)。

我有一个类“DatabaseHelper”来创建和升级表,每个表都有自己的适配器类“horsesDbAdapter”和“coversDbAdapter”,其中包含添加、编辑和删除条目以及相关查询的方法。(fetchAllHorse(), fetchHorse(long rowId))

例如:

    public Cursor fetchAllHorses() {

    return mDb.query(DATABASE_TABLE,
            new String[] { KEY_ROWID, KEY_NAME, KEY_TYPE, KEY_BIRTHDATE,
                    KEY_VACCINEDATE, KEY_INFOAL, KEY_NOTES }, null, null,
            null, null, null);
}

(全部改编自Android记事本示例)

我在列表视图中显示了封面表的内容(只显示了stallionName 和mareName)。但是由于这些字段只包含对 horses 表的唯一引用,所以显示的只是相当无信息的 _id 字段。

我的问题是;如何获取马匹的相关名称以显示在 listView 中?我已经阅读了连接查询等,但是当我尝试实现它们时迷路了。我假设我必须加入 horses._id 和 Covers.stallionName (然后为 MareName 制作一个几乎相同的),但我找不到如何执行此操作的具体示例。

如果需要任何其他信息/代码,请告诉我。

任何帮助将不胜感激,在此先感谢您。

编辑:我在 horses 表中创建了stallionName 和 mareName 外键引用(_id),但我仍然不确定如何以及在何处实现连接查询;它应该在 horsesDbAdapter、coverDbAdapter 还是 CoverList 类中?(coversList 是创建和填充 listView 的类)封面表声明现在读取;

    private static final String COVERS_CREATE = "create table covers (_id integer primary key autoincrement, "
        + "stallionName integer not null, mareName integer not null, firstCoverDate text not null, lastCoverDate text not null, "
        + "scan14Date text not null, scan28Date text not null, foalingDate text not null, inFoal integer not null, notes text not null," +
        "FOREIGN KEY (stallionName) REFERENCES horses (_id), FOREIGN KEY (mareName) REFERENCES horses (_id));";
4

2 回答 2

9

我是 Android 和 SQLLiteHelper 的新手,我想知道同样的事情。

看完这篇文章,我发现定义表之间连接的方法是用SQLLiteQueryBuilder.setTables方法来完成的。请参阅此处的参考

我从这个博客得到这个

希望这有助于为读者指明正确的方向。

于 2012-10-03T01:34:22.463 回答
2

我已经设法让它工作了。对于其他可能有类似问题的人,我会尝试详细说明我做了什么。正如@deceiver 所说,我应该让stallionName 和mareName 外键引用马(见编辑)。

在coverList类(实现listView的类)中,我只需要获取数据库的一个实例并使用rawQuery直接实现SQL代码(可以使用Query来实现,但我不确定如何)添加的代码如下;

private Cursor coversCursor;
private void fillData() {

    db = (new DatabaseHelper(this).getReadableDatabase());
    coversCursor = db.rawQuery("SELECT horses1.name AS stallionNameText, covers.*, horses2.name AS mareNameText FROM horses horses1 JOIN covers ON horses1._id = covers.stallionName JOIN horses horses2 ON horses2._id = covers.MareName",
                    null);
    startManagingCursor(coversCursor);
    // Create an array to specify the fields we want to display in the list
    // (the renamed fields from the above query)
    String[] from = new String[] { "stallionNameText", "mareNameText" };

    // and an array of the fields we want to bind those fields to (in this
    // case just text1)
    int[] to = new int[] { R.id.rowStallionName, R.id.rowMareName };

    // Now create a simple cursor adapter and set it to display
    SimpleCursorAdapter covers = new SimpleCursorAdapter(this,
            R.layout.covers_list_row, coversCursor, from, to);
    setListAdapter(covers);
}

然后在 onCreate() 方法中调用 FillData()。然后只需在 onDestroy 方法中关闭数据库。(在这里选择封面表中的所有列似乎很浪费,但我最终也会在 listView 中显示这些列。我只是想在继续编码之前回答这个问题)。我发现有用的教程是http://coenraets.org/blog/android-samples/androidtutorial/

我的 SQL 查询有问题,因为有 2 个外键引用同一个表,我希望 listView 显示种马名称和母马名称,因此必须将两个马表连接到一个封面表。我只需要重命名 SQL 查询的 FROM 部分中的表。希望上面的代码很清楚。如果没有,我发现以下有用;http://www.bryantwebconsulting.com/blog/index.cfm/2005/3/11/join_a_table_to_itself_in_sql

对不起,如果这个解释对我的(不寻常的)例子来说太具体了。谢谢阅读。

于 2012-07-06T11:32:11.153 回答