2012-10-04 15 views
7

Solo quiero una notificación después de que toda la inserción masiva se realice en la base de datos. Proporcione un ejemplo para usar la función bulkInsert(). No puedo encontrar un ejemplo adecuado en internet. ¡¡¡¡Por favor ayuda!!!!¿Cómo se usa la función bulkInsert() en android?

Respuesta

37

Esto es bulkInsert using ContentProvider.

public int bulkInsert(Uri uri, ContentValues[] values){ 
    int numInserted = 0; 
    String table; 

    int uriType = sURIMatcher.match(uri); 

    switch (uriType) { 
    case PEOPLE: 
     table = TABLE_PEOPLE; 
     break; 
    } 
    SQLiteDatabase sqlDB = database.getWritableDatabase(); 
    sqlDB.beginTransaction(); 
    try { 
     for (ContentValues cv : values) { 
      long newID = sqlDB.insertOrThrow(table, null, cv); 
      if (newID <= 0) { 
       throw new SQLException("Failed to insert row into " + uri); 
      } 
     } 
     sqlDB.setTransactionSuccessful(); 
     getContext().getContentResolver().notifyChange(uri, null); 
     numInserted = values.length; 
    } finally {   
     sqlDB.endTransaction(); 
    } 
    return numInserted; 
} 

Llámalo solo una vez cuando tengas más ContentValues ​​en ContentValues ​​[] values ​​array.

+0

Esto * no * terminará las inserciones restantes si una falla, ¿verdad? – Anthony

+0

Esto revertirá/revertirá cada inserción individual si hay alguna excepción antes de llamar a setTransactionSuccessful en ese bloque try/catch. En resumen, si hay una excepción, no recibirá ninguna inserción. – Warlock

+0

Me salió un error al decir que 'Variable' tabla 'puede no haberse inicializado'. Establecer la declaración a 'String table =" ";' resolvió el problema. –

3

He buscado por siempre para encontrar un tutorial para implementar esto en el lado de la actividad y el lado del proveedor de contenido. Utilicé la respuesta de "Warlock" desde arriba y funcionó muy bien en el lado del proveedor de contenido. Utilicé la respuesta de this post para preparar la matriz ContentValues ​​en el extremo de la actividad. También modifiqué mis valores de contenido para recibir de una cadena de valores separados por comas (o nuevas líneas, puntos, punto y coma). ¿Qué era la siguiente:

ContentValues[] bulkToInsert; 
    List<ContentValues>mValueList = new ArrayList<ContentValues>(); 

    String regexp = "[,;.\\n]+"; // delimiters without space or tab 
    //String regexp = "[\\s,;.\\n\\t]+"; // delimiters with space and tab 
    List<String> splitStrings = Arrays.asList(stringToSplit.split(regexp)); 

    for (String temp : splitStrings) { 
     Log.d("current student name being put: ", temp); 
     ContentValues mNewValues = new ContentValues(); 
     mNewValues.put(Contract.KEY_STUDENT_NAME, temp); 
     mNewValues.put(Contract.KEY_GROUP_ID, group_id); 
     mValueList.add(mNewValues); 
    } 
    bulkToInsert = new ContentValues[mValueList.size()]; 
    mValueList.toArray(bulkToInsert); 
    getActivity().getContentResolver().bulkInsert(Contract.STUDENTS_CONTENT_URI, bulkToInsert); 

no pude encontrar una forma más limpia para unir la cadena de división trazada directamente a la matriz ContentValues ​​para bulkInsert. Pero esto funciona hasta que lo encuentre.

0

Pruebe este enfoque.

public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) { 
    final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 

    switch (sUriMatcher.match(uri)) { 

     case CODE_WEATHER: 
      db.beginTransaction(); 
      int rowsInserted = 0; 
      try { 
       for (ContentValues value : values) { 


        long _id = db.insert(WeatherContract.WeatherEntry.TABLE_NAME, null, value); 
        if (_id != -1) { 
         rowsInserted++; 
        } 
       } 
       db.setTransactionSuccessful(); 
      } finally { 
       db.endTransaction(); 
      } 

      if (rowsInserted > 0) { 
       getContext().getContentResolver().notifyChange(uri, null); 
      } 


      return rowsInserted; 

     default: 
      return super.bulkInsert(uri, values); 
    } 
} 

La respuesta de Warlock inserta todas o ninguna fila. Además, realice tareas mínimas entre setTransactionSuccessful() y endTransaction() y, por supuesto, no hay operaciones de base de datos entre estas dos llamadas a funciones.

Fuente de código: Udacity

Cuestiones relacionadas