Java 如何在Sqlite Android中执行从文件读取的大量Insert查询

Java 如何在Sqlite Android中执行从文件读取的大量Insert查询,java,android,database,sqlite,insert,Java,Android,Database,Sqlite,Insert,目前,我有一个要求,即我需要读取大量的insert查询,大约有100000个查询写在一个.sql文件中。我需要从SdCard读取此文件,并在我的应用程序中更新本地sqlite数据库 我正在使用以下代码并成功更新: 同时,我担心性能问题和应用程序挂起的风险,因为这将像是一个较重的sql文件任务。我需要改变我现在使用的方法吗?是否有更好的Sqlite数据库实现来执行此任务而不存在风险 /* Iterate through lines (assuming each insert has its own

目前,我有一个要求,即我需要读取大量的insert查询,大约有100000个查询写在一个.sql文件中。我需要从SdCard读取此文件,并在我的应用程序中更新本地sqlite数据库

我正在使用以下代码并成功更新:

同时,我担心性能问题和应用程序挂起的风险,因为这将像是一个较重的sql文件任务。我需要改变我现在使用的方法吗?是否有更好的Sqlite数据库实现来执行此任务而不存在风险

/* Iterate through lines (assuming each insert has its own line 
   and theres no other stuff) */
while (insertReader.ready()) {
    String insertStmt = insertReader.readLine();
    db.execSQL(insertStmt);

    bytesRead += insertStmt.length();
    int percent = (int) (bytesRead * 100 / totalBytes);

    // To show the updating data progress
    if (previousPercent < percent) {
        System.out.println(percent);
        previousPercent = percent;
        Bundle b = new Bundle();
        b.putInt(AppConstants.KEY_PROGRESS_PERCENT, percent);
        Message msg = new Message();
        msg.setData(b);
        errorViewhandler.sendMessage(msg);
    }
    result++;
}
insertReader.close();
/*迭代行(假设每个插入都有自己的行
(没有其他东西)*/
while(insertReader.ready()){
字符串insertStmt=insertReader.readLine();
execSQL(insertStmt);
bytesRead+=insertStmt.length();
整数百分比=(整数)(字节读取*100/总字节);
//显示更新数据进度的步骤
如果(以前的百分比<百分比){
系统输出打印项次(百分比);
以前的百分比=百分比;
Bundle b=新Bundle();
b、 putInt(AppConstants.KEY\u进度百分比,百分比);
Message msg=新消息();
msg.setData(b);
errorViewhandler.sendMessage(消息);
}
结果++;
}
insertReader.close();

我发现将大量数据导入数据库的最快方法是在数据库上使用
applyBatch()

以下是我从一个项目中缩减的一个示例:

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

while (condition) {
    ContentProviderOperation.Builder b = ContentProviderOperation.newInsert(YourOwnContentProvider.CONTENT_URI);
    b.withYieldAllowed(true);

    b.withValue(COLUMN_ONE, 1);
    b.withValue(COLUMN_TWO, 2);

    cpoList.add(b.build());

    // You could check here, whether you have a lot of items in your list already. If you do, you should send them to applyBatch already.
}

if(cpoList.size() > 0) {
    context.get().getContentResolver().applyBatch(YourOwnContentProvider.AUTHORITY, cpoList);
}
ArrayList cpoList=new ArrayList();
while(条件){
ContentProviderOperation.Builder b=ContentProviderOperation.newInsert(YourOwnContentProvider.CONTENT\u URI);
b、 withYieldAllowed(true);
b、 withValue(第一列,1);
b、 withValue(第2列,2);
cpoList.add(b.build());
//你可以在这里检查,你的列表中是否已经有很多项目。如果你有,你应该已经将它们发送到applyBatch。
}
如果(cpoList.size()>0){
context.get().getContentResolver().applyBatch(YourOwnContentProvider.AUTHORITY,cpoList);
}
作为applyBatch的示例实现:

@Override
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) {
    ContentProviderResult[] result = new ContentProviderResult[operations.size()];
    int i = 0;
    SQLiteDatabase sqlDB = db.getWritableDatabase();

    sqlDB.beginTransaction();

    try {
        for (ContentProviderOperation operation : operations) {
            result[i++] = operation.apply(this, result, i);
        }

        sqlDB.setTransactionSuccessful();
    } catch (OperationApplicationException e) {
        // Deal with exception
    } finally {
        sqlDB.endTransaction();
    }

    return result;
}
@覆盖
public ContentProviderResult[]applyBatch(ArrayList操作){
ContentProviderResult[]结果=新的ContentProviderResult[operations.size()];
int i=0;
SQLiteDatabase sqlDB=db.getWritableDatabase();
sqlDB.beginTransaction();
试一试{
for(ContentProviderOperation操作:操作){
result[i++]=operation.apply(this,result,i);
}
sqlDB.setTransactionSuccessful();
}捕获(操作应用程序异常e){
//处理例外
}最后{
sqlDB.endTransaction();
}
返回结果;
}

似乎很有希望,但我不清楚EPGContentprovider及其实现。我是否能够从SdCard中的文件中读取插入查询。该ContentProvider实际上是我粘贴的代码中的ContentProvider。在这种情况下,您需要创建自己的内容提供商。是的,您可以从任何源添加插入新行。所以这个文件也可以用。您只需要在while循环中逐个解析文件。