天天看點

Android開發(23)資料庫更新概述實作更新擴充内容:如何資料庫檔案的版本參考

概述

我這裡說的資料庫版本指的是:

我們的應用的程式的資料庫的使用者版本(user_version).比如說下面的情形:

2013年4月,我們第一次 釋出了 我們的應用,資料庫版本是1。

2013年5月,我們第二次 釋出了 我們的應用,資料庫版本是2。由于業務需要,我們更改了資料庫裡的某個表的表結構。

這時候就有這樣的難題出現:

有些使用者已經下載下傳了4月份的版本1,并且已經使用了,很多資料存儲在資料庫了,這個時候,他想安裝新的版本2,怎麼辦? 怎麼才能讓資料不丢失?

有的使用者直接裝了5月份的版本,那這些使用者就直接使用了新的表結構格式。

可能以後還有版本3,4,N,怎麼保證“資料不丢失的情況下“讓使用者手機裡的資料庫跟着更新?

實作

SQLiteOpenHelper 中的 onUpgrade方法可以幫我們實作它,那麼它是如何工作呢?

我們該如何使用他?下面先說說使用它的方式。

剛開始

我們在4月份資料庫建立時,使用下面的方式

public class MyDbHelper1 extends SQLiteOpenHelper{
    public final static int DB_VERSION = 1;
    public final static String DB_NAME = "mydb.db";
    public final String TABLE_NAME = "tbl_data";
    public final String COL_UID = "uid";
    public final String COL_ITSVALUE = "itsvalue";
    public final String COL_CREATEDDATE = "createddate";
    
    public MyDbHelper1(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "create table ["+TABLE_NAME+"] ( [uid] int identity primary key,[itsvalue] nvarchar(200),createddate TIMESTAMP default (datetime('now', 'localtime')) )";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
        
    }
}           

複制

我們看到,在這裡,我們的onCreate方法裡,寫個建表的語句,這個表有3個字段。

我們注意看下資料庫的版本,是1

更新

[時間飛逝]..............................

于是到了五月份,由于業務需要,我們想添加新的字段到這個表裡。我們這樣寫代碼:

public class MyDbHelper2 extends SQLiteOpenHelper{
    public final static int DB_VERSION = 2;
    public final static String DB_NAME = "mydb.db";
    public final String TABLE_NAME = "tbl_data";
    public final String COL_UID = "uid";
    public final String COL_ITSVALUE = "itsvalue";
    public final String COL_CREATEDDATE = "createddate";
    public final String COL_DESC = "desc";
    
    
    public MyDbHelper2(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }
    
    @Override
    public void onCreate(SQLiteDatabase db) {
        //建立新的資料庫時。已經 有新列desc了。
        String sql = "create table ["+TABLE_NAME+"] ( [uid] int identity primary key,[itsvalue] nvarchar(200),createddate TIMESTAMP default (datetime('now', 'localtime')),[desc] nvarchar(300) )";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if(oldVersion == 1 && newVersion == 2){
            //從版本1到版本2時,增加了一個字段 desc
            String sql = "alter table ["+TABLE_NAME+"] add [desc] nvarchar(300)";
            db.execSQL(sql);
        }
        
    }           

複制

這個時候,onCreate方法裡,是新的建立表的方式。

而不同的是 onUpgrade方法裡我們檢測了這樣的變化,

如果 是從版本1到版本2,我們執行了一段”添加列的sql語句“。

也就是說,當檢測到資料庫需要更新時,執行這些 用于更新資料庫的sql。

通過上面的方式,我們就完成了一次的資料庫更新的操作。

android會判斷 資料庫的版本号,并自動的調用onUpgrade方法。

擴充内容:如何資料庫檔案的版本

我們通過 SQLite Expert 軟體(運作在windows下)。可以看到的這個資料庫檔案有個屬性 user_version。

它是sqlite資料庫的 "PRAGMA " 參數。執行 PRAGMA + sql有可以獲得一些資料庫檔案的中繼資料資訊。

比如:

PRAGMA schema_version; 
    PRAGMA schema_version = integer ; 
    PRAGMA user_version; 
    PRAGMA user_version = integer ;
    The pragmas schema_version and user_version are used to set or get the value of the schema-version and user-version, respectively. The schema-version and the user-version are big-endian 32-bit signed integers stored in the database header at offsets 40 and 60, respectively.
    The schema-version is usually only manipulated internally by SQLite. It is incremented by SQLite whenever the database schema is modified (by creating or dropping a table or index). The schema version is used by SQLite each time a query is executed to ensure that the internal cache of the schema used when compiling the SQL query matches the schema of the database against which the compiled query is actually executed. Subverting this mechanism by using "PRAGMA schema_version" to modify the schema-version is potentially dangerous and may lead to program crashes or database corruption. Use with caution!
    The user-version is not used internally by SQLite. It may be used by applications for any purpose.           

複制

在資料庫中,我們可以執行 sql語句來查詢它:

PRAGMA main.user_version            

複制

或者來設定它的值,執行下面的語句

PRAGMA main.user_version = 1           

複制

更多内容參考sqlite的官方描述。

參考

http://www.sqlite.org/pragma.html

http://dev.10086.cn/cmdn/bbs/thread-25063-1-1.html

http://blog.sina.com.cn/s/blog_6ffbcfdb0100vjhs.html

http://stackoverflow.com/questions/12778551/how-to-check-sqlite-database-file-and-get-my-defined-database-user-version