1. 程式人生 > >Android中SQLite的資料庫版本升級詳解

Android中SQLite的資料庫版本升級詳解

Android開發是經常會用到輕量級的資料庫SQLite,但是對於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資料庫結構都是一樣的

謝謝!!!