Android のデータベースでテーブルの結合に困ること
Android で利用できるデータベースは SQLite3 ですが、クエリの結果はCursor
という抽象化されたインタフェースで取り扱っています。
SQLiteDatabase
で直接 SQL を実行するインタフェースもありますが、SELECT 文だけは特別扱いされ、返り値がCursor
となるため、ほぼ確実にクエリ結果を取り扱うにはCursor
とつきあうことになります。
ここで、あるデータベースに以下のような複数のテーブルがあったと仮定します。
- table_1
_id | name | description |
---|---|---|
1 | foo | first entry |
2 | bar | second entry |
3 | baz | another entry |
- table_2
_id | age | description |
---|---|---|
1 | 13 | hogehoge |
2 | 14 | fugafuga |
3 | 16 | piyopiyo |
これらのテーブルから、_id
を元に結合したクエリを投げてみます。
SELECT * FROM table_1, table_2 WHERE table_1._id = table_2._id;
これによって得られるCursor
で、クエリ結果のセットにアクセスするには、以下のようにします。
Cursor cursor = // query...
if (cursor == null)
return;
try {
while (cursor.moveToNext()) {
long id = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
String name = cursor.getString(cursor.getColumnIndex("name"));
int age = cursor.getInt(cursor.getColumnIndex("age"));
String description = cursor.getString(cursor.getColumnIndex("description"));
// do something with the result...
}
} finally {
cursor.close();
}
Cursor#getColumnIndex(String)
を使って、カラム名に対応する、1行分のデータを格納しているコレクションのインデックスを取得し、そのインデックスを元に、結果セットからデータを取り出します。
さて、table_1
とtable_2
にはそれぞれ、description
という名前のカラムが存在します。
Cursor
を経由したアクセスでは、どちらのものかを区別するようなコードの書き方はしていませんが、結果自体は取得できているようです。
実のところ、テーブルを結合した際、同じ名前のカラムが存在した時、それぞれテーブルごとにカラムを絞り込む機能はCursor
にはありません。
内部的には、Map
のようなデータ構造でクエリ結果のセットを管理しています。つまり、カラム名の衝突はMap
におけるキーの衝突と同じ結果をもたらすことになります。よって、データ自体は存在し取得もできていますが、取得できるデータは、Cursor
が持つ結果セットに最後に追加された(実質上書きされた)データになります。
このような事態を避けるには、カラム名を衝突しないように作るか、ある程度正規化しないで、最初から結合した状態にしておくか、クエリを別々に分けるかのいずれかの手段で対処します。
Author And Source
この問題について(Android のデータベースでテーブルの結合に困ること), 我々は、より多くの情報をここで見つけました https://qiita.com/KeithYokoma/items/9c24b912b87b65a08db8著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .