Android数据库升级

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rikkatheworld/article/details/88652930

今天跟着大神的blog学习下Android数据库升级的原理。

下面看一个软件的升级的例子

  1. 软件v1.0
    安装v1.0,假设1.0版本只有一个account表,这时继续走SQLiteOpenHelper的onCreate,不走onUpgrade

  2. 软件v2.0
    有两种安装软件的情况:
    1)v1.0 --> v2.0 不走onCreate,执行onUpgrade
    2)v2.0 (直接安装)直接onCreate
    v1.0只有一个account表,软件升级到2.0需要新增一个member表,有两个方法,一是在onUpgrade中添加member方法,另一种就是用户从来没有安装这个软件,直接安装v2.0,这时走onCreate。

  3. 软件v3.0
    假设v3.0又新增一个news表,这里有三种情况:
    1)v1.0 --> v3.0 不走onCreate ,走onUpgrade
    2)v2.0 --> v3.0 不走onCreate,走onUpgrade
    3)v3.0(直接安装) 直接onCreate
    那么数据库添加表语句在哪里写呢?数据库有一个版本号DATABASE_VERSION表示,其实就是要么在onCreate中要么就在onUpgrade中添加,下面有一种做法
    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。
通过数据库版本号来判断要不要Upgrade,如果当前的DATABASE_VERSION比安装数据库的版本号大的时候,就会进入onUpgrade。
下列是一个例子:来自传送门
(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的建表语句为:

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);
    }
}

这就是升级的一个步骤。在onCreate中去执行onUpgrade。

数据库升级原理

在使用数据库时,我们会定义一个继承了SQLiteOpenHelper的子类,就比如刚才的DBHelper。我们通过版本号去更新一个数据库。我们更新一次数据库,当应用去访问数据库的时候就会读取数据库的版本号,如果和之前不一样,则会调用onUpgrade方法。

SQLiteOpenHelper的构造方法
在这里插入图片描述
当版本号小于1时,是会报错的。 CursorFactory和DatabaseErrorHandler我们一般传null。

SQLiteOpenHelper的使用
在这里插入图片描述
DatabaseHelper是继承了SQLiteOpenHelper的数据库类,其中,getWritableDatabase( )会调用getDatabaseLocked(false)方法,在该方法中实现了对数据库版本检查和升级等的逻辑。其中部分代码如下,
在这里插入图片描述
我们可以看到,系统会先调用getVersion获取当前数据库版本,如果没有数据库文件存在则getversion返回0,并且调用数据库的onCreate方法。如果version不为0,则会比较当前version和数据库保存的version从而决定数据库升级还是降级,对于降级数据库会抛出异常。而升级则会调用我们重写的onUpgrade,最后系统会将当前version更新到数据库中。

这里还有一个数据库升级的例子:
传送门

猜你喜欢

转载自blog.csdn.net/rikkatheworld/article/details/88652930