SQLite 一個非常流行的嵌入式數據庫,它支持 SQL 語言,並且只利用很少的內存就有很好的性能。此外它還是開源的,任何人都可以使用它。許多開源項目((Mozilla, PHP, Python)都使用了 SQLite.
SQLite 由以下幾個組件組成:SQL 編譯器、內核、后端以及附件。SQLite 通過利用虛擬機和虛擬數據庫引擎(VDBE),使調試、修改和擴展 SQLite 的內核變得更加方便。今天我們就開始Sqlite數據庫的學習:
目錄導航
Sqlite數據庫的簡單說明
SQLite 和其他數據庫最大的不同就是對數據類型的支持,創建一個表時,可以在 CREATE TABLE 語句中指定某列的數據類型,但是你可以把任何數據類型放入任何列中。當某個值插入數據庫時,SQLite 將檢查它的類型。如果該類型與關聯的列不匹配,則 SQLite 會嘗試將該值轉換成該列的類型。如果不能轉換,則該值將作為其本身具有的類型存儲。比如可以把一個字符串(String)放入 INTEGER 列
此外,SQLite 不支持一些標准的 SQL 功能,特別是外鍵約束(FOREIGN KEY constrains),嵌套 transcaction 和 RIGHT OUTER JOIN 和 FULL OUTER JOIN, 還有一些 ALTER TABLE 功能。除了上述功能外,SQLite 是一個完整的 SQL 系統,擁有完整的觸發器,交易等等。Android 為了讓我們能夠更加方便地管理數據庫,專門提供了一個SQLiteOpenHelper 幫助類,借助這個類就可以非常簡單地對數據庫進行創建和升級。
由於 JDBC 會消耗太多的系統資源,所以 JDBC 對於手機這種內存受限設備來說並不合適。因此,Android 提供了一些新的 API 來使用 SQLite 數據庫。在接下來的實例中,我們會提到。
Sqlite數據庫的使用步驟
- new一個繼承於SQLiteOpenHelper類的對象:dbHelper = new MyDatabaseHelper(this, "User.db", null, newVersion),User.db就是數據庫的名字。
- 調用getWritableDatabase()或者getReadableDatabase()方法創建或者得到數據庫實例,這里onCreate()方法得到執行,可以在此建表
- 調用getWritableDatabase()或者getReadableDatabase()可以得到數據庫實例
- 添加: db.insert(String table, String nullColumnHack, ContentValues values) 。insert方法的第二個參數用於在未指定添加數據的情況下給某些可為空的列自動賦值NULL,第三個參數是一個ContentValues 對象,它提供了一系列的put()方法重載,用於向ContentValues 中添加數據,只需要將表中的每個列名以及相應的待添加數據傳入即可。
- 更新:db.update(Stringtable,ContentValues對象,String whereClause, String[] whereArgs);第三、第四個參數用於去約束更新某一行或某幾行中的數據,不指定的話默認就是更新所有行。
- 查詢:db.query(String[] columns, String selection,String[] selectionArgs, String groupBy, String having, String orderBy)
- 刪除:db.delete(String table, String whereClause, String[] whereArgs)
Sqlite數據庫項目代碼
/** * Created by Linux on 2016/3/8. */ public class MyDatabaseHelper extends SQLiteOpenHelper { private final static String TAG = "SqliteTest"; private Context mContext; public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); Log.i(TAG, "my database helper constructor"); mContext = context; } public static final String CREATE_USER = "create table user (" + "userid integer primary key autoincrement, " + "username text, " + "password text)"; public static final String CREATE_BOOK = "create table book (" + "bookid integer primary key autoincrement, " + "bookname text, " + "bookpage integer)"; @Override public void onCreate(SQLiteDatabase db) { Log.i(TAG, "my database helper create"); db.execSQL(CREATE_USER); Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show(); } // 升級 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.i(TAG, "oldVersion: " + oldVersion + ", newVersion: " + newVersion); switch (newVersion) { case 2: db.execSQL(CREATE_BOOK); case 1: Log.i(TAG, "Hello world."); default: } } }
二、 在MainActivity中的onCreate方法中初始化一些信息:
private final static String TAG = "SqliteTest"; private MyDatabaseHelper dbHelper; private static int newVersion = 1; @Override protected void onCreate(Bundle savedInstanceState) { Log.i(TAG, "main create"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); dbHelper = new MyDatabaseHelper(this, "User.db", null, newVersion); }
三、 創建Sqlite數據庫:
// 創建數據庫 public void createTable(View view) { Log.i(TAG, "main create table"); dbHelper.getWritableDatabase(); }
// 插入數據 public void insertData(View view) { SQLiteDatabase db = dbHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("username", "Huhx"); values.put("password", "123456"); db.insert("user", null, values); values.clear(); // 開始組裝第二條數據 values.put("username", "Linux"); values.put("password", "456789"); db.insert("user", null, values);// 插入第二條數據 }
// 查詢數據 public void queryData(View view) { StringBuffer stringBuffer = new StringBuffer(); SQLiteDatabase db = dbHelper.getWritableDatabase(); Cursor cursor = db.query("user", null, null, null, null, null, null); if (cursor.moveToFirst()) { do { // 遍歷Cursor對象,取出數據並打印 String username = cursor.getString(cursor.getColumnIndex("username")); String password = cursor.getString(2); //index從0開始的,password位於第三 stringBuffer.append("username: " + username + ", password: " + password + "\n"); } while (cursor.moveToNext()); } cursor.close(); Log.i(TAG, stringBuffer.toString()); }
六、 數據庫中更新數據:
// 更新數據 public void updateData(View view) { SQLiteDatabase db = dbHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("username", "胡紅翔"); db.update("user", values, "username = ?", new String[]{"Huhx"}); }
// 刪除數據 public void deleteData(View view) { SQLiteDatabase db = dbHelper.getWritableDatabase(); db.delete("user", "username = ?", new String[]{"Linux"}); }
八、 數據庫中批量插入數據:
// 批量插入數據 public void buttleInsertData(View view) { // 不支持批量插入數據? }
// 數據庫事務 public void transcation(View view) { SQLiteDatabase db = dbHelper.getWritableDatabase(); db.beginTransaction(); // 開啟事務 try { db.delete("user", null, null); if (true) { // 在這里手動拋出一個異常,讓事務失敗 throw new NullPointerException(); } ContentValues values = new ContentValues(); values.put("username", "liuli"); values.put("password", "ch29"); db.insert("user", null, values); db.setTransactionSuccessful(); // 事務已經執行成功 } catch (Exception e) { e.printStackTrace(); } finally { db.endTransaction(); // 結束事務 } }
十、 數據庫的升級:
// 升級數據庫 public void upgrade(View view) { dbHelper = new MyDatabaseHelper(this, "User.db", null, ++newVersion); }
sqlite數據庫其他使用
一、 數據庫的高級特性
創建視圖:
視圖是虛擬表,它的內容都派生自其它表的查詢結果。雖然它看起來像基本表,但是它不是,因為基本表的內容是持久的,而視圖的內容是使用時動態產生的。create view 表名 as 定義
創建索引:
索引是一種用來在某種條件下加速查詢的結構。通常情況下,第一次創建數據庫時創建了表和索引。如果你不需要改變表的 schema,不需要刪除表和索引 . 刪除表和索引,需要使用 execSQL() 方法調用 DROP INDEX 和 DROP TABLE 語句。create index 索引名 on 表名(列名)
創建觸發器:
觸發器的作用是當具體的表發生特定的數據事件時,執行對應的操作。
create trigger 觸發器名 [before|after] [insert|delete|update|update of columns] on 表名 action
二、 導出查看數據庫文件
在android中,為某個應用程序創建的數據庫,只有它可以訪問,其它應用程序是不能訪問的,數據庫位於Android設備/data/data/package_name/databases文件夾中。

三、 命令行查看sqlite數據庫:真機測試沒有root,不能進入數據庫。
啟動模擬器,命令行cd 到android-sdk-windows\platform-tools目錄 adb shell //進入模擬器 cd /data/data/yourpackagename/ //進入到軟件安裝目錄 cd databases //進入到數據庫目錄 ls //查看現有的數據庫,如果創建過應該有個XXXX.db sqlite3 XXXX.db //用sqlite3工具打開數據庫 //下面是sqlite3命令 sqlite> .tables //查看數據庫里面的表 本例應該能看到表YYYY sqlite> .schema YYYY //查看表結構 sqlite> select * from YYYY; //查詢表
四、 查看數據庫,使用SQlite Database Browser:

sqlite數據庫的實現原理
一、 數據庫的創建:部分重要代碼
db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ? Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0, mFactory, mErrorHandler);//打開或者創建數據庫
二、 數據庫的更新:部分重要代碼
final int version = db.getVersion(); //新版本與當前版本不一致 if (version != mNewVersion) { if (db.isReadOnly()) { throw new SQLiteException("Can't upgrade read-only database from version " + db.getVersion() + " to " + mNewVersion + ": " + mName); } db.beginTransaction(); try { if (version == 0) { onCreate(db); } else { // 新版本號小於當前版本,則執行onDowngrade方法 if (version > mNewVersion) { onDowngrade(db, version, mNewVersion); } else { // 新版本號大於當前版本,則執行onUpgrade方法 onUpgrade(db, version, mNewVersion); } } db.setVersion(mNewVersion); db.setTransactionSuccessful(); } finally { db.endTransaction(); } }
三、 數據庫更新:onUpgrade方法
version的增大, onUpgrade方法並沒有因此而立即得到執行。源碼中,dbHelper.getWritableDatabase()調用才會去比較版本,onUpgrade方法在此執行。
1 db.beginTransaction(); 2 try { 3 if (version == 0) { 4 onCreate(db); 5 } else { 6 if (version > mNewVersion) { 7 onDowngrade(db, version, mNewVersion); 8 } else { 9 onUpgrade(db, version, mNewVersion); 10 } 11 } 12 db.setVersion(mNewVersion); 13 db.setTransactionSuccessful(); 14 } finally { 15 db.endTransaction(); 16 }

