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 = 1;
    private static final int currentVersion = 1;
    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 1:
                    upgradeToVersionTwo(db);
                    onUpgrade(db,2,newVersion);
                    break;
                case 2:
                    upgradeToVersionThree(db);
                    onUpgrade(db,3,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)。如图:

这里写图片描述

下面我们就可以来测试一下了。
首先安装V1,打开程序,Log如下:

这里写图片描述

调用了onCreate()方法,由于主动调用了onUpgrade()方法,所以会打印出oldVersion 和 newVersion 。由于判断条件的限定所以不往下继续执行。

使用DDMS查看手机文件,数据库存放在data/data/包名/databases目录下

这里写图片描述

student.db数据库已被创建,将其导出到桌面使用Navicat Premium 打开查看,user表已被创建。name字段和age字段都创建了。

这里写图片描述

下面我们将V2版本覆盖安装,打开程序,通过log发现调用了onUpgrade()方法,并调用了upgradeToVersionTwo()方法。

这里写图片描述

重新导出数据库文件并查看发现 gender 字段已经添加到user表中

这里写图片描述

然后将V3版本覆盖安装,打开程序,通过log发现调用了onUpgrade()方法,并调用了upgradeToVersionThree()方法。

这里写图片描述

重新导出数据库文件并查看发现 新表record 已经创建

这里写图片描述

下面我们再测一下直接安装V2,先将软件卸载,然后安装V2,,log如下

这里写图片描述

发现程序执行了onCreate()方法,并且执行了upgradeToVersionTwo()方法。为什么会执行到upgradeToVersionTwo()方法呢?这是首次安装,并不会调用数据库升级逻辑的。是因为我们在 onCreate()方法中手动调用了onUpgrade()方法。

重新导出数据库文件并查看,发现user表中gender字段已被添加上。

这里写图片描述

然后卸载V2,安装V3,log如下

这里写图片描述

重新导出数据库文件并查看,发现user表中gender字段已被添加。并且 record表也创建了。保证了数据库的统一性。

这里写图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值