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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM