问题:
有的时候使用Android原数据库SQLite,通常我们在插入数据库是这样的:
private boolean addDataSet(SQLiteDatabase db, DataOneLogFileDecorator dataSet) {
ContentValues values = new ContentValues();
int countData = dataSet.getDataDecoratorsList().size();
Logger.d("count Data = "+countData);
try {
for (int i = 0; i < countData; i++) {
values.clear();
values.put(DataTable.ExitDataOri.F_fileName, dataSet.getLogFileName());
values.put(DataTable.ExitDataOri.F_fileHash, dataSet.getLogFileHash());
ExitDataDecorator exitDataDecorator = (ExitDataDecorator)dataSet.getDataDecoratorsListItem(i);
values.put(DataTable.ExitDataOri.F_pkg, exitDataDecorator.getPackageName());
values.put(DataTable.ExitDataOri.F_cls, exitDataDecorator.getClassName());
values.put(DataTable.ExitDataOri.F_isHome, exitDataDecorator.getIsHome());
values.put(DataTable.ExitDataOri.F_startTime, exitDataDecorator.getStartTime());
values.put(DataTable.ExitDataOri.F_exitTime, exitDataDecorator.getKeyValueExitTime());
//Logger.d("insert count = "+i);
db.insert(DataTable.ExitDataOri.TABLE_NAME, null, values);
}
} catch (Exception e) {
// TODO: handle exception
Logger.d("insert have a issue on file log");
e.printStackTrace();
} finally{
}
return true;
}
1.这种情况,如果数据过多,加入countData = 10000 , 那么db.insert()函数就会执行10000次, 默认这里就是 一万个 事务, 读写磁盘一万次。
2.这种情况也会出现一部分数据写进数据库了,而另外一部分还没写进数据库,数据库混乱了,这也系不是我们本意想要的。
这极大的浪费了时间,同时解决此混乱。我们完全可以 一次读写磁盘的操作把一万条数据全部写进磁盘; 要么全写进,要么全没写进数据库。从而优化APP性能 和 更健壮。
优化方式:
手动设置事务控制。
使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。
如:
private boolean addDataSet(SQLiteDatabase db, DataOneLogFileDecorator dataSet) {
ContentValues values = new ContentValues();
int countData = dataSet.getDataDecoratorsList().size();
Logger.d("count Data = "+countData);
try {
db.beginTransaction();// start transaction
for (int i = 0; i < countData; i++) {
values.clear();
values.put(DataTable.LaunchDataOri.F_fileName, dataSet.getLogFileName());
values.put(DataTable.LaunchDataOri.F_fileHash, dataSet.getLogFileHash());
LaunchDataDecorator dataDecorator = dataSet.getDataDecoratorsListItem(i);
values.put(DataTable.LaunchDataOri.F_pkg, dataDecorator.getPackageName());
values.put(DataTable.LaunchDataOri.F_cls, dataDecorator.getClassName());
values.put(DataTable.LaunchDataOri.F_firstBoot, dataDecorator.isFirstBoot());
values.put(DataTable.LaunchDataOri.F_startTimeStamp, dataDecorator.getStartTimePoint());
values.put(DataTable.LaunchDataOri.F_bindAppTime, dataDecorator.getKeyValueBindAppTime());
values.put(DataTable.LaunchDataOri.F_input, dataDecorator.getKeyValueInputTimePoint());
values.put(DataTable.LaunchDataOri.F_onCreate, dataDecorator.getKeyValueOnCreateTime());
values.put(DataTable.LaunchDataOri.F_onStart, dataDecorator.getKeyValueOnStartTime());
values.put(DataTable.LaunchDataOri.F_onResume, dataDecorator.getKeyValueOnResumeTime());
values.put(DataTable.LaunchDataOri.F_responseTime, dataDecorator.getKeyValueResponseTime());
values.put(DataTable.LaunchDataOri.F_animationTime, dataDecorator.getKeyValueAnimationTime());
values.put(DataTable.LaunchDataOri.F_animationDone, dataDecorator.getKeyValueAnimationDoneTimePoint());
//Logger.d("insert count = "+i);
db.insert(DataTable.LaunchDataOri.TABLE_NAME, null, values);
}
db.setTransactionSuccessful();// set transaction flag
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally{
values.clear();
db.endTransaction();// if success commit the transaction, if no success roll back the transaction
}
return true;
}
后记:
增删改查,类似于这样的事物均可以这样优化。