我无法让SQLite支持围绕多个插入的开始/结束事务。
Multiples INSERTs : 2500ms
Using BEGIN and COMMIT : 90ms
Using SELECT and UNION : 40ms
所以我看着使用begin和commit。我做错了什么?
// 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());
好的,我做了一些研究,似乎“不支持以分号分隔的多个语句。”我可以做些什么来插入和保留插入顺序?
答案 0 :(得分:2)
启动事务,在单独的execSQL()
调用上执行每个INSERT,然后提交事务。
您无需在同一execSQL()
次呼叫中将INSERT群集在一起。
答案 1 :(得分:2)
使用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();
}
答案 2 :(得分:0)
查看beginTransaction()上的官方Android文档。用循环执行单独的execSQL()调用替换“...”部分 - 不需要在一个缓冲区中一起截断语句。
此外,使用准备好的声明通常也是值得的。准备语句,开始事务,循环每个项目绑定并执行语句,最后提交。
答案 3 :(得分:0)
这可能有所帮助:
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();
}