Android设备上的批量插入
我想在下次升级时将大约700条记录批量插入Android数据库。最有效的方法是什么?从各种帖子中,我知道如果我使用Android设备上的批量插入,android,sqlite,bulkinsert,Android,Sqlite,Bulkinsert,我想在下次升级时将大约700条记录批量插入Android数据库。最有效的方法是什么?从各种帖子中,我知道如果我使用Insert语句,我应该将它们包装在事务中。还有一个关于使用你自己的数据库的问题,但我需要这些数据进入我的应用程序的标准Android数据库。请注意,每个设备只能执行一次 一些想法: 将一组SQL语句放在一个文件中,一次读取一行,然后执行SQL 将数据放在CSV文件、JSON、YAML、XML或其他文件中。一次读一行,然后执行db.insert() 了解如何导入和单个导入整个文件 创
Insert
语句,我应该将它们包装在事务中。还有一个关于使用你自己的数据库的问题,但我需要这些数据进入我的应用程序的标准Android数据库。请注意,每个设备只能执行一次
一些想法:
db.insert()
最好的办法是什么?是否有其他加载数据的方法?3和4都有可能吗?我认为没有任何可行的方法来完成你名单上的3或4 在其他解决方案中,您列出了两个数据文件包含直接SQL的解决方案,另一个解决方案的数据格式为非SQL格式 这三种方法都可以很好地工作,但后一种建议是从格式化文件中获取数据并自己构建SQL,这似乎是最干净的。如果在以后添加了真正的批处理更新功能,那么您的数据文件仍然可用,或者至少可以轻松地处理成可用的形式。此外,数据文件的创建更简单,更不容易出错。最后,拥有“原始”数据将允许导入其他数据存储格式
在任何情况下,您都应该(如您所提到的)将插入组包装到事务中,以避免创建每行事务日志。我发现,对于批量插入,类(显然很少使用)比使用
SQLiteDatabase.insert快几倍
另外两种优化也有助于提高我的应用程序的性能,尽管它们可能并不适用于所有情况:
- 不要
bind
空值或null
- 如果您可以确定这样做是安全的,那么暂时关闭数据库的内部锁定也有助于提高性能
通常,每次使用db.insert()
时,SQLite都会创建一个事务(并在文件系统中生成日志文件),这会降低速度
如果使用db.beginTransaction()
和db.endTransaction()
SQLite只在文件系统上创建一个日志文件,然后同时提交所有插入,大大加快了速度
下面是来自以下站点的一些伪代码:
如果由于意外错误或其他原因希望中止事务,只需db.endTransaction()
,而不首先将事务设置为成功(db.setTransactionSuccessful()
)
另一个有用的方法是使用<代码> dB.InTraceNo.(/)代码>(返回<代码> Trase< /Cord>或<代码> false <代码>),以确定当前是否处于事务的中间。
嗯,我的解决方案有点奇怪,但效果很好。。。
我编译了大量数据并一次性插入(批量插入?)
我使用db.execSQL(Query)
命令,用以下语句构建“Query”
INSERT INTO yourtable SELECT * FROM (
SELECT 'data1','data2'.... UNION
SELECT 'data1','data2'.... UNION
SELECT 'data1','data2'.... UNION
.
.
.
SELECT 'data1','data2'....
)
唯一的问题是查询的构建可能有点混乱。
我希望它能有所帮助下面的示例将非常有效
String sql = "INSERT INTO " + DatabaseHelper.TABLE_PRODUCT_LIST
+ " VALUES (?,?,?,?,?,?,?,?,?);";
SQLiteDatabase db = this.getWritableDatabase();
SQLiteStatement statement = db.compileStatement(sql);
db.beginTransaction();
for(int idx=0; idx < Produc_List.size(); idx++) {
statement.clearBindings();
statement.bindLong(1, Produc_List.get(idx).getProduct_id());
statement.bindLong(2, Produc_List.get(idx).getCategory_id());
statement.bindString(3, Produc_List.get(idx).getName());
// statement.bindString(4, Produc_List.get(idx).getBrand());
statement.bindString(5, Produc_List.get(idx).getPrice());
//statement.bindString(6, Produc_List.get(idx).getDiscPrice());
statement.bindString(7, Produc_List.get(idx).getImage());
statement.bindLong(8, Produc_List.get(idx).getLanguage_id());
statement.bindLong(9, Produc_List.get(idx).getPl_rank());
statement.execute();
}
db.setTransactionSuccessful();
db.endTransaction();
String sql=“插入”+DatabaseHelper.TABLE\u产品列表
+“值(?,,,,,,,,,,,,,,;”;
SQLiteDatabase db=this.getWritableDatabase();
SQLiteStatement=db.compileStatement(sql);
db.beginTransaction();
对于(int idx=0;idx
很酷。多么有创意的解决方案啊。听起来会很快。是吗?使用StringBuilder类速度会很快。@Andrew Prat。。。工会的最高限额是多少。对于我来说,通过这个联合操作,我可以在一个insert语句中插入500条记录。如果我想在一条语句中插入5000条记录。有可能吗?如果是,那么怎么做?更多代码参考:试图修复db.endTransaction()
中的打字错误,但它太小了。这正是我要找的。我导入了大约50个包含数千条记录的csv文件,当从csv中读取一行并将其插入数据库时,需要几个小时才能完成。使用db.beginTransaction()只需几秒钟!谢谢回滚到r4。r5和r6是不必要的-打字错误已经修复。@AndrewMedico是的,根据链接的示例和文档,必须调用db.setTransactionSuccessful()
db.endTransaction()
已在finally块中调用。谢谢!这一优化增加了大量的
String sql = "INSERT INTO " + DatabaseHelper.TABLE_PRODUCT_LIST
+ " VALUES (?,?,?,?,?,?,?,?,?);";
SQLiteDatabase db = this.getWritableDatabase();
SQLiteStatement statement = db.compileStatement(sql);
db.beginTransaction();
for(int idx=0; idx < Produc_List.size(); idx++) {
statement.clearBindings();
statement.bindLong(1, Produc_List.get(idx).getProduct_id());
statement.bindLong(2, Produc_List.get(idx).getCategory_id());
statement.bindString(3, Produc_List.get(idx).getName());
// statement.bindString(4, Produc_List.get(idx).getBrand());
statement.bindString(5, Produc_List.get(idx).getPrice());
//statement.bindString(6, Produc_List.get(idx).getDiscPrice());
statement.bindString(7, Produc_List.get(idx).getImage());
statement.bindLong(8, Produc_List.get(idx).getLanguage_id());
statement.bindLong(9, Produc_List.get(idx).getPl_rank());
statement.execute();
}
db.setTransactionSuccessful();
db.endTransaction();