使用事务的 Android SQLite 批量插入

mho*_*gan 1 sqlite android android-asynctask android-sqlite

我有一个插入语句,我的应用程序需要大约 25 秒才能插入 ~1000 行。我试图用它Transactions来加快我的处理时间,但我在实现它时遇到了麻烦。

下面是我的方法inserting在我的DatabaseHandler

public boolean insertQuestions(String gid, String qid, String qname) {
    SQLiteDatabase db = this.getWritableDatabase();
    db.beginTransaction();
    try {
        ContentValues contentValues = new ContentValues();
        contentValues.put(KEY_GID, gid);
        contentValues.put(KEY_QID, qid);
        contentValues.put(KEY_QNAME, qname);

        long result = db.insert(TABLE_QUESTIONS, null, contentValues);
        db.setTransactionSuccessful();
        if (result == -1) {
            db.close();
            return false;
        } else {
            db.close();
            return true;
        }
    } finally {
        db.endTransaction(); //Error is here
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试运行上述方法时出现以下错误:

08-28 15:50:40.961  20539-20539/? E/AndroidRuntime? FATAL EXCEPTION: main
Process: com.murrion.navigationdrawer, PID: 20539
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /storage/emulated/0/testapp3.db
        at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
        at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:522)
        at com.murrion.navigationdrawer.utils.DatabaseHandler.insertQuestions(DatabaseHandler.java:197)
Run Code Online (Sandbox Code Playgroud)

该语句正在我的 Activity 中的 Asynctask 方法中运行。

pet*_*tey 5

您在结束事务之前已经关闭了数据库,而是在结束后关闭它。

public boolean insertQuestions(String gid, String qid, String qname) {
    SQLiteDatabase db = this.getWritableDatabase();

    boolean wasSuccess = true;
    try {
        db.beginTransaction();
        ContentValues contentValues = new ContentValues();
        contentValues.put(KEY_GID, gid);
        contentValues.put(KEY_QID, qid);
        contentValues.put(KEY_QNAME, qname);

        long result = db.insert(TABLE_QUESTIONS, null, contentValues);

        if (result == -1) {
            wasSuccess = false;
        } else {
            db.setTransactionSuccessful();
        }
    } finally {
        db.endTransaction(); 
        db.close();
    }
    return wasSuccess;
}
Run Code Online (Sandbox Code Playgroud)

  • @Mark117 如果你真的想加速你的插入,ContentValues + db.insert + transactions 不会像准备好的语句那样有帮助。我的回答只能解决您的崩溃问题。请参阅此答案(Section Inser Valuess),因为已经(惊人地)回答了加速插入 http://stackoverflow.com/a/29797229/794088(如果您发现任何有用的东西,请不要忘记投票 =) (3认同)
  • @Mark117 你真的应该每行插入一个。并尝试**指示**您的领域! (2认同)