当前位置 : 主页 > 手机开发 > android >

android – 使用ContentValues数组批量插入

来源:互联网 收集:自由互联 发布时间:2021-06-11
我试图做一个约700浮动的批量插入.我正在使用的方法是以及内容提供者的bulkInsert.问题是,当我将所有浮点值放入ContentValues时,没有任何反应.将这些浮点值插入ContentValues对象的更好方法
我试图做一个约700浮动的批量插入.我正在使用的方法是以及内容提供者的bulkInsert.问题是,当我将所有浮点值放入ContentValues时,没有任何反应.将这些浮点值插入ContentValues对象的更好方法是什么?

private void saveToDatabase( float[] tempValues )
    {
    ContentValues values = new ContentValues();

    // WM: TODO: add patient id and sensor type
    for (float tempVal : tempValues){
        values.put( DataTable.COLUMN_DATA, tempVal );
    }

    ContentValues[] cvArray = new ContentValues[1];
    cvArray[0] = values;

    ContentResolver resolver = getContentResolver();
    resolver.bulkInsert( HealthDevContentProvider.CONTENT_URI_DATA, cvArray);

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

    int uriType = sURIMatcher.match(uri);

    switch (uriType) {
    case RAWINPUT_TABLE:
        table = RAWINPUT_TABLE_PATH;
        break;
    }

    db.beginTransaction();
    try {
        for (ContentValues cv : values) {
            long newID = db.insertOrThrow(table, null, cv);
            if (newID <= 0) {
                throw new SQLException("Failed to insert row into " + uri);
            }
        }
        db.setTransactionSuccessful();
        getContext().getContentResolver().notifyChange(uri, null);
        numInserted = values.length;
    } finally {         
        db.endTransaction();
    }
    return numInserted;
}
我知道这将是粗鲁的,但只是丢掉这段代码.提供程序具有处理大多数SQLite操作的主要方法,并且您尝试将其中的三个(insert(),bulkInsert()和applyBatch())混合到某种类型的Frankenstein中.以下是主要错误:

1)此行values.put(DataTable.COLUMN_DATA,tempVal)未在每次迭代时插入新条目;它压倒了他们.在所有迭代之后,值仅包含数组的第700个浮点值.

2)正如@Karakuri记得的那样,cvArray中只有一个ContentValues实例. bulkInsert()doc说明了它的第二个参数:

An array of sets of column_name/value pairs to add to the database. This must not be null.

因此,cvArray必须包含要插入数据库的每个条目的ContentValues实例(一组).

3)不完全是一个错误,但你应该注意的事情.无法保证mTables将存在,并且尝试在不指定表的情况下进行操作将抛出SQLException.

4)这三行基本没用:

if (newId <= 0) {
    throw new SQLException("Failed to insert row into " + uri);
}

如果在插入操作期间发生某些错误,insertOrThrow()已经抛出异常.如果要手动检查错误,请尝试insert()或insertWithOnConflict()(或者在try块中添加一个catch并在那里处理异常).

5)最后,有一个关于numInserted @petey指向的问题(并且没有必要重复).

最后一条建议:忘记bulkInsert()存在.我知道这将需要更多行代码,但使用applyBatch()可以获得更好的结果(更容易,因为您不必实现它). Wolfram Rittmeyer写了一系列关于交易的优秀文章,检查你是否有任何疑问.

最后但并非最不重要的(是的,我今天心情很好),这就是我将如何进行代码的基本实现:

@Override
public Uri insert(Uri uri, ContentValues values) {
    final SQLiteDatabase db // TODO: retrieve writable database
    final int match = matcher.match(uri);

    switch(match) {
        case RAWINPUT_TABLE:
            long id = db.insert(RAWINPUT_TABLE, null, values); // TODO: add catch block to deal.
            getContext().getContentResolver().notifyChange(uri, null, false);
            return ContentUris.withAppendedId(uri, id);

        default: 
            throw new UnsupportedOperationException("Unknown uri: " + uri);
    }
}

private void saveToDatabase( float[] tempValues ) {

    ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();

    for (float tempVal : tempValues){     

        operations.add(ContentProviderOperation
                        .newInsert(HealthDevContentProvider.CONTENT_URI_DATA)
                        .withValue(DataTable.COLUMN_DATA, tempVal).build();
                        .withValue() // TODO: add patient id
                        .withValue() // TODO: add sensor type);        
    }

// WARNING!! Provider operations (except query if you are using loaders) happen by default in the main thread!!

    getContentResolver().applyBatch(operations); 
}
网友评论