當需要儲存大量或關聯式資料時Android支援的資料庫為SQLite,使用標準SQL語法,而Android也提供更簡便的存取方式,將新增刪除等語法縮減到一行程式完成。
Stetho則是Facebook出版的測試工具,讓我們透過Chrome瀏覽器看APP的資料庫,檢測資料欄位和內容是否如我們預期,使用上很輕便,滑鼠點一點就行了。
新增一個Java Class名為MyDBHelper並extends SQLiteOpenHelper,用途即為建立和更新資料表(Table)
public class MyDBHelper extends SQLiteOpenHelper {
// 以Singleton模式使用資料庫
private static MyDBHelper mInstance = null;
// 資料庫名稱
private final static String _DBName = "MyDB.db";
// 資料庫版本,要更新資料庫時需增加版本號
private final static int _DBVersion = 1;
public static MyDBHelper getInstance(Context ctx) {
if (mInstance == null) {
mInstance = new DBHelper(ctx.getApplicationContext());
}
return mInstance;
}
private MyDBHelper(Context context) {
super(context, _DBName, null, _DBVersion);
}
@Override
public void onCreate(SQLiteDatabase db) {
// 建立資料表寫在這裡
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 當資料庫版本更新時會執行這邊,可在此修改資料表
}
}
之後用SQL語法將要建立的資料表寫在onCreate()裡就可以囉,SQLite只用三種欄位型態:
我們在onCreate中建立一個UserData資料表,特別注意第一個欄位須為_id並設為主鍵
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS UserData ( " +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"Name TEXT, " +
"Age INTEGER, " +
"Email TEXT DEFAULT '' " +
");");
}
在Activity中呼叫MyDBHelper完成資料庫初始化
public class MainActivity extends AppCompatActivity {
// 宣告資料庫物件
private SQLiteDatabase db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 呼叫MyDBHelper
MyDBHelper DH = MyDBHelper.getInstance(this);
// 取得可讀寫的資料庫
db = DH.getWritableDatabase();
}
}
在討論CRUD之前先來裝個Stetho,看看我們剛剛創的資料表有沒有成功
加入dependencies
compile 'com.facebook.stetho:stetho:1.4.1'
新增一個Java Class名為MyApplication,並讓它繼承Application。這樣的話每次APP開啟時都會先執行MyApplication的onCreate()方法,可以用來啟動各種工具如Stetho
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 啟動Stetho
Stetho.initializeWithDefaults(this);
}
}
在AndroidManifest.xml中的application加上一行android:name
並設為.MyApplication
安裝完成,執行APP
開啟Chrome瀏覽器並在網址列輸入 chrome://inspect/#devices ,會出現目前運行中的模擬器和APP,點選inspect
在新開啟的視窗中選擇Resources,左邊選擇Web SQL -> 資料庫名稱(MyDB.db) -> 資料表UserData,就會看到剛剛創的Table欄位囉。有時候_id會重複出現兩次我也還不清楚原因,請先忽略它Orz
使用ContentValues來新增資料,將值和欄位寫好並用db.insert新增
public class MainActivity extends AppCompatActivity {
// 宣告資料庫物件
private SQLiteDatabase db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 呼叫MyDBHelper
MyDBHelper DH = MyDBHelper.getInstance(this);
// 取得可讀寫的資料庫
db = DH.getWritableDatabase();
// 將要新增的資料放到ContentValues
ContentValues values = new ContentValues();
values.put("Name", "Ivan");
values.put("Age", 18);
values.put("Email", "ivan@BeanBean.com");
// 新增資料到UserData欄位
db.insert("UserData", null, values);
}
}
執行APP並在Stetho的視窗按左下角的重新整理,就會出現資料囉
使用db.rawQuery撈資料,並用Cursor的get方法取得欄位值,Select全部時第0欄為_id,第1欄為Name,因此getString(1)就會取得第1欄的資料Name,若只Select Name, Age的話就會分別是第0和1欄。記得撈完要用close()關閉Cursor
Cursor c = db.rawQuery("SELECT * FROM UserData " , null);
while (c.moveToNext()) {
String name = c.getString(1);
int age = c.getInt(2);
String email = c.getString(3);
Log.d("使用者資訊", "姓名:" + name);
Log.d("使用者資訊", "年齡:" + age);
Log.d("使用者資訊", "信箱:" + email);
}
c.close();
以上執行後可在Log看到資料
和新增一樣先用ContentValues放好資料,差別在最後用db.update時加入條件式
ContentValues values = new ContentValues();
// 將Name欄位更新為IvanBean
values.put("Name", "IvanBean");
// 第三個參數為條件式,等同於SQL語法的 WHERE _id = 1
db.update("UserData", values, "_id = " + 1 , null);
用db.delete刪除資料,第二個參數為條件式,若輸入null則會刪除全部
// 刪除_id為1的資料
db.delete("UserData", "_id = " + 1, null);
今天先建立資料庫並做簡單的CRUD,明天再補充更新資料表欄位的方法