1 資料庫思路
(1)可把表中的欄位用javabean來實現
(2)在資料庫和ContentProvider結合使用時,不採用此處SQLiteDatabase的execSQL()和rawQuery()方法來實現資料的增刪改查而是使用了SQLiteDatabase的內建的update(),delete(),query()等方法.因為兩者的參數基本一致,直接從ContentProvider傳遞給這些內建方法即可
2 SQLiteOpenHelper的引入
我們在編寫資料庫應用軟體時,需要考慮這樣的問題:因為軟體可能會安裝在很多使用者的手機上.
如果應用使用到了SQLite資料庫,我們必須在使用者初次使用軟體時建立出應用使用到的資料庫表結構及添加一些初始化記錄,另外在軟體升級的時候,也需要對資料表結構進行更新。
那麼,我們如何才能實現在使用者初次使用或升級軟體時自動在使用者的手機上建立出應用需要的資料庫表呢?總不能讓我們在每個需要安裝此軟體的手機上通過手工方式建立資料庫表吧?(這也是為什麼它叫……OpenHelper的原因)
於是可以複寫SQLiteOpenHelper的onCreate()和onUpgrade()方法以在建立資料庫和資料庫版本發生變化時自動調用。
3 DataBaseOpenHelper 的使用
DataBaseOpenHelper的執行個體dataBaseOpenHelper可以dataBaseOpenHelper.getWritableDatabase()和dataBaseOpenHelper.getWritableDatabase()的方式返回資料庫SQLiteDatabase的執行個體db。這兩種方式有什麼區別呢?查看原始碼可知:getReadableDatabase在不出錯的時候其實際返回的是getWritableDatabase.那麼什麼時候會出錯呢?
資料庫的磁碟空間滿了,資料庫此時只可以讀而不可以寫,所以不可以用讀寫(可以進行讀和寫操作)方式開啟資料庫。這個時候就會報錯;所以只可以用唯讀方式開啟資料庫。
因此在出錯的時候,返回的是getReadableDatabase()!!!
4 資料庫的增刪改查操作
利用SQLiteDatabase的執行個體db進行資料庫的增刪改查操作.其中db.execSQL()來執行更改行為的語句;db.rawQuery()來執行查詢語句
注意:
(1)在SQL語句中最好使用預留位置,這樣來提高SQL語句的安全性
(2)public void execSQL (String sql, Object[] bindArgs)第二個參數是Object數組
(3)public Cursor rawQuery (String sql, String[] selectionArgs)第二個參數是String數組
增加樣本:
db.execSQL("insert into person (name,phone) values(?,?)",new Object[]{person.getName(),person.getPhone()});
更新樣本:
public void update(Person person){
SQLiteDatabase db=openHelper.getWritableDatabase();
db.execSQL("update person set name=?,phone=? where personid=?",new Object[]{person.getName(),person.getPhone(),person.getId()});
}
刪除樣本:
public void delete(int i){
SQLiteDatabase db=openHelper.getWritableDatabase();
db.execSQL("delete from person where personid=?",new Object[]{String.valueOf(i)});
}
尋找樣本:
public Person find(int personId){SQLiteDatabase db=openHelper.getWritableDatabase();Cursor cursor=db.rawQuery("select * from person where personid=?", new String[]{String.valueOf(i)});while(cursor.moveToFirst()){int personid=cursor.getInt(cursor.getColumnIndex("personid"));String name=cursor.getString(cursor.getColumnIndex("name"));String phone=cursor.getString(cursor.getColumnIndex("phone"));return new Person(personid, name, phone);}cursor.close();return null;}
注意:
(1)db.rawQuery()的結果是一個cursor結果集.其指標最開始時候執行指向結果集的上方,即第一條紀錄的前面
(2)取值操作:cursor.get具體類型(參數為某列的名稱的索引值)
(3)最後關閉cursor
統計樣本:
public int count(){SQLiteDatabase db=openHelper.getReadableDatabase(); Cursor cursor=db.rawQuery("select count(*) from person", null);int i=0;while(cursor.moveToFirst()){ i=cursor.getInt(0); break;}return i;}
分頁樣本:
public List<Person> page(int offset,int resuletNumber){SQLiteDatabase db=openHelper.getWritableDatabase();ArrayList<Person> persons=new ArrayList<Person>();Person person;Cursor cursor=db.rawQuery("select * from person limit ?,?",new String []{String.valueOf(offset),String.valueOf(resuletNumber)});while(cursor.moveToNext()){int personid=cursor.getInt(cursor.getColumnIndex("personid"));String name=cursor.getString(cursor.getColumnIndex("name"));String phone=cursor.getString(cursor.getColumnIndex("phone"));person=new Person(personid, name, phone);persons.add(person);}return persons; }
5 資料庫事務
public void payment(){SQLiteDatabase db = dbOpenHelper.getWritableDatabase();db.beginTransaction();try{db.execSQL("update person set amount=amount-10 where personid=1");db.execSQL("update person set amount=amount+10 where personid=2");db.setTransactionSuccessful();//設定事務的標誌為成功}finally{db.endTransaction();//結束事務,預設情況下是復原事務}}
結束事務有兩種:提交事務和復原事務。預設情況是復原事務!!!
事務是否提交是由事務的標誌來決定的,如果事務的標誌位失敗(false),那麼就復原事務,否則(true)提交事務。
所以預設情況下事務的標誌為失敗(false),交易回復.
為什麼要把結束事務放在finally裡面?
若不這樣當事務發生異常,便不會往下執行了,資料庫要等到一個逾時後才會結束事務而影響效能,所以在finally裡將其結束