您的位置:首页 > 数据库 > SQL

使用SQLiteOpenHelper的onUpgrade实现数据库版本升级

2017-01-05 19:08 691 查看
Andoird的SQLiteOpenHelper类中有一个onUpgrade方法。帮助文档中只是说当数据库升级时该方法被触发。经过实践,解决了我一连串的疑问:

1.帮助文档里说的“数据库升级”是指什么?

你开发了一个程序,当前是1.0版本。该程序用到了数据库。到1.1版本时,你在数据库的某个表中增加了一个字段。那么软件1.0版本用的数据库在软件1.1版本就要被升级了。

2.数据库升级应该注意什么?

软件的1.0版本升级到1.1版本时,老的数据不能丢。那么在1.1版本的程序中就要有地方能够检测出来新的软件版本与老的数据库不兼容,并且能够有办法把1.0软件的数据库升级到1.1软件能够使用的数据库。换句话说,要在1.0软件的数据库的那个表中增加那个字段,并赋予这个字段默认值。

3.程序如何知道数据库需要升级?

SQLiteOpenHelper类的构造函数有一个参数是intversion,它的意思就是指数据库版本号。比如在软件1.0版本中,我们使用SQLiteOpenHelper访问数据库时,该参数为1,那么数据库版本号1就会写在我们的数据库中。

到了1.1版本,我们的数据库需要发生变化,那么我们1.1版本的程序中就要使用一个大于1的整数来构造SQLiteOpenHelper类,用于访问新的数据库,比如2。

当我们的1.1新程序读取1.0版本的老数据库时,就发现老数据库里存储的数据库版本是1,而我们新程序访问它时填的版本号为2,系统就知道数据库需要升级。

4.何时触发数据库升级?如何升级?

当系统在构造SQLiteOpenHelper类的对象时,如果发现版本号不一样,就会自动调用onUpgrade函数,让你在这里对数据库进行升级。根据上述场景,在这个函数中把老版本数据库的相应表中增加字段,并给每条记录增加默认值即可。

新版本号和老版本号都会作为onUpgrade函数的参数传进来,便于开发者知道数据库应该从哪个版本升级到哪个版本。

升级完成后,数据库会自动存储最新的版本号为当前数据库版本号。

案例:

2013年4月,我们第一次发布了我们的应用,数据库版本是1。

2013年5月,我们第二次发布了我们的应用,数据库版本是2。由于业务需要,我们更改了数据库里的某个表的表结构。

这时候就有这样的难题出现:

有些用户已经下载了4月份的版本1,并且已经使用了,很多数据存储在数据库了,这个时候,他想安装新的版本2,怎么办?怎么才能让数据不丢失?

有的用户直接装了5月份的版本,那这些用户就直接使用了新的表结构格式。

可能以后还有版本3,4,N,怎么保证“数据不丢失的情况下“让用户手机里的数据库跟着升级?

------

我们记得SQLiteOpenHelper的onUpgrade方法,那么它是如何工作呢?我们该如何使用他?下面先说说使用它的方式。

解决方案:

我们在4月份数据库建立时,使用下面的方式

packagedome.file.com.filedome;

importandroid.content.Context;
importandroid.database.sqlite.SQLiteDatabase;
importandroid.database.sqlite.SQLiteOpenHelper;

/**
*Createdbylidaqiangon17/1/5.
*/
publicclassMyDbHelper1extendsSQLiteOpenHelper{
publicfinalstaticintDB_VERSION=1;
publicfinalstaticStringDB_NAME="mydb.db";
publicfinalStringTABLE_NAME="tbl_data";
publicfinalStringCOL_UID="uid";
publicfinalStringCOL_ITSVALUE="itsvalue";
publicfinalStringCOL_CREATEDDATE="createddate";
publicfinalStringCOL_DESC="desc";

publicMyDbHelper1(Contextcontext){
super(context,DB_NAME,null,DB_VERSION);
}

@Override
publicvoidonCreate(SQLiteDatabasedb){
Stringsql="createtable["+TABLE_NAME+"]([uid]intidentityprimarykey,[itsvalue]nvarchar(200),createddateTIMESTAMPdefault(datetime('now','localtime')))";
db.execSQL(sql);
}

@Override
publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){
}
}





我们注意看下数据库的版本



..............................

于是到了五月份,由于业务需要,我们想添加新的字段到这个表里。我们这样写代码:

packagedome.file.com.filedome;

importandroid.content.Context;
importandroid.database.sqlite.SQLiteDatabase;
importandroid.database.sqlite.SQLiteOpenHelper;

/**
*Createdbylidaqiangon17/1/5.
*/
publicclassMyDbHelperextendsSQLiteOpenHelper{
publicfinalstaticintDB_VERSION=2;//版本号升级为2
publicfinalstaticStringDB_NAME="mydb.db";
publicfinalStringTABLE_NAME="tbl_data";
publicfinalStringCOL_UID="uid";
publicfinalStringCOL_ITSVALUE="itsvalue";
publicfinalStringCOL_CREATEDDATE="createddate";
publicfinalStringCOL_DESC="desc";

publicMyDbHelper(Contextcontext){
super(context,DB_NAME,null,DB_VERSION);
}

@Override
publicvoidonCreate(SQLiteDatabasedb){
//如果以前没有数据库,现在创建新的数据库时已经有新列desc了。
Stringsql="createtable["+TABLE_NAME+"]([uid]intidentityprimarykey,[itsvalue]nvarchar(200),createddateTIMESTAMPdefault(datetime('now','localtime')),[desc]nvarchar(300))";
db.execSQL(sql);
}

@Override
publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){
if(oldVersion==1&&newVersion==2){
//从版本1到版本2时,增加了一个字段desc
Stringsql="altertable["+TABLE_NAME+"]add[desc]nvarchar(300)";
db.execSQL(sql);
}
}
}


  这个时候,onCreate方法里,是新的建立表的方式。而不同的是onUpgrade方法里我们检测了这样的变化,如果是从版本1到版本2,我们执行了一段”添加列的sql语句“。这段代码,仅仅在符合这样的场景里执行。

通过上面的方式,我们就完成了一次的数据库升级的操作。Android会判断数据库的版本号,并自动的调用onUpgrade方法。



看看数据库的版本



------------------

下面是一些扩展内容?

我们通过SQLiteExpert看到的这个user_version是什么东西?经过在网络上反复查到资料,这个其实是sqlite数据库的"PRAGMA".

看看描述:

在数据库中,我们可以使用这样写sql语句来查询它:

PRAGMAmain.user_version

或者来设置它的值

PRAGMAmain.user_version=1

更多内容参考sqlite的官方描述。

参考:http://www.sqlite.org/pragma.html

http://dev.10086.cn/cmdn/bbs/thread-25063-1-1.html

http://blog.sina.com.cn/s/blog_6ffbcfdb0100vjhs.html

http://stackoverflow.com/questions/12778551/how-to-check-sqlite-database-file-and-get-my-defined-database-user-version
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: