任何人都对如何使用SQLite
实现ContentProvider
的一对多映射有很好的建议?如果查看Uri ContentProvider#insert(Uri, ContentValues)
,您会发现它具有ContentValues
参数,其中包含要插入的数据。问题在于,在其当前实现中ContentValues
不支持put(String, Object)
方法,并且类是最终的,因此我无法对其进行扩展。为什么有问题?这是我的设计:
我有2个处于一对多关系的表。为了用代码表示这些,我有2个模型对象。第一个代表主记录,并具有一个字段,该字段是第二个对象实例的列表。现在,我在模型对象#1中有一个辅助方法,该方法返回从当前对象生成的ContentValues
。用ContentValues#put
重载的方法填充原始字段很简单,但是我对这个列表不满意。因此,当前由于我的第二个表行只是一个String值,因此生成了一个逗号分隔的String,然后将其解析为ContentProvider#insert
内部的String []。感觉令人讨厌,所以也许有人可以暗示如何以更清洁的方式完成它。
这是一些代码。首先来自模型类:
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();
}
}
最佳答案
我认为您正在寻找一对多关系的错误结局。
例如,看看ContactsContract
内容提供程序。联系人可以具有许多电子邮件地址,许多电话号码等。完成的方法是在“许多”侧进行插入/更新/删除。要添加新的电话号码,请插入一个新的电话号码,并提供该电话号码所属的联系人的ID。
如果您有一个没有内容提供程序的纯SQLite数据库,则将执行相同的操作。关系数据库中的一对多关系是通过在“许多”侧的表上进行插入/更新/删除来实现的,每个插入/更新/删除都具有返回“一个”侧的外键。
现在,从面向对象的角度来看,这是不理想的。欢迎您创建ORM样式的包装器对象(例如Hibernate),该对象可让您从“一个”侧操纵一组子代。然后,一个足够智能的集合类可以转过来并同步“许多”表以进行匹配。但是,正确实现这些不一定很琐碎。
关于Android:SQLite一对多设计,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2205327/