题
任何人都具有良好的建议就如何实现一个多映射 SQLite
使用 ContentProvider
?如果你看看 Uri ContentProvider#insert(Uri, ContentValues)
你可以看到,它已经 ContentValues
param,其中包含的数据插入。问题是,在其目前的执行情况 ContentValues
不支持 put(String, Object)
方法和类是最终的,所以我不能延长。为什么它是一个问题吗?这里是我的设计:
我有2表其是在一对多关系。来表示这些代码我有2个模型对象。1代表主记录和具有领域,这是一个列表2对象的实例。现在我有一个辅助方法的模型对象#1返回 ContentValues
产生的断电流的对象。这是微不足道填充的原始领域 ContentValues#put
超载方法,但我运气不好的的名单。因此,目前由于我的第2次表行只是一个单一的字符串值我产生一个逗号分隔串然后我重新分析串[]内 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();
}
}
解决方案
我觉得你看一个一对多的关系的错误的一端。
看一看的ContactsContract
内容提供商,例如。联系人可以有多个电子邮件地址,许多电话号码等所完成的方式是通过做刀片上的“多” 的侧/更新/删除。要添加新的电话号码,可以插入一个新的电话号码,提供对他们的电话号码所属的接触的ID。
如果你有没有内容提供商一个普通的SQLite数据库您会做同样的。上的表中的一个到许多在关系数据库中的关系通过插入/更新得以实现/删除的“多”方,每一个具有一个外键返回到“一”侧。
现在,从OO的角度来看,这是不理想的。欢迎您来创建ORM风格的包装对象(认为休眠),让您从“一”方操纵儿童的集合。然后足够智能的集合类可以转身并同步“多”表进行匹配。然而,这些并不一定琐碎正确实现。
其他提示
可以使用ContentProviderOperations
此。
它们与到后台参考用于父行生成的标识符的能力基本上批量操作。
如何ContentProviderOperations
可以用于一个一对多的设计在这个答案是很好的解释:是什么withValueBackReference的语义?
所以,我要回答我自己的问题。我是正确的轨道上具有两个表格和两个模型对象。什么是缺少和什么样的混淆,我是,我想直接插入复杂的数据通过 ContentProvider#insert
在一个单一的呼吁。这是错误的。 ContentProvider
应该创建和维持这两个表格,但决定在其表使用应当由Uri参数 ContentProvider#insert
.这是非常方便地使用ContentResolver和方法添加诸如"addFoo"的模式对象。这种方法将采取ContentResolver参数,并在结束这里的顺序插入一个复杂的记录:
- 插入父记录通过
ContentProvider#insert
和获得记录id - 每个孩子提供父ID(foregn关键)和使用
ContentProvider#insert
与不同Uri插入孩子的记录
那么剩下的唯一问题是如何为信封上的代码交易?