Android SQLite数据库版本升级的管理实现

Android SQLite数据库版本升级的管理实现

我们知道在SQLiteOpenHelper的构造方法:

super(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

中最后一个参数表示数据库的版本号.当新的版本号大于当前的version时会调用方法:

onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)

所以我们的重点是在该方法中实现SQLite数据库版本升级的管理

当我们项目刚开始的时候第一版SQLiteOpenHelper是这样写的:

package cc.database; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; /** * Demo描述: * SQLite数据库版本升级的管理实现 * * 参考资料: * http://blog.csdn.net/guolin_blog * Thank you very much */ public class DataBaseOpenHelper extends SQLiteOpenHelper { private final static String DATABASE_NAME="test.db"; private static DataBaseOpenHelper mDataBaseOpenHelper; public static final String CREATE_PERSON= "create table person(personid integer primary key autoincrement,name varchar(20),phone VARCHAR(12))"; public DataBaseOpenHelper(Context context,String name,CursorFactory factory,int version) { super(context, name, factory, version); } //注意: //将DataBaseOpenHelper写成单例的. //否则当在一个for循环中频繁调用openHelper.getWritableDatabase()时 //会报错,提示数据库没有执行关闭操作 static synchronized DataBaseOpenHelper getDBInstance(Context context) { if (mDataBaseOpenHelper == null) { mDataBaseOpenHelper = new DataBaseOpenHelper(context,DATABASE_NAME,null,1); } return mDataBaseOpenHelper; } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_PERSON); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }

在几天之后根据项目需求,需要添加一张student表,于是DataBaseOpenHelper就出现了第二版:

package cc.database; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class DataBaseOpenHelper extends SQLiteOpenHelper { private final static String DATABASE_NAME="test.db"; private static DataBaseOpenHelper mDataBaseOpenHelper; public static final String CREATE_PERSON= "create table person(personid integer primary key autoincrement,name varchar(20),phone VARCHAR(12))"; public static final String CREATE_STUDENT= "create table student(studentid integer primary key autoincrement,name varchar(20),phone VARCHAR(12))"; public DataBaseOpenHelper(Context context,String name,CursorFactory factory,int version) { super(context, name, factory, version); } //注意: //将DataBaseOpenHelper写成单例的. //否则当在一个for循环中频繁调用openHelper.getWritableDatabase()时 //会报错,提示数据库没有执行关闭操作 static synchronized DataBaseOpenHelper getDBInstance(Context context) { if (mDataBaseOpenHelper == null) { //改动1 mDataBaseOpenHelper = new DataBaseOpenHelper(context,DATABASE_NAME,null,2); } return mDataBaseOpenHelper; } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_PERSON); //改动2 db.execSQL(CREATE_STUDENT); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //改动3 switch (oldVersion) { case 1: db.execSQL(CREATE_STUDENT); default: } } }

较版本一在版本二中有三处修改的地方:

1 版本号变成了2

2 在onCreate()方法中添加了代码db.execSQL(CREATE_STUDENT);创建student表

因为有的用户根本就没有第一版本的APP,直接从市场下载了第二版本的App。所以当然会执行onCreate()而不会执行onUpgrade()

3 在onUpgrade()做了处理:当oldVersion为1时调用db.execSQL(CREATE_STUDENT);创建student表
   因为有的用户手机上本来就有第一版本的APP,所以在App升级到第二版本时会执行onUpgrade(),不会执行onCreate()

通过这样的处理使得不同的情况下使用第二版APP时都会生成student表

又过了一个月,根据项目变更,需要给person表添加一个字段genderid,于是DataBaseOpenHelper就出现了第三版:

package cc.database; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class DataBaseOpenHelper extends SQLiteOpenHelper { private final static String DATABASE_NAME="test.db"; private static DataBaseOpenHelper mDataBaseOpenHelper; //改动1 public static final String CREATE_PERSON= "create table person(personid integer primary key autoincrement,name varchar(20),phone VARCHAR(12)),genderid integer)"; public static final String ALTER_PERSON="alter table person add column genderid integer"; public static final String CREATE_STUDENT= "create table student(studentid integer primary key autoincrement,name varchar(20),phone VARCHAR(12))"; public DataBaseOpenHelper(Context context,String name,CursorFactory factory,int version) { super(context, name, factory, version); } //注意: //将DataBaseOpenHelper写成单例的. //否则当在一个for循环中频繁调用openHelper.getWritableDatabase()时 //会报错,提示数据库没有执行关闭操作 static synchronized DataBaseOpenHelper getDBInstance(Context context) { if (mDataBaseOpenHelper == null) { //改动2 mDataBaseOpenHelper = new DataBaseOpenHelper(context,DATABASE_NAME,null,3); } return mDataBaseOpenHelper; } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_PERSON); db.execSQL(CREATE_STUDENT); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { switch (oldVersion) { case 1: db.execSQL(CREATE_STUDENT); //改动3 case 2: db.execSQL(ALTER_PERSON); default: } } }

较版本二在版本三中有三处修改的地方:

1 改变了CREATE_PERSON语句,在改语句中增加了一个字段genderid

和前面的描述类似,有的用户第一次安装该APP时就直接下载了第三版

2 修改版本号为3

应对了用户从第一版本或者第二版本升级到第三版本的情况(见下分析)

3 在onUpgrade()方法中)做了处理:当oldVersion为2时调用 db.execSQL(ALTER_PERSON);修改person表,增加genderid字段

应对了用户从第二版本升级到第三版本的情况(见下分析)

注意一个问题:为什么这里的switch语句在每个case中没有break???

这是为了保证跨版本升级的时候每次数据库的升级都会执行到。

比如从第二版升级到第三版本,那么case 2会被执行。

比如从第一版直接升级到第三版本,那么case 1肯定会被调用,由于没有break所以会穿透switch语句又执行case 2语句继续升级,从而保证了数据的所有版本中的升级都会被执行到。

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

时间: 2024-09-20 14:38:57

Android SQLite数据库版本升级的管理实现的相关文章

SQLite数据库版本升级的管理实现

我们知道在SQLiteOpenHelper的构造方法: super(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) 中最后一个参数表示数据库的版本号.当新的版本号大于当前的version时会调用方法: onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 所以我们的重点是在该方法中实现SQLite数据库版本升级的管理

Android SQLite数据库彻底掌握数据存储_Android

SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么. 例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值.  但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段保存除整数以外的数据时,将会产生错误. 另外, SQLite 在解析CREATE TABLE 语句时,会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息,如下面语

android sqlite数据库表字段更新

问题描述 android sqlite数据库表字段更新 android sqlite数据库表字段更新,调用onUpgrade方法出现了Can't upgrade read-only database from version 3 to 4: 异常,有哪个大神碰到过或者知道怎么解决. 代码: public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { String sql = " alter table pe

Android SQLite数据库操作代码类分享_Android

使用示例: package cn.hackcoder.beautyreader.db; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; /** * Created by hackcoder on 15-1-25. */ public clas

android sqlite 数据库问题

问题描述 android sqlite 数据库问题 我想将Android应用中的数据库进行修改,导出后,修改完毕,导入.但是,导入后数据并没有变化,求解..(我用的sqlitestudio工具),求具体的步骤,谁能指导下 解决方案 把原数据库删了(记得备份一次) 解决方案二: 我估计你是导入程序中 sqllite 数据库是正确创建的吗? 进入 --> DDMS --> 打开文件浏览器 --> 选择数据dir -->另外时间选择数据--> 你的包名 -->数据库 dir-

Android SQLite数据库增删改查操作的使用详解_Android

一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库--SQLite,SQLite3支持NULL.INTEGER.REAL(浮点数字). TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型只有五种,但实际上sqlite3也接受varchar(n). char(n).decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型. SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段

Android SQLite数据库增删改查操作的使用详解

一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库--SQLite,SQLite3支持NULL.INTEGER.REAL(浮点数字). TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型只有五种,但实际上sqlite3也接受varchar(n). char(n).decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型. SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段

android SQLite数据库存储数据

简介 SQLite是轻量级嵌入式数据库引擎,它支持 SQL 语言,并且只利用很少的内存就有很好的性能.Android 集成了 SQLite 数据库 Android 在运行时(run-time)集成了 SQLite,所以每个 Android 应用程序都可以使用 SQLite 数据库. 对于熟悉 SQL 的开发人员来时,在 Android 开发中使用 SQLite 相当简单.但是,由于 JDBC 会消耗太多的系统资源,所以 JDBC 对于手机这种内存受限设备来说并不合适.因此,Android 提供了

[Android] SQLite数据库之增删改查基础操作

    在编程中经常会遇到数据库的操作,而Android系统内置了SQLite,它是一款轻型数据库,遵守事务ACID的关系型数据库管理系统,它占用的资源非常低,能够支持Windows/Linux/Unix等主流操作系统,同时能够跟很多程序语言如C#.PHP.Java等相结合.下面先回顾SQL的基本语句,再讲述Android的基本操作. 一. adb shell回顾SQL语句     首先,我感觉自己整个大学印象最深的几门课就包括<数据库>,所以想先回顾SQL增删改查的基本语句.而在Androi