Android SQLite數據庫版本升級原理解析

Android SQLite數據庫版本升級原理解析

Android使用SQLite數據庫保存數據,那數據庫版本升級是怎麼回事呢,請看下面的詳細分析。

一、軟件v1.0

安裝v1.0,假設v1.0版本只有一個account表,這時走繼承SQLiteOpenHelper的onCreate,不走onUpgrade。

1、v1.0(直接安裝v1.0)

二、軟件v2.0

有2種安裝軟件情況:

1、v1.0   -->  v2.0              不走onCreate,走onUpgrade

2、v2.0(直接安裝v2.0)             走onCreate,不走onUpgrade

v1.0版本只有一個account表,軟件版本升級到v2.0了,但是v2.0數據庫需要新增一個member表,那怎麼辦呢?這裏有2種情況了:一種是安裝了v1.0升級到v2.0,這時不會走繼承SQLiteOpenHelper的onCreate,而是直接走onUpgrade,這時就要在onUpgrade添加member表的代碼了,在onCreate加了也沒用,因爲這種情況都不走onCreate。。另一種情況就是用戶從來沒有安裝過這個軟件,直接安裝v2.0,這時走繼承SQLiteOpenHelper的onCreate,不走onUpgrade,所以要在onCreate添加member表的代碼。這怎麼辦呢?這就要合理升級數據庫版本了。

三、軟件v3.0

假設v3.0又新增一個news表,這裏有三種情況:

1、v1.0   -->  v3.0              不走onCreate,走onUpgrade

2、v2.0   -->  v3.0              不走onCreate,走onUpgrade

3、v3.0(直接安裝v3.0)             走onCreate,不走onUpgrade

那數據庫添加表語句在那裏寫呢?數據庫有一個版本號用DATABASE_VERSION表示

其實想一下,就知道不是onCreate寫就是onUpgrade寫,就是要兼容各種情況下安裝app,都能把數據庫表添加進去就好了。這裏很巧妙:

1、v1.0     DATABASE_VERSION=1000    onCreate      --添加--  account

2、v2.0     DATABASE_VERSION=1001    onCreate      --添加--  account  (v1.0代碼不變)  onUpgrade(DATABASE_VERSION>1000)

                                                       onUpgrade   --添加--  member 

3、v3.0     DATABASE_VERSION=1002    onCreate      --添加--  account  (v1.0代碼不變)  onUpgrade(DATABASE_VERSION>1001)

                                                       onUpgrade   --添加--  member (v2.0代碼不變)

                                                       onUpgrade   --添加--  news

這樣就可以解決問題了,第一版本的都在onCreate,其他版本新增的在onUpgrade,而且在onCreate執行onUpgrade。做判斷是否執行onUpgrade該怎麼判斷呢,所以有了數據庫版本的概念了,DATABASE_VERSION保存當前的數據庫版本,只要當前的數據庫版本比已經安裝的數據庫版本大時,就進入onUpgrade,這時還會把上一個數據庫版本號(oldVersion)跟安裝的數據庫版本號(newVersion)做比較,不同的DATABASE_VERSION添加自己所需要的表(跨版本升級數據庫)。

簡單的實例

(1)、V1.0 : DATABASE_VERSION = 1000 添加一個favorite表

public class DBHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "mall.db"; 
    private static final int DATABASE_VERSION = 1000;

    private static DBHelper instance = null;


    public DBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    public synchronized static DBHelper getInstance(Context context) {
        if (instance == null) {
            instance = new DBHelper(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL.CREATE_TABLE_FAVORITE);

        // 若不是第一個版本安裝,直接執行數據庫升級
        // 請不要修改FIRST_DATABASE_VERSION的值,其爲第一個數據庫版本大小
        final int FIRST_DATABASE_VERSION = 1000;
        onUpgrade(db, FIRST_DATABASE_VERSION, DATABASE_VERSION);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 使用for實現跨版本升級數據庫
        for (int i = oldVersion; i < newVersion; i++) {
            switch (i) {

            default:
                break;
            }
        }
    }
}

其中SQL.java是建表語句

public class SQL {
    public static final String T_FAVORITE = "favorite";


    public static final String CREATE_TABLE_FAVORITE =
            "CREATE TABLE IF NOT EXISTS " + T_FAVORITE + "(" +
                    "id VARCHAR PRIMARY KEY, " +
                    "title VARCHAR, " +
                    "url VARCHAR, " +
                    "createDate VARCHAR " +
                    ")";
}

(2)、V2.0 : DATABASE_VERSION = 1001 在favorite表添加1個deleted字段 ###

public class DBHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "mall.db"; 
    private static final int DATABASE_VERSION = 1001;

    private static DBHelper instance = null;


    public DBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    public synchronized static DBHelper getInstance(Context context) {
        if (instance == null) {
            instance = new DBHelper(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL.CREATE_TABLE_FAVORITE);

        // 若不是第一個版本安裝,直接執行數據庫升級
        // 請不要修改FIRST_DATABASE_VERSION的值,其爲第一個數據庫版本大小
        final int FIRST_DATABASE_VERSION = 1000;
        onUpgrade(db, FIRST_DATABASE_VERSION, DATABASE_VERSION);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 使用for實現跨版本升級數據庫
        for (int i = oldVersion; i < newVersion; i++) {
            switch (i) {
            case 1000:
                upgradeToVersion1001(db);
                break;
            default:
                break;
            }
        }
    }

    private void upgradeToVersion1001(SQLiteDatabase db){
        // favorite表新增1個字段
        String sql1 = "ALTER TABLE "+SQL.T_FAVORITE+" ADD COLUMN deleted VARCHAR";
        db.execSQL(sql1);
    }
}

(3)、V3.0 : DATABASE_VERSION = 1002 在favorite表添加message和type字段 ###

public class DBHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "mall.db"; 
    private static final int DATABASE_VERSION = 1002;

    private static DBHelper instance = null;


    public DBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    public synchronized static DBHelper getInstance(Context context) {
        if (instance == null) {
            instance = new DBHelper(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL.CREATE_TABLE_FAVORITE);

        // 若不是第一個版本安裝,直接執行數據庫升級
        // 請不要修改FIRST_DATABASE_VERSION的值,其爲第一個數據庫版本大小
        final int FIRST_DATABASE_VERSION = 1000;
        onUpgrade(db, FIRST_DATABASE_VERSION, DATABASE_VERSION);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 使用for實現跨版本升級數據庫
        for (int i = oldVersion; i < newVersion; i++) {
            switch (i) {
            case 1000:
                upgradeToVersion1001(db);
                break;
            case 1001:
                upgradeToVersion1002(db);
                break;

            default:
                break;
            }
        }
    }

    private void upgradeToVersion1001(SQLiteDatabase db){
        // favorite表新增1個字段
        String sql1 = "ALTER TABLE "+SQL.T_FAVORITE+" ADD COLUMN deleted VARCHAR";
        db.execSQL(sql1);
    }
    private void upgradeToVersion1002(SQLiteDatabase db){
        // favorite表新增2個字段,添加新字段只能一個字段一個字段加,sqlite有限制不予許一條語句加多個字段
        String sql1 = "ALTER TABLE "+SQL.T_FAVORITE+" ADD COLUMN message VARCHAR";
        String sql2 = "ALTER TABLE "+SQL.T_FAVORITE+" ADD COLUMN type VARCHAR";
        db.execSQL(sql1);
        db.execSQL(sql2);
    }
}

就是這樣,無論v1.0升級到v3.0,或者v2.0升級到3.0,還是v3.0直接安裝,安裝後的v3.0數據庫結構都是一樣的,理解透徹就是好啊,剛做sqlite數據庫的肯定會遇到這些問題,所以在這裏詳細地寫了一下,不過還是要注意一下,就是onUpgrade升級時候一定要寫對,測試好,不然安裝後的數據庫都有問題就麻煩了。

本文來自網絡,原文: http://www.cnblogs.com/liqw/p/4264925.html

個人覺得寫得很好,思路清晰,明瞭易懂,解決了實際問題,特此分享給大家,希望對有相同需求的同志有幫助。

歡迎加QQ羣交流: 365532949
Homepage: http://junkchen.com

發佈了39 篇原創文章 · 獲贊 22 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章