android數據庫 批量 事務 操作

先說說多線程 數據庫sqlite問題:


1:多線程 單例 SQLiteOpenHelper 可以同時讀和寫。

2.多線程 多個對象 SQLiteOpenHelper  不能同時讀寫(可以同時讀)。


3.多線程事務(1個讀寫過程就是一個事務,推薦以後都用事務的方式,對於大量的數據)


4.事務寫法:

1. 使用db.execSQL(sql)

  1. public void inertOrUpdateDateBatch(List<String> sqls) {     
  2.         SQLiteDatabase db = getWritableDatabase();     
  3.         db.beginTransaction();     
  4.         try {     
  5.             for (String sql : sqls) {     
  6.                 db.execSQL(sql);     
  7.             }     
  8.             // 設置事務標誌爲成功,當結束事務時就會提交事務     
  9.             db.setTransactionSuccessful();     
  10.         } catch (Exception e) {     
  11.             e.printStackTrace();     
  12.         } finally {     
  13.             // 結束事務     
  14.             db.endTransaction();     
  15.             db.close();     
  16.         }     
  17. }   

2. 使用db.insert("table_name", null, contentValues)


  1. db.beginTransaction(); // 手動設置開始事務  
  2.        for (ContentValues v : list) {  
  3.            db.insert("bus_line_station"null, v);  
  4.        }  
  5.        db.setTransactionSuccessful(); // 設置事務處理成功,不設置會自動回滾不提交  
  6.        db.endTransaction(); // 處理完成  
  7.   
  8.        db.close(); 

    3. 使用InsertHelper類

    這個類在API 17中已經被廢棄了,參考博客:http://www.outofwhatbox.com/blog/2010/12/android-using-databaseutils-inserthelper-for-faster-insertions-into-sqlite-database/

    1. InsertHelper ih = new InsertHelper(db, "bus_line_station");  
    2.         db.beginTransaction();  
    3.         final int directColumnIndex = ih.getColumnIndex("direct");  
    4.         final int lineNameColumnIndex = ih.getColumnIndex("line_name");  
    5.         final int snoColumnIndex = ih.getColumnIndex("sno");  
    6.         final int stationNameColumnIndex = ih.getColumnIndex("station_name");  
    7.         try {  
    8.             for (Station s : busLines) {  
    9.                 ih.prepareForInsert();  
    10.                 ih.bind(directColumnIndex, s.direct);  
    11.                 ih.bind(lineNameColumnIndex, s.lineName);  
    12.                 ih.bind(snoColumnIndex, s.sno);  
    13.                 ih.bind(stationNameColumnIndex, s.stationName);  
    14.                 ih.execute();  
    15.             }  
    16.             db.setTransactionSuccessful();  
    17.         } finally {  
    18.             ih.close();  
    19.             db.endTransaction();  
    20.             db.close();  
    21.         }  


    4. 使用SQLiteStatement

    查看InsertHelper時,官方文檔提示改類已經廢棄,請使用SQLiteStatement,鏈接:https://developer.android.com/reference/android/database/DatabaseUtils.InsertHelper.html 該方法類似於JDBC裏面的預編譯sql語句,使用方法如下:

    1. String sql = "insert into bus_line_station(direct,line_name,sno,station_name) values(?,?,?,?)";  
    2.         SQLiteStatement stat = db.compileStatement(sql);  
    3.         db.beginTransaction();  
    4.         for (Station line : busLines) {  
    5.             stat.bindLong(1, line.direct);  
    6.             stat.bindString(2, line.lineName);  
    7.             stat.bindLong(3, line.sno);  
    8.             stat.bindString(4, line.stationName);  
    9.             stat.executeInsert();  
    10.         }  
    11.         db.setTransactionSuccessful();  
    12.         db.endTransaction();  
    13.         db.close();  

    下圖是以上4中方法在批量插入1萬條數據消耗的時間

    運行結果

    可以發現第三種方法需要的時間最短,鑑於該類已經在API17中廢棄,所以第四種方法應該是最優的方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章