Utilice Insertar o Reemplazar en ContentProvider

Cuando quiero comprobar y ver si existe algo en mi ContentProvider lo que suelo hacer es algo similar a esto

 Cursor c = getContentResolver().query(table,projection,selection,selectionArgs,sort); if(c != null && c.moveToFirst()){ //item exists so update }else{ //item does not exist so insert } 

Pero eso significa que siempre tengo que hacer posiblemente una llamada de base de datos innecesaria ralentizar las cosas, especialmente el mayor número de controles en la base de datos que tengo que hacer. Tiene que haber una mejor manera de manejar esto, así que no siempre tengo que consultar primero.

Miré esta pregunta

Android Contentprovider – actualización dentro de un método de inserción

Pero el uso de insertWithOnConflict sólo comprueba la identificación de la clave principal y en mi caso que no funcionará porque lo que estoy comprobando no es el id sino una cadena única de una base de datos del servidor.

Por lo que hay algo que puedo hacer con el proveedor de contenido por lo que no siempre tienen que hacer una consulta para comprobar si el elemento existe en él ya?

Puede tener una restricción UNIQUE en columnas diferentes de ID uno. Ejemplo:

CREATE TABLE TEST (_id INTEGER PRIMARY KEY AUTOINCREMENT, server_id INTEGER NOT NULL, name TEXT, UNIQUE(server_id))

Al tener esta tabla, en el método de inserción de su proveedor de contenido, puede hacer algo como esto:

 @Override public Uri insert(Uri uri, ContentValues contentValues) { final SQLiteDatabase db = mDatabase.getWritableDatabase(); final int match = mUriMathcer.match(uri); switch (match) { case TEST: insertOrUpdateById(db, uri, "TEST", contentValues, "server_id"); getContext().getContentResolver().notifyChange(uri, null, false); return Contract.Test.buildTestUri(contentValues.getAsString("server_id")); default: throw new UnsupportedOperationException("Unknown uri: " + uri); } } /** * In case of a conflict when inserting the values, another update query is sent. * * @param db Database to insert to. * @param uri Content provider uri. * @param table Table to insert to. * @param values The values to insert to. * @param column Column to identify the object. * @throws android.database.SQLException */ private void insertOrUpdateById(SQLiteDatabase db, Uri uri, String table, ContentValues values, String column) throws SQLException { try { db.insertOrThrow(table, null, values); } catch (SQLiteConstraintException e) { int nrRows = update(uri, values, column + "=?", new String[]{values.getAsString(column)}); if (nrRows == 0) throw e; } } 

Espero que ayude. ¡Aclamaciones!

La respuesta de Edy Bolos puede escribirse simplemente como

CREATE TABLE TEST ( _id INTEGER PRIMARY KEY AUTOINCREMENT, server_id INTEGER NOT NULL, name TEXT UNIQUE ON CONFLICT REPLACE);

Agregue UNIQUE ON CONFLICT REPLACE en create table query.

La respuesta de Edy Bolos se puede escribir de nuevo como

 private void insertOrUpdateById(SQLiteDatabase db, Uri uri, String table, ContentValues values, String column) throws Exception { long id = db.insertWithOnConflict(table, column, values, SQLiteDatabase.CONFLICT_REPLACE); if(id < 0){ throw new Exception(); } } 
  • ORMLite insertar o reemplazar
  • Almacenamiento de bases de datos SQLite con Android y Phonegap
  • ¿Es posible crear una tabla sqlite en tiempo de ejecución basada en el número de elementos en matriz
  • ¿Qué son las aplicaciones com.sec.android.provider. * Exactamente?
  • Mostrar datos SQLite en RecyclerView
  • Por qué necesitamos onUpgrade (); Método en la clase SQLiteOpenHelper
  • Android SQLite Query - Obteniendo los últimos 10 registros
  • ¿Cómo recuperar un ID del elemento seleccionado en un Spinner dinámico?
  • Creación de restricciones de clave externa en ORMLite en SQLite
  • ¿Debo habilitar la restricción de clave externa en onOpen o onConfigure?
  • El tacto de la firma de la lona crea la edición en teléfono
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.