在项目编写中,sql语句经常用到,写的时候也很随意,完成功能没问题,很少在sql语句上出现性能的问题,因此也没有考虑这方面的优化,今天看了别人写的代码对比我写的,确实有很多不足之处。 经常出现以下代码:
//伪代码
public void save(List<Bean> list){
String sql = "insert into table values(?,?)";
for(Bean b:list){
//这里new 出了好多String 数组啊。
db.exeSQL(sql,new String[]{b.name,b.age})
}
}
对于上面代码,有的人没使用占位符 “?” ,而是直接用字符串拼接的形式 拼写sql,还放在了for循环里。这种方式就更不应该了。如果确实需要字符串的操作,建议使用stringBuilder来处理
这里贴上性能更好的代码实现:
// 伪代码
public void save(List<Bean> list){
SQLiteStatement stmt = db.compileStatement("insert into table values(?,?)");
int i = 0;
for(Bean b :list){
stmt.bindString(1,b.name);
stmt.bindString(2,b.age);
stmt.executeInsert();
}
// 数据库关闭等其他操作
}
这种写法对比上面有以下优点:
1 只需要编译一次sql语句。而不是上面的for循环里的次数.
2 不用再创建好多个 String 数组
关于事务:
上面 插入操作并没有显示的创建任何事务,但是 数据库会为每个插入操作创建一个事务,并在每次插入后立即提交。、
而显示的创建事务 有2个特性:
1:原子提交
2:性能更好
原子提交意味着 数据库的操作要么都完成 要么 都失败。这里如果把插入操作当成一个事务, 在时间消耗上显然比上面更节省。
public void save (List<Bean> list){
try{
//开启事务
db.beginTransaction();
SQLiteStatement stmt = db.compileStatement("insert into table values(?,?)");
int i = 0;
for(Bean b :list){
stmt.bindString(1,b.name);
stmt.bindString(2,b.age);
stmt.executeInsert();
}
//删除这一句代码 将不会提交
db.setTransactionSuccessful();
}catch(Exception e){
e.print...
}finally{
//必须在finally块关闭事务
db.endTransaction();
}
}