SQLite
誰もが使用するための1対多のマッピングを実装する方法について良いアドバイスを持っていContentProvider
ますか?見てみると、挿入するデータを含むパラメータが含まれUri ContentProvider#insert(Uri, ContentValues)
ていることがわかります。ContentValues
問題は、現在の実装ではメソッドをContentValues
サポートしておらずput(String, Object)
、クラスがfinalであるため、拡張できないことです。なぜそれが問題なのですか?これが私のデザインです:
1対多の関係にある2つのテーブルがあります。これらをコードで表すために、2つのモデルオブジェクトがあります。1番目はメインレコードを表し、2番目のオブジェクトインスタンスのリストであるフィールドがあります。ContentValues
これで、現在のオブジェクトから生成されたものを返すヘルパーメソッドがモデルオブジェクト#1にあります。プリミティブフィールドにContentValues#put
オーバーロードされたメソッドを入力するのは簡単ですが、リストがうまくいきません。したがって、現在、2番目のテーブル行は単一の文字列値であるため、コンマで区切られた文字列を生成し、それを内部のString[]に再解析しContentProvider#insert
ます。それは不愉快に感じるので、誰かがそれをよりクリーンな方法で行う方法をほのめかすことができるかもしれません。
ここにいくつかのコードがあります。モデルクラスからの最初:
public ContentValues toContentValues() {
ContentValues values = new ContentValues();
values.put(ITEM_ID, itemId);
values.put(NAME, name);
values.put(TYPES, concat(types));
return values;
}
private String concat(String[] values) { /* trivial */}
ContentProvider#insert
これがメソッドのスリム化バージョンです
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.beginTransaction();
try {
// populate types
String[] types = ((String)values.get(Offer.TYPES)).split("|");
// we no longer need it
values.remove(Offer.TYPES);
// first insert row into OFFERS
final long rowId = db.insert("offers", Offer.NAME, values);
if (rowId > 0 && types != null) {
// now insert all types for the row
for (String t : types) {
ContentValues type = new ContentValues(8);
type.put(Offer.OFFER_ID, rowId);
type.put(Offer.TYPE, t);
// insert values into second table
db.insert("types", Offer.TYPE, type);
}
}
db.setTransactionSuccessful();
return ContentUris.withAppendedId(Offer.CONTENT_URI, rowId);
} catch (Exception e) {
Log.e(TAG, "Failed to insert record", e);
} finally {
db.endTransaction();
}
}