數據庫是Android的一種數據存儲方式,但是SQLiteOpenHelper是抽象類,我們需要自己寫一個實現類來實現onCreate方法和onUpgrade方法,這兩個方法分別會在數據庫創建和更新的時候調用到。
getWritableDatabase方法和getReadableDatabase方法分別返回一個可寫的數據庫和一個可讀的數據庫。如果發現數據庫不存在,就會調用onCreate方法創建一個數據庫,如果版本號升級就調用onUpgrade升級數據庫。創建的數據庫在/data/data/xxx(package)/xxx.dbSQLiteOpenHelper:如下是一個SQLiteOpenHelper的實現類,創建的時候生成兩張表,更新的時候生成一張表。
package com.example.sql.sql;import android.content.Context;import android.database.DatabaseErrorHandler;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import android.util.Log;/** * Created by hongbin on 17-3-6. */public class MyOpenHelper extends SQLiteOpenHelper { //數據庫版本號 PRivate static final int DATABASE_VERSION = 1; //數據庫名 private static final String DATABASE_NAME = "Test.db"; //數據庫表名 public static final String[] TABLE_NAMES = {"TABLE_0", "TABLE_1", "TABLE_2"}; public MyOpenHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); Log.d("dbLog","MyOpenHelper"); } public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) { super(context, name, factory, version, errorHandler); } @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { Log.d("dbLog","onCreate"); //創建表一語句 StringBuffer sBuffer0 = new StringBuffer(); sBuffer0.append("CREATE TABLE [" + TABLE_NAMES[0] + "] ("); sBuffer0.append("[_id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "); sBuffer0.append("[name] TEXT,"); sBuffer0.append("[age] INTEGER,"); //創建表二語句 StringBuffer sBuffer1 = new StringBuffer(); sBuffer1.append("CREATE TABLE [" + TABLE_NAMES[1] + "] ("); sBuffer1.append("[_id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "); sBuffer1.append("[name] TEXT,"); sBuffer1.append("[age] INTEGER,"); // 執行SQL語句 sqLiteDatabase.execSQL(sBuffer0.toString()); sqLiteDatabase.execSQL(sBuffer1.toString()); } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { Log.d("dbLog","onUpgrade"); StringBuffer sBuffer3 = new StringBuffer(); sBuffer3.append("CREATE TABLE [" + TABLE_NAMES[2] + "] ("); sBuffer3.append("[_id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "); sBuffer3.append("[name] TEXT,"); sBuffer3.append("[age] INTEGER,"); sqLiteDatabase.execSQL(sBuffer3.toString()); }}Activity:public class MainActivity extends AppCompatActivity { private MyOpenHelper myOpenHelper; private SQLiteDatabase db; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myOpenHelper = new MyOpenHelper(this); //獲取一個可寫的數據庫,如果不存在就創建,如果版本更新就升級 Log.d("dbLog","getWritableDatabase"); db = myOpenHelper.getWritableDatabase(); }}Log:
從以上日志可以發現數據庫創建和升級的流程。
創建之后對數據庫的增刪改查可以用execSQL來執行SQL語句,也可以分別用insert、delete、update、query來執行。
批量處理
在數據庫的使用過程中,常常需要一次性操作大量的數據,如果用循環一次一次的操作肯定是很消耗事件的,這時候我們就需要用到開啟一個事務來做批處理。做個實驗驗證一下一次性插入5000條數據的時間消耗。
public void onClick(View view) { int i = 0; String sql = "INSERT INTO %s VALUES (null, %s, %s)"; try { Log.d("dbLog","非批處理"); Log.d("dbLog","start"); while(i < 5000){ db.execSQL(String.format(sql,MyOpenHelper.TABLE_NAMES[0],i,i)); i++; } } catch (Exception e) { e.printStackTrace(); } finally { Log.d("dbLog","finish"); Log.d("dbLog","插入" + i + "條數據"); } }//----------------------------------我是一條分割線------------------------------------//
public void onClick(View view) { int i = 0; String sql = "INSERT INTO %s VALUES (null, %s, %s)"; try { Log.d("dbLog","批處理"); Log.d("dbLog","start"); db.beginTransaction(); while(i < 5000){ db.execSQL(String.format(sql,MyOpenHelper.TABLE_NAMES[1],i,i)); i++; } db.setTransactionSuccessful(); } catch (Exception e) { e.printStackTrace(); } finally { db.endTransaction(); Log.d("dbLog","finish"); Log.d("dbLog","插入" + i + "條數據"); } }不采用事務來執行人5000次的插入操作,從日志中可以看到,start到finish的時間差是34.53秒。
而采用事務來執行人5000次的插入操作,從日志中可以看到,start到finish的時間差是1.16秒。
這里的性能差別真是太大啦。
我們都知道磁盤的讀寫是很耗時的,簡單來說,每一次的插入都是一個事務,執行5000插入操作相當于執行了5000次的磁盤讀寫,而采用事務包裝的話就把5000次的插入操作當作一次事務,也就是一次磁盤讀寫,時間上當然相差很大啦。
數據庫的知識太多了,這里就簡單描述一下Android SQLite最基礎的操作。
新聞熱點
疑難解答