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