如果你足夠細心,一定會發現 MyDatabaseHelper 中還有一個空方法呢!沒錯,onUpgrade() 方法是用於對數據庫進行升級的,它在整個數據庫的管理工作當中起着非常重要的作用,可 千萬不能忽視它喲。
目前 DatabaseTest 項目中已經有一張 Book 表用於存放書的各種詳細數據,如果我們想 再添加一張 Category 表用於記錄書籍的分類該怎么做呢?
比如 Category 表中有 id(主鍵)、分類名和分類代碼這幾個列,那么建表語句就可以 寫成:
create table Category (
id integer primary key autoincrement, category_name text,
category_code integer)
接下來我們將這條建表語句添加到 MyDatabaseHelper 中,代碼如下所示:
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_BOOK = "create table Book ("
+ "id integer primary key autoincrement, "
+ "author text, "
+ "price real, "
+ "pages integer, "
+ "name text)";
public static final String CREATE_CATEGORY = "create table Category ("
+ "id integer primary key autoincrement, "
+ "category_name text, "
+ "category_code integer)";
private Context mContext;
public MyDatabaseHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK); db.execSQL(CREATE_CATEGORY);
Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).
show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
看上去好像都挺對的吧,現在我們重新運行一下程序,並點擊 Create database 按鈕,咦? 竟然沒有彈出創建成功的提示。當然,你也可以通過 adb 工具到數據庫中再去檢查一下,這 樣你會更加地確認,Category 表沒有創建成功!
其實沒有創建成功的原因不難思考,因為此時 BookStore.db 數據庫已經存在了,之后不 管我們怎樣點擊 Create database 按鈕,MyDatabaseHelper 中的 onCreate()方法都不會再次執 行,因此新添加的表也就無法得到創建了。
解決這個問題的辦法也相當簡單,只需要先將程序卸載掉,然后重新運行,這時 BookStore.db 數據庫已經不存在了,如果再點擊 Create database 按鈕,MyDatabaseHelper 中 的 onCreate()方法就會執行,這時 Category 表就可以創建成功了。
不過通過卸載程序的方式來新增一張表毫無疑問是很極端的做法,其實我們只需要巧妙 地運用 SQLiteOpenHelper 的升級功能就可以很輕松地解決這個問題。修改 MyDatabaseHelper中的代碼,如下所示:
public class MyDatabaseHelper extends SQLiteOpenHelper {
……
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists Book");
db.execSQL("drop table if exists Category");
onCreate(db);
}
}
可以看到,我們在 onUpgrade()方法中執行了兩條 DROP 語句,如果發現數據庫中已經 存在 Book 表或 Category 表了,就將這兩張表刪除掉,然后再調用 onCreate()方法去重新創 建。這里先將已經存在的表刪除掉,是因為如果在創建表時發現這張表已經存在了,就會直 接報錯。
接下來的問題就是如何讓 onUpgrade()方法能夠執行了,還記得 SQLiteOpenHelper 的構 造方法里接收的第四個參數嗎?它表示當前數據庫的版本號,之前我們傳入的是 1,現在只 要傳入一個比 1 大的數,就可以讓 onUpgrade()方法得到執行了。修改 MainActivity 中的代碼, 如下所示:
public class MainActivity extends Activity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 2); Button createDatabase = (Button) findViewById(R.id.create_database); createDatabase.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dbHelper.getWritableDatabase();
}
});
}
}
這里將數據庫版本號指定為 2,表示我們對數據庫進行升級了。現在重新運行程序,並點擊 Create database 按鈕,這時就會再次彈出創建成功的提示。為了驗證一下 Category 表是 不是已經創建成功了,我們在 adb shell 中打開 BookStore.db 數據庫,然后鍵入.table 命令, 結果如圖 6.19 所示。
圖 6.19
接着鍵入.schema 命令查看一下建表語句,結果如圖 6.20 所示。
圖 6.20
由此可以看出,Category 表已經創建成功了,同時也說明我們的升級功能的確起到了作用。