У кого-нибудь есть хорошая рекомендация о том, как реализовать отображение "один ко многим" для SQLite
с помощью ContentProvider
? Если вы посмотрите Uri ContentProvider#insert(Uri, ContentValues)
, вы увидите, что у него есть параметр ContentValues
, содержащий данные для вставки. Проблема в том, что в своей текущей реализации ContentValues
не поддерживает метод put(String, Object)
, и класс является окончательным, поэтому я не могу его расширять. Почему это проблема? Вот мой дизайн:
У меня есть 2 таблицы, которые связаны друг с другом. Чтобы представить их в коде, у меня есть 2 объекта модели. Первая представляет основную запись и имеет поле, которое является списком экземпляров 2-го объекта. Теперь у меня есть вспомогательный метод в объекте модели # 1, который возвращает ContentValues
, сгенерированный с текущего объекта. Тривиально заполнять примитивные поля перегруженными методами ContentValues#put
, но мне не повезло в списке. Так что, так как моя вторая строка таблицы - это всего лишь одно значение String, я генерирую строку с разделителями-запятыми, которая затем я переписываю в String [] внутри ContentProvider#insert
. Это кажется yucky, поэтому, может быть, кто-то может намекнуть, как это можно сделать чище.
Вот какой код. Сначала из класса модели:
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();
}
}