天天看點

Android 資料庫SQLite更新更新問題

Android中資料持久化存儲可以使用SQLite,常用的是SQLiteOpenHelper。這樣就會引申出一些資料庫更新的問題。

比如,資料庫V1版本中原始表中隻有2個字段,在更新資料庫V2版本中想要在表中多加1個字段。或者是 使用者直接安裝的是資料庫V2版本,如何保證所有表中的字段是最新的?

假設有資料庫V1,資料庫V2,資料庫V3。存在2種安裝情況,都要考慮到。

1,首先安裝V1,依次更新V2,V3。

2,首先安裝V1,解除安裝V1之後安裝V2,解除安裝V2,然後安裝V3。

SQLiteOpenHelper的onCreate()方法隻會在初次建立資料庫的時候調用。而onUpgrade()方法會在資料庫更新的時候調用。像上述情況V1更新V2則會調用該方法。而若直接安裝V2,則隻會調用onCreate()方法,并不會調用到onUpgrade()方法,這個時候需要在onCreate()方法中主動調用onUpgrade()方法并在方法内部判斷隻有當新版本号大于老版本号的時候才執行相應的邏輯。

建立工程DBTest,繼承SQLiteOpenHelper.
           
public class DBSQLiteOpenHelper extends SQLiteOpenHelper {
    private static String DBName = "student.db";
    private static final int oldVersion = ;
    private static final int currentVersion = ;
    private static final String TAG = "DBSQLiteOpenHelper";
    private static DBSQLiteOpenHelper instance = null;
    private   String tabName = "user";

    private DBSQLiteOpenHelper(Context context) {
        super(context, DBName, null,currentVersion);
    }
    public  static DBSQLiteOpenHelper getInstance(Context context) {
        if (instance == null) {
                synchronized (DBSQLiteOpenHelper.class) {
                    if (instance == null)
                        instance = new DBSQLiteOpenHelper(context);
                }
        }
        return instance;
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "create table if not exists "+tabName+" (_id integer primary key autoincrement, name nchar,age nchar)";
        db.execSQL(sql);
        Log.e(TAG, "onCreate: ");
        //首次安裝檢查是否有更新
        onUpgrade(db,oldVersion,currentVersion);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.e(TAG, "oldVersion: "+oldVersion);
        Log.e(TAG, "newVersion: "+newVersion);
        if (oldVersion < newVersion){
            switch (oldVersion){
                case :
                    upgradeToVersionTwo(db);
                    onUpgrade(db,,newVersion);
                    break;
                case :
                    upgradeToVersionThree(db);
                    onUpgrade(db,,newVersion);
                    break;
                default:
                    break;
            }
        }

    }

    /**
     * user表新增1個字段
     * @param db
     */
    private void upgradeToVersionTwo(SQLiteDatabase db) {
        String sql = "alter table "+tabName+" add column gender nchar";
        db.execSQL(sql);
        Log.e(TAG, "upgradeToVersionTwo: ");
    }

    /**
     * 建立新表
     * @param db
     */
    private void upgradeToVersionThree(SQLiteDatabase db) {
        String tableName = "record";
        String sql = "create table if not exists "+tableName+" (_id integer primary key autoincrement, chinese nchar,english nchar)";
        db.execSQL(sql);
        Log.e(TAG, "upgradeToVersionThree: ");
    }
}
           
在MainActivity中調用建立資料庫邏輯。
           
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        DBSQLiteOpenHelper dbsqLiteOpenHelper = DBSQLiteOpenHelper.getInstance(getApplicationContext());
        dbsqLiteOpenHelper.getWritableDatabase();
    }
}
           
目前版本currentVersion為1,即V1(建立user表),修改currentVersion=2,重新編譯生成V2(添加字段),再修改currentVersion=3,重新編譯生成V3(建立新表record)。如圖:
           
Android 資料庫SQLite更新更新問題
下面我們就可以來測試一下了。
首先安裝V1,打開程式,Log如下:
           
Android 資料庫SQLite更新更新問題
調用了onCreate()方法,由于主動調用了onUpgrade()方法,是以會列印出oldVersion 和 newVersion 。由于判斷條件的限定是以不往下繼續執行。

使用DDMS檢視手機檔案,資料庫存放在data/data/包名/databases目錄下
           
Android 資料庫SQLite更新更新問題
student.db資料庫已被建立,将其導出到桌面使用Navicat Premium 打開檢視,user表已被建立。name字段和age字段都建立了。
           
Android 資料庫SQLite更新更新問題
下面我們将V2版本覆寫安裝,打開程式,通過log發現調用了onUpgrade()方法,并調用了upgradeToVersionTwo()方法。
           
Android 資料庫SQLite更新更新問題
重新導出資料庫檔案并檢視發現 gender 字段已經添加到user表中
           
Android 資料庫SQLite更新更新問題
然後将V3版本覆寫安裝,打開程式,通過log發現調用了onUpgrade()方法,并調用了upgradeToVersionThree()方法。
           
Android 資料庫SQLite更新更新問題
重新導出資料庫檔案并檢視發現 新表record 已經建立
           
Android 資料庫SQLite更新更新問題
下面我們再測一下直接安裝V2,先将軟體解除安裝,然後安裝V2,,log如下
           
Android 資料庫SQLite更新更新問題
發現程式執行了onCreate()方法,并且執行了upgradeToVersionTwo()方法。為什麼會執行到upgradeToVersionTwo()方法呢?這是首次安裝,并不會調用資料庫更新邏輯的。是因為我們在 onCreate()方法中手動調用了onUpgrade()方法。

重新導出資料庫檔案并檢視,發現user表中gender字段已被添加上。
           
Android 資料庫SQLite更新更新問題
然後解除安裝V2,安裝V3,log如下
           
Android 資料庫SQLite更新更新問題
重新導出資料庫檔案并檢視,發現user表中gender字段已被添加。并且 record表也建立了。保證了資料庫的統一性。
           
Android 資料庫SQLite更新更新問題