Android sqlite 插入 500 行不起作用或保留插入顺序



我无法让SQLite支持围绕多个插入的开始/结束事务。

 Multiples INSERTs : 2500ms
 Using BEGIN and COMMIT : 90ms
 Using SELECT and UNION : 40ms

所以我使用开始和提交进行了查找。我做错了什么?

  // pseudocode: 
  ArrayList<Integer> iList = new ArrayList<Integer>();
    for (int i = 1; i <= 500; i++) {
      iList.add(i);
    }
  Collections.shuffle(iList);
  StringBuilder sb = new StringBuilder("begin transaction;");
  for (Integer i: iList) {
    sb.append("insert into "t_order" (qid) values(");
    sb.append(i);
    sb.append(");");
  }
  sb.append(" end transaction;");
  // from docs: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#execSQL(java.lang.String)
  // Execute a single SQL statement that is NOT a SELECT or any other SQL statement that returns data.
  m_db.execSQL(sb.toString());

好的,我做了更多的研究,似乎"不支持用分号分隔的多个语句"。 我该怎么做才能插入和保留插入顺序?

启动一个事务,在单独的execSQL()调用上执行每个 INSERT,然后提交事务。

无需在同一execSQL()调用中将 INSERT 聚集在一起。

使用 SQLiteDatabase.beginTransaction()SQLiteDatabase.endTransaction() 方法,并在它们之间发出 execSQL 调用。使用ContentValues结构而不是执行自己的字符串连接也是更好的样式:

ContentValues cv = new ContenValues();
m_db.beginTransaction();
try {
    for (Integer i: iList) {
        cv.put("qid", i);
        m_db.insert("t_order", null, cv);
    }
    m_db.setTransactionSuccessful();
} finally {
    m_db.endTransaction();
}

看看 beginTransaction() 上的官方 Android 文档。将"..."部分,带有执行单独 execSQL() 调用的循环 -- 无需在一个缓冲区中一起截断语句。

此外,使用准备好的语句通常是值得的。准备语句,开始事务,循环每个项绑定并执行语句,最后提交。

这可能会有所帮助:

public void putAll(Context context, LinkedList<HANDLEDOBJECT> objects) {
    if (objects.size() < 1 || objects.get(0) == null)
        return;
    Log.i("Database", "Starting to insert objects to " + getTableName());
    List<String> insertCommands = new ArrayList<String>();
    int t = 0;
    while (t < objects.size()) {
        int k = 0;
        StringBuilder sb = new StringBuilder();
        sb.append("INSERT OR REPLACE INTO ").append(getTableName())
                .append("('k', 'v') ");
        for (t = t + 0; t < objects.size() && k < 450; t++) {
            k++;
            if (t % 450 != 0)
                sb.append("UNION ");
            sb.append("SELECT " + objects.get(t).getId())
                    .append(" AS k, ")
                    .append("'"
                            + GsonSerializer.getInstance().toJson(
                                    objects.get(t), getHandledObjectType())
                            + "'").append(" AS v ");
        }
        insertCommands.add(sb.toString());
    }
    for (String insertCommand : insertCommands)
        SQLiteClient.getConnetion(context).execSQL(insertCommand);
    Log.i("Database", "Successfully inserted " + t + " objects to "
            + getTableName() + "!!!");
    System.gc();
}

最新更新