標籤:win ber generate 資料庫更新 結合 addclass jpg 資料庫檔案 同比
Android開發之利用SQLite進行資料存放區
- Android開發之利用SQLite進行資料存放區
- SQLite資料庫簡單介紹
- Android中怎樣使用SQLite
- 1 建立SQLiteOpenHelper對象並建立表
- 2 通過SQLiteDatabase對象運行增刪改查操作
- 3 SQLiteDatabase之事務transaction
1.SQLite資料庫簡單介紹
SQLite。是一款輕型的資料庫,是遵守ACID的關係型資料庫管理系統,它包括在一個相對小的C庫中。它是D.RichardHipp建立的公有領域項目。它的設計目標是嵌入式的,並且眼下已經在非常多嵌入式產品中使用了它,它佔用資源非常的低,在嵌入式裝置中。可能僅僅須要幾百K的記憶體就夠了。它能夠支援Windows/Linux/Unix等等主流的作業系統,同一時候能夠跟非常多程式語言相結合,比方 Tcl、C#、PHP、Java等,還有ODBC介面,相同比起M
ysql、PostgreSQL這兩款開源的世界著名資料庫管理系統來講,它的處理速度比他們都快。
SQLite第一個Alpha版本號碼誕生於2000年5月。
至2015年已經有15個年頭,SQLite也迎來了一個版本號碼 SQLite 3已經公布。
總結 : SQLite作為移動終端的資料庫是非常合適的。佔用記憶體小、輕量級、處理速度快…
2.Android中怎樣使用SQLite2.1 建立SQLiteOpenHelper對象。並建立表
建立一個類,命名為MySQLiteOpenHelper,並將其繼承自SQLiteOpenHelper:
建立後會報錯,由於沒有加入構造方法,加入構造方法:
package com.example.sqllitetest; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class MySQLOpenHelper extends SQLiteOpenHelper { public MySQLOpenHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub } /** * 資料庫建立時會調用,在這裡運行建立表的語句 */ @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub } /** * 資料庫升級時,此方法會調用,在這裡運行資料庫更新操作 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } /** * 資料庫開啟時,此方法會調用 */ @Override public void onOpen(SQLiteDatabase db) { // TODO Auto-generated method stub super.onOpen(db); } }
在上面的onCreate()。方法中運行一條建立表名為person的語句
db.execSQL("create table person (_id integer primary key autoincrement, name char(10), age integer(3), phone integer(20))");
注意:事實上在sqlite中除了id主鍵以外。全部的欄位都沒有明白的類型限制,舉個列子,我們向integer類型的欄位中插入char類型的資料也是能夠的
那麼既然這樣,我們建立資料庫時,指定的資料類型意圖何在?
這些是為了。讓我們程式猿瞭解某個欄位的類型限制。實際編碼時,還是要指定欄位明白類型的,方便日後維護和理解。
建立一個測試類SqliteTestCase.java:
package com.example.sqllitetest; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.test.AndroidTestCase; public class SqlliteTestCase extends AndroidTestCase { private MySQLOpenHelper oh; private SQLiteDatabase db; public void test() { System.out.println("This is test method!"); } /** * 測試架構初始化完成過後,在測試方法調用之前調用此方法 */ @Override protected void setUp() throws Exception { super.setUp(); // 獲得可寫的資料庫物件(若資料庫不存在。先建立資料庫。再擷取可讀可寫的資料庫物件;假設資料庫存在,就直接開啟) // *********************** 參數說明 *********************** // 參數1 : 擷取Context對象,AndroidTestCase中為了方便測試,提供了getContext()方法 // 參數2 : 資料庫檔案名稱 // 參數3 : 遊標工廠對象,被用來建立遊標對象。默覺得空 // 參數4 : 用來標識資料庫的版本號碼,用來與之前建立的時候做對照,當版本號碼大於,則調用onUpgrade() oh = new MySQLOpenHelper(getContext(), "person.db", null, 1); /** * ************** 第一種方法:擷取資料庫 ************** * 1.被用來建立或開啟一個可讀寫的資料庫。 * 當它被第一次調用的時候,會依據new SQLOpenHelper()中的資料庫名和版本號碼號 * 當已存在相同資料庫檔案。並且版本號碼號相同。則直接開啟, * 反之,則調用建立或更新方法。 * * 2.資料一旦開啟成功。將被緩衝起來,當我們在須要錄入資料時,能夠在不論什麼地方去調用返回 * 的對象去操作資料庫。注意:但不須要使用資料庫時。須要關閉資料庫 * * 3.但沒有許可權時。抑或磁碟滿了的時候,這種方法將會被調用失敗,可是,若問題得到解決。就可以成功調用 * * 4.調用這種方法,若觸發更新操作,你就須要警覺了: * 由於資料庫的更新是個耗時的操作。我們不應該在應用的主線程中去調用它。包括ContentProvider.onCreate() * */ db = oh.getWritableDatabase(); /** * ************** 另外一種方法:擷取資料庫 ************** * 不要被名字誤導。這種方法相同可獲得可讀寫的資料庫物件。 * 它與上面方法的差別是,當遇到一些問題:(列如:磁碟滿了。這個時候調用不會失敗,而是將會返回一個僅僅讀的資料庫物件) */ db = oh.getReadableDatabase(); } /** * 測試方法運行完成過後,調用此方法 */ @Override protected void tearDown() throws Exception { // TODO Auto-generated method stub super.tearDown(); // 關閉資料庫 db.close(); } }
注意:當我們new SQLiteOpenHelper()開啟某個資料庫時。傳入的版本號碼號不應比之前建立這個資料庫的時候綁定的版本號碼號低。否則會出現以下的錯誤,版本號碼號僅僅能遞增
運行test()方法,顯示為綠色,說明沒有錯誤
通過DDMS–>File Explore,查看data/data/項目包名/databases檔案夾下:
匯出檔案。在SQLite Expert軟體中開啟:
能夠看到,資料庫和表都被正確建立。
2.2 通過SQLiteDatabase對象運行增刪改查操作
2.2.1加入資料操作
加入資料有兩種方法:
- 第一種方法 : 通過手寫sql語句,運行execSQL();方法;
在SqliteTestCase.java中加入insert()方法
public void insert() { db.execSQL("insert into person (name, age, phone) values(?, ? , ?)", new Object[]{"張三", 18, "180199678455"}); db.execSQL("insert into person (name, age, phone) values(?
, ? , ?)", new Object[]{"趙四", 16, "180199678455"}); db.execSQL("insert into person (name, age, phone) values(?
, ? , ?)", new Object[]{"Android", 15, "180199678455"}); }
運行結果,資料成功插入表中:
- 另外一種方法 : 通過Android API,將資料封裝到contentValues中。
在SqliteTestCase.java中加入insertByApi()方法:
public void insertApi() { // 把全部的資料封裝到contentValues中 ContentValues values = new ContentValues(); values.put("name", "zhangsan"); values.put("age", 78); values.put("phone", "13812235689"); // 參數說明: // 第一個參數table : 表名 // 第二個參數nullColumnHack :能夠指定為null,若為null,當你values中無值。則不會插入行 // 若你指定了nullColumnHack的值,即便你的values中無值,也會 // 插入null值到你的欄位下 // 第三個參數values : ContentValues對象 db.insert("person", null, values); }
匯出db檔案,重新整理:
2.2.1刪除資料操作
刪除資料相同有兩種方法:
- 第一種方法 : 通過手寫sql語句,運行execSQL();方法。
public void delete() { // 刪除id為1的行 db.execSQL("delete from person where _id = ?", new Object[]{1}); }
public void deleteApi() { // 刪除表中age = 78, id = 4的記錄 // 傳回值為受影響的行,刪除了多少行 int i = db.delete("person", "age = ? and _id = ?", new String[]{"78", "4"}); }
2.2.1改動資料操作
改動資料相同有兩種方法:
- 第一種方法 : 通過手寫sql語句。運行execSQL()方法:
public void update() { // 改動id為2的phone值為110 db.execSQL("update person set phone = ? where _id = ?", new Object[]{"110", 2}); }
查看結果:
public void updateApi() { // 通過ContentValues來指定改動後的值 ContentValues values = new ContentValues(); values.put("phone", "120"); // 傳回值為受影響的行 int i = db.update("person", values, "_id = ? and age = ?", new String[]{"3", "15"}); }
查看結果:
2.2.1查詢資料操作
查詢資料相同有兩種方法:
public void query() { Cursor cursor = db.rawQuery("select name, age, phone from person ", null); while (cursor.moveToNext()) { // 不推薦用這樣的下標的方式來擷取值,一旦後期欄位的位置有所改動,維護起來比較麻煩 // String name = cursor.getString(0); // int age = cursor.getInt(1); // String phone = cursor.getString(2); // 推薦使用 String name = cursor.getString(cursor.getColumnIndex("name")); int age = cursor.getInt(cursor.getColumnIndex("age")); String phone = cursor.getString(cursor.getColumnIndex("phone")); System.out.println("name : " + name + "; age = " + age + ";" + " phone = " + phone); } }
logcat輸出結果:
public void queryApi() { Cursor cursor = db.query("person", null, null, null, null, null, null); while (cursor.moveToNext()) { String name = cursor.getString(cursor.getColumnIndex("name")); int age = cursor.getInt(cursor.getColumnIndex("age")); String phone = cursor.getString(cursor.getColumnIndex("phone")); System.out.println("name : " + name + "; age = " + age + ";" + " phone = " + phone); } }
2.3 SQLiteDatabase之事務transaction
應用情境:當須要保證多條語句同一時候運行成功,否則。復原
這裡。我們簡單的類比一下。假設我們須要id為2的age加1歲,同一時候又要保證id為3的age減1歲
原本資料在資料庫中是這樣:
假設事務運行成功後。name為趙四的age將變為17,而name為Android的age變為14。反之,兩條資料的全部屬性值不變。
首先。我們人為的導致運行失敗:
加入方法:
public void transaction() { try { // 開啟事務 db.beginTransaction(); ContentValues values = new ContentValues(); values.put("age", 17); db.update("person", values, "_id = ?", new String[]{"2"}); values.clear(); values.put("age", 14); db.update("person", values, "_id = ?", new String[]{"3"}); int i = 1 / 0; // 這裡有錯,將導致事務運行失敗 // 設定事務運行成功 db.setTransactionSuccessful(); } catch (Exception e) { // TODO: handle exception } finally { // 結束事務,同一時候提交。假設已經設定事務運行成功,則sql語句生效。反之,則復原 db.endTransaction(); } }
匯出db檔案,重新整理,看到資料無不論什麼變化:
再將錯誤去掉。運行方法:
結果例如以下,運行成功:
Android開發之利用SQLite進行資料存放區