編輯:關於Android編程
今天我們來接觸一個輕輕輕量級數據庫(SQLite),為什麼要加3個輕呢?因為它確實很輕
。 Sqlite是專門未嵌入式設備准備的輕量級數據庫,麻雀雖小,五髒俱全,sqlite的功能卻一點都不少。它和其他的數據庫:MySql,SqlServer,Oracle等數據庫的最大區別我覺得就是Sqlite只能運行在終端,不能用在服務器上,這也體現了它為嵌入式設備工作的初衷。
好了,來看看今天的內容:
SQLiteAndroid單元測試今天我們不僅要介紹sqlite,還要簡單介紹一下怎麼使用android的單元測試。如果不知道什麼是單元測試,那就去找google吧!
在android中使用 sqlite數據庫,一般要通過一個協助類: SQLiteOpenHelper,這個類中有兩個方法:onCreate() ,和 onUpgrade()。
onCreate() 在數據庫第一次被創建時才調用。onUpgrade()當數據庫版本更新時調用。是什麼意思呢?來看看代碼:
package db;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.transition.Transition;
import android.util.Log;
public class DBOpenHelper extends SQLiteOpenHelper {
private static final String TAG = "DBOpenHelper";
private Context mContext;
private String mDBname;
private String mTableName = "students";
private SQLiteDatabase mDatabase;
private int mVersion;
private String CREATE_TABLE = "create table if not exists " + mTableName
+ " (_id integer primary key, name text)";
public DBOpenHelper(Context context, String dbname, CursorFactory factory,
int version) {
super(context, dbname, factory, version);
this.mContext = context;
this.mDBname = dbname;
this.mVersion = version;
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.e(TAG, "onCreate");
db.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.e(TAG, "onUpgrade");
}
public long insert(String data) {
if (mDatabase == null) {
mDatabase = getWritableDatabase();
}
ContentValues values = new ContentValues();
values.put("name", data);
return mDatabase.insert(mTableName, "_id", values);
}
public int delete(int id) {
if (mDatabase == null) {
mDatabase = getWritableDatabase();
}
return mDatabase.delete(mTableName, "_id" + "=" + id, null);
}
public int update(int id, String data) {
if (mDatabase == null) {
mDatabase = getWritableDatabase();
}
ContentValues values = new ContentValues();
values.put("name", data);
return mDatabase.update(mTableName, values, "_id" + "=" + id, null);
}
public Cursor getItemAt(int id) {
if (mDatabase == null) {
mDatabase = getWritableDatabase();
}
Cursor cursor = mDatabase.query(mTableName, new String[] { "_id",
"name" }, "_id" + "=" + id, null, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
}
public Cursor getAll() {
if (mDatabase == null) {
mDatabase = getWritableDatabase();
}
Cursor cursor = mDatabase.query(mTableName, new String[] { "_id",
"name" }, null, null, null, null, null);
return cursor;
}
}
在使用SqliteOpenHelper時,這三個方法是必須的:
public DBOpenHelper(Context context, String dbname, CursorFactory factory,
int version) {
super(context, dbname, factory, version);
this.mContext = context;
this.mDBname = dbname;
this.mVersion = version;
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.e(TAG, "onCreate");
db.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.e(TAG, "onUpgrade");
}構造方法完成 Context, 數據庫名稱,數據庫版本 的初始化,CursorFactory一般用不到,直接穿為null。
在onCreate()我們調用 db.execSQl( CREATE_TABLE) ; 初始化了一張表 “students”,那麼這個DBOpenHelper類也就是為這張表工作了。
至於 onUpdrade()是在調用 構造函數時,version的值 大於 上一個值的時候就會被觸發,然後 onUpgrade()中主要做表的數據修改列啊,備份數據等工作,這裡不講。
然後我們來看看數據庫的增刪改查是怎麼完成的:
增:
使用android提供的ContentValues 可以輕易的初始化要添加的對象,它相當於一個鍵值對,如果有多項,依次用put方法添加就可以了,注意key一定要與數據庫中的列對應。
這裡的 mDatabase 是一個SqliteDatabase 對象,專門用來操作數據庫的,可通過 SqliteOpenHelper. getWritableDatabase()獲得,然後通過調用 insert()方法就可以插入數據。這裡大家需要注意,使用sqlite時,表中必須有一個字段叫 “_id",而且是主鍵自增長,這就是insert的第二個參數的值。
相當於執行 sql語句:
insert into students(_id, name) values(id, name); public long insert(String data) {
if (mDatabase == null) {
mDatabase = getWritableDatabase();
}
ContentValues values = new ContentValues();
values.put("name", data);
return mDatabase.insert(mTableName, "_id", values);
}
刪:
第二個參數是字符串,相當於: "where _id=id " 只是 delete方法自己做了拼接。
相當於執行 sql語句:
delete from students where _id=id;
public int delete(int id) {
if (mDatabase == null) {
mDatabase = getWritableDatabase();
}
return mDatabase.delete(mTableName, "_id" + "=" + id, null);
}改:
update方法就需要提供 條件, 以及修改的值,對應於 values 和 ”_id"=id 兩個參數。
相當於執行 sql語句:
update students where _id=id set name = "data";
public int update(int id, String data) {
if (mDatabase == null) {
mDatabase = getWritableDatabase();
}
ContentValues values = new ContentValues();
values.put("name", data);
return mDatabase.update(mTableName, values, "_id" + "=" + id, null);
}查:
查找需要注意的是android中使用到了游標作為結果集(java中的ResultSet),如果找到,返回到游標在第一行數據的前面,所以需要先調用一次 cursor.moveToFirst() 或者 cursor.moveToNext() ,這樣就可以指向第一行數據。
public Cursor getItemAt(int id) {
if (mDatabase == null) {
mDatabase = getWritableDatabase();
}
Cursor cursor = mDatabase.query(mTableName, new String[] { "_id",
"name" }, "_id" + "=" + id, null, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
}
public Cursor getAll() {
if (mDatabase == null) {
mDatabase = getWritableDatabase();
}
Cursor cursor = mDatabase.query(mTableName, new String[] { "_id",
"name" }, null, null, null, null, null);
return cursor;
}好了,sqlite的操作看完了,我們來看看怎麼使用 DBOpenHelper這個類。這個時候我們使用到了Android的單元測試。
Android單元測試的配置方法:
1. 在AndroidMainefest.xml 文件中添加注冊。
標簽之間添加:
2. 測試類必須繼承與 AndroidTestCase。
3. 每個測試方法都以 test+要測試的方法 名作為測試方法名, 並且需要拋出異常。
我們來看看代碼:
package Test;
import db.DBOpenHelper;
import android.database.Cursor;
import android.test.AndroidTestCase;
import android.util.Log;
public class TestDBOpenHelper extends AndroidTestCase {
private static final String TAG = "TestDBOpenHelper";
public void TestInsert() throws Throwable{
Log.e(TAG,"TestInsert");
DBOpenHelper dbopenhelper = new DBOpenHelper(mContext, "stu.db", null, 1);
dbopenhelper.insert("stu1");
dbopenhelper.insert("stu2");
dbopenhelper.insert("stu3");
dbopenhelper.insert("stu4");
dbopenhelper.insert("stu5");
}
public void TestDelete(){
DBOpenHelper dbopenhelper = new DBOpenHelper(mContext, "stu.db", null, 1);
dbopenhelper.delete(1);
dbopenhelper.delete(2);
}
public void TestUpdate(){
DBOpenHelper dbopenhelper = new DBOpenHelper(mContext, "stu.db", null, 1);
dbopenhelper.update(3, "333");
dbopenhelper.update(4, "444");
}
public void TestGetItemAtId(){
Log.e(TAG,"TestGetItemAtId");
DBOpenHelper dbopenhelper = new DBOpenHelper(mContext, "stu.db", null, 1);
Cursor cursor = dbopenhelper.getItemAt(3);
Log.e(TAG,"_id="+cursor.getInt(0));
Log.e(TAG,"name="+cursor.getString(1));
}
public void TestGetAll(){
Log.e(TAG,"TestGetAll");
DBOpenHelper dbopenhelper = new DBOpenHelper(mContext, "stu.db", null, 1);
Cursor cursor = dbopenhelper.getAll();
while(cursor.moveToNext()){
Log.e(TAG,"_id="+cursor.getInt(0));
Log.e(TAG,"name="+cursor.getString(1));
}
}
}
寫好之後我們就可以啟動單元測試來測試我們寫的代碼:
如果正確就會綠條,有異常會顯示紅條:
單元測試的好處多多,關心代碼質量的同志們都應該學會怎麼使用單元測試,它是為了驗證每個代碼塊都能工作正常而產生的。
測試代碼應該很容易就看懂了:
這是在測試添加數據,只需要new一個 helper對象,然後調用insert方法就可以了,是不是很簡單:
測試插入:
public void TestInsert() throws Throwable{
Log.e(TAG,"TestInsert");
DBOpenHelper dbopenhelper = new DBOpenHelper(mContext, "stu.db", null, 1);
dbopenhelper.insert("stu1");
dbopenhelper.insert("stu2");
dbopenhelper.insert("stu3");
dbopenhelper.insert("stu4");
dbopenhelper.insert("stu5");
}
測試刪除:
public void TestDelete(){
DBOpenHelper dbopenhelper = new DBOpenHelper(mContext, "stu.db", null, 1);
dbopenhelper.delete(1);
dbopenhelper.delete(2);
}
測試查找:
public void TestGetAll(){
Log.e(TAG,"TestGetAll");
DBOpenHelper dbopenhelper = new DBOpenHelper(mContext, "stu.db", null, 1);
Cursor cursor = dbopenhelper.getAll();
while(cursor.moveToNext()){
Log.e(TAG,"_id="+cursor.getInt(0));
Log.e(TAG,"name="+cursor.getString(1));
}
}剛剛我們看到,getAll() 函數返回到是一個 cursor,我們可以通過循環遍歷每個cursor中的對象。 得到cursor某一列的值 可通過 cursor.getXXX( index ) 來獲取,index是column的編號,從0開始,當然也可以通過列的名字來得到。總的來說 Cursor的一行就像一個Map一樣,存放數據庫中的一行數據的鍵值對。
好了,終於完了,最後還是要說一下,上面的例子是很不規范的,當然只是為了體現應該怎麼來使用Sqlite存取數據,在真實的開發中,我們傳入的內容應該是 一個對象,這裡需要和JavaBean結合,就是說數據庫中存儲的數據,其實是針對一個Class的屬性值來存儲的,而不是單個的值。數據庫中的每一行存儲一個對象的所有屬性,當然也可能是幾張表聯合。
Android Framework Application Framework層簡單介紹
引言 Andr
Android實現畫板、寫字板功能(附源碼下載)
前言本文給大家分享一個使用Android開發寫字板功能Dem、簡單操作內存中的圖像、對圖像進行簡單的處理、繪制直線、以達到寫字板的效果效果圖如下XML布局代碼<Re
Android Studio導入Eclipse項目的兩種方法
Android Studio導入Eclipse項目有兩種方法,一種是直接把Eclipse項目導入Android Studio,另一種是在Eclipse項目裡面進行轉換,然
Android 圖片的顏色處理實例代碼
仿造美圖秀秀移動鼠標調整seekbar,調整圖片的顏色項目布局如下:<LinearLayout xmlns:android=http://schemas.andro