一、為什麼要會點SQLite?
SQLite作為一款輕量級的關係型資料庫,佔用的資源特別少,所以其應用場景也是特別的多。在移動開發中,我們經常會有將資料儲存在本地的需求,此時SQLite將是我們最佳的選擇。
可喜的是,SQLite已經被完美的整合在Android系統中,所以對於開發者而言,上手SQLite的難度又降低了不少。
二、開始玩玩SQLite
首先來說說在Android中操作SQLite資料庫的整體思路:
1、自定義資料庫操作輔助類,並繼承自SQLiteOpenHelper類;
2、在Application中初始化SQLiteOpenHelper物件,並公開一個方法供其他類呼叫獲取該物件;
3、根據SQLiteOpenHelper物件例項化SQLiteDatabase物件;
4、最後,我們拿SQLiteDatabase物件即可進行SQLite資料庫的常規操作了。
複製程式碼
其實整個流程並不複雜,稍微來點耐心,動動手指頭,再回頭瞧瞧SQLite,“哇哦,操作你如此簡單!”
1、自定義資料庫操作輔助類,並繼承自SQLiteOpenHelper類
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* author:silencezwm on 16/6/20 06:43
* email:silencezwm@gmail.com
* description:資料庫操作輔助類
*/
public class DBHelper extends SQLiteOpenHelper {
//資料庫名稱
private static final String DBName = "study.db";
//資料庫版本號
private static final int DBVersion = 1;
//構造方法
public DBHelper(Context context) {
super(context, DBName, null, DBVersion);
}
@Override
public void onCreate(SQLiteDatabase db) {
//建立表---study
db.execSQL("CREATE TABLE study ( _id integer PRIMARY KEY AUTOINCREMENT NOT NULL, bookName varchar, bookDesc varchar)");
}
/**
* 資料庫版本更新
* @param db 資料庫例項
* @param oldVersion 舊版本號
* @param newVersion 新版本號
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS study");
onCreate(db);
}
}
複製程式碼
該類繼承了SQLiteOpenHelper,並實現了三個方法,其中onCreate()在資料庫初始化時會呼叫,onUpgrade()方法只有在資料庫新版本號大於舊版本號時才會呼叫,即進行資料庫的更新操作。其中涉及到了常用SQL語句的書寫,看不懂的童鞋得抽空腦補一下這方面的知識哦。
SQLiteOpenHelper有什麼用?
該SQLiteOpenHelper是Android平臺提供給我們的資料庫輔助類,用於建立或開啟資料庫。
複製程式碼
2、在Application中初始化SQLiteOpenHelper物件,並公開一個方法供其他類呼叫獲取該物件
考慮到整個應用中的不同地方都有可能涉及到資料庫的操作,所以我們有必要將該類的初始化放在我們自定義的Application類中。就像該下:
public class MyApp extends Application {
//資料庫輔助類例項
private static DBHelper mDBHelper;
@Override
public void onCreate() {
super.onCreate();
mDBHelper = new DBHelper(getApplicationContext());
}
//返回DBHelper例項,
public static DBHelper getmDBHelper(){
return mDBHelper;
}
}
複製程式碼
我們來看看初始化SQLiteOpenHelper類原始碼的實現方式
public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
this(context, name, factory, version, null);
}
複製程式碼
引數含義解析:
context:上下文物件,這裡我們傳入了ApplicationContext;
name:資料庫名稱,這裡我們定義為"study.db";
factory:運算元據庫後返回的預設Cursor物件,這裡我們預設為null,後續需要儲存返回的Cursor物件時,自己再進行構造;
version:資料庫的版本號,初始版本號必須大於1,否則系統會拋IllegalArgumentException("Version must be >= 1, was " + version)異常。
複製程式碼
3、根據SQLiteOpenHelper物件例項化SQLiteDatabase物件
該操作將會讓我們得到SQLiteDatabase物件,而一旦有了該物件,我們就可以進行資料庫的增刪改查操作了。該操作我們可以單獨封裝在某個類,同樣也可以直接在某個Activity中實現。
核心程式碼如下:
//獲取的資料庫物件
//其中 getWritableDatabase() 和 getReadableDatabase() 區別???
SQLiteDatabase db = MyApp.getmDBHelper().getWritableDatabase();
//SQLiteDatabase db = MyApp.getmDBHelper(). getReadableDatabase();
複製程式碼
得到SQLiteDatabase例項有以上兩種方法,兩種方法的主要區別在於:
在資料庫僅開放只讀許可權或磁碟已滿時,getReadableDatabase只會返回一個只讀的資料庫物件。
複製程式碼
另外在我們每次初始化SQLiteDatabase物件時,系統都會進行資料庫版本號的判斷,該判斷的核心程式碼如下(有興趣的童鞋可以研究下getWritableDatabase()、getReadableDatabase()的原始碼實現):
//獲取資料庫版本號,預設為0
final int version = db.getVersion();
//如果老版本號與新版本號不同
if (version != mNewVersion) {
//如果資料庫為只讀,系統則會丟擲"SQLiteException"異常
if (db.isReadOnly()) {
throw new SQLiteException("Can`t upgrade read-only database from version " +
db.getVersion() + " to " + mNewVersion + ": " + mName);
}
//資料庫開啟事務
db.beginTransaction();
try {
//表示資料庫第一次建立,則會進入我們文章最上面自定義DBHelper類的onCreate()方法
if (version == 0) {
onCreate(db);
} else {
//如果舊版本號大於新版本號,資料庫會”降級“,否則資料庫會”升級“
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
}
//設定資料庫的最新版本號
db.setVersion(mNewVersion);
//事務成功完成
db.setTransactionSuccessful();
} finally {
//最後結束事務
db.endTransaction();
}
}
複製程式碼
4、拿SQLiteDatabase物件進行SQLite資料庫的常規操作
該下簡略介紹兩種操作方法:
1、使用SQL語句
2、使用Android封裝好的方法
複製程式碼
我們在初始化SQLiteDatabase物件的時候,建立了一個資料庫:study.db,並在資料庫中建立了一個表:study,表中包含主鍵自增 _id , 還有兩個欄位:bookName、bookDesc。
該下程式碼實現了往資料庫中插入、更新、查詢、刪除四種常用操作,此時你應該親自動手試試…
//插入資料
case R.id.btn_insert:
//使用SQL語句
if (useSQL) {
db.execSQL("insert into study values(null, ?, ?)",
new Object[]{et_insert_book_name.getText().toString(), et_insert_book_desc.getText().toString()});
//使用Android封裝的方法
} else {
//其中cv為ContentValues的例項
cv.put("bookName", et_insert_book_name.getText().toString());
cv.put("bookDesc", et_insert_book_desc.getText().toString());
long isOK = db.insert("study", null, cv);
//-1代表操作失敗
if (isOK == -1) {
Toast.makeText(DBDemoActivity.this, "插入失敗", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(DBDemoActivity.this, "插入成功", Toast.LENGTH_SHORT).show();
}
}
break;
//更新資料
case R.id.btn_update:
if (useSQL) {
db.execSQL("update study set bookName = ? where bookName = ?", new String[]{et_update_new_book_name.getText().toString(), et_update_book_name.getText().toString()});
} else {
cv.put("bookName", et_update_new_book_name.getText().toString());
int updateCount = db.update("study", cv, "bookName = ?", new String[]{et_update_book_name.getText().toString()});
//更新後更新的個數,"0"表示更新失敗
if (updateCount != 0) {
Toast.makeText(DBDemoActivity.this, "更新成功,共更新個數:" + updateCount, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(DBDemoActivity.this, "更新失敗", Toast.LENGTH_SHORT).show();
}
}
break;
//查詢操作
case R.id.btn_query:
if (useSQL) {
Cursor cursor = db.rawQuery("select * from study", null);
StringBuilder sb = new StringBuilder();
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
sb.append("總數:" + cursor.getCount() + "\\n" + "書名:" + cursor.getString(cursor.getColumnIndex("bookName"))
+ "----該書簡介:" + cursor.getString(cursor.getColumnIndex("bookDesc")));
text_query_result.setText(sb.toString());
}
//記得進行關閉哦
cursor.close();
} else {
//查詢該表中所有資料
Cursor c = db.query("study", null, null, null, null, null, null);
StringBuffer sb = new StringBuffer();
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
sb.append("總數:" + c.getCount() + "\\n" + "書名:" + c.getString(c.getColumnIndex("bookName"))
+ "----該書簡介:" + c.getString(c.getColumnIndex("bookDesc")));
text_query_result.setText(sb.toString());
}
//記得進行關閉哦
c.close();
}
break;
//刪除操作
case R.id.btn_del:
if (useSQL) {
db.execSQL("delete from study where bookName = ?", new String[]{et_del_book_name.getText().toString()});
} else {
db.delete("study", "bookName = ?", new String[]{et_del_book_name.getText().toString()});
}
break;
複製程式碼
三、SQLite說
”555…又被你看穿了“