¿Alguien tiene buenos consejos sobre cómo implementar el mapeo uno a muchos para SQLite
usando ContentProvider
? Si mira Uri ContentProvider#insert(Uri, ContentValues)
, puede ver que tiene el parámetro ContentValues
que contiene datos para insertar. El problema es que en su implementación actual ContentValues
no es compatible con el método put(String, Object)
y la clase es definitiva, así que no puedo extenderla. ¿Por qué es un problema? Aquí viene mi diseño:Android: SQLite de diseño uno a muchos
Tengo 2 tablas que están en una relación uno a muchos. Para representarlos en el código, tengo 2 objetos modelo. Primero representa el registro principal y tiene un campo que es una lista de instancias de segundo objeto. Ahora tengo un método de ayuda en el objeto modelo # 1 que devuelve ContentValues
generado fuera del objeto actual. Es trivial poblar campos primitivos con ContentValues#put
métodos sobrecargados, pero no tengo suerte para la lista. Así que actualmente dado que mi segunda fila de la tabla es solo un único valor de cadena, genero una cadena delimitada por comas que luego vuelvo a analizar en String [] dentro de ContentProvider#insert
. Eso se siente asqueroso, así que tal vez alguien pueda insinuar cómo se puede hacer de una manera más limpia.
Aquí hay algunos códigos. En primer lugar de la clase del modelo:
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 */}
y aquí está adelgazado versión de ContentProvider#insert
método
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();
}
}
Sí, tengo el mismo problema ... cómo envuelva múltiples insertos en una transacción? Logré esto agregando dos URI especiales: uno para el inicio de la transacción y otro para el final. Sé que esta no es la mejor solución. Si tienes uno mejor lo agradeceré! – Bhiefer