Android使用SQLite数据库保存数据,那数据库版本升级是怎么回事呢,这里说一下。

一、软件v1.0

安装v1.0,假设v1.0版本只有一个account表,这时走继承SQLiteOpenHelper的onCreate,不走onUpgrade。

1、v1.0(直接安装v1.0)

二、软件v2.0

有2种安装软件情况:

1、v1.0   -->  v2.0              不走onCreate,走onUpgrade

2、v2.0(直接安装v2.0)          走onCreate,不走onUpgrade

v1.0版本只有一个account表,软件版本升级到v2.0了,但是v2.0数据库需要新增一个member表,那怎么办呢?这里有2种情况了:一种是安装了v1.0升级到v2.0,这时不会走继承SQLiteOpenHelper的onCreate,而是直接走onUpgrade,这时就要在onUpgrade添加member表的代码了,在onCreate加了也没用,因为这种情况都不走onCreate。。另一种情况就是用户从来没有安装过这个软件,直接安装v2.0,这时走继承SQLiteOpenHelper的onCreate,不走onUpgrade,所以要在onCreate添加member表的代码。这怎么办呢?这就要合理升级数据库版本了。

三、软件v3.0

假设v3.0又新增一个news表,这里有三种情况:

1、v1.0   -->  v3.0              不走onCreate,走onUpgrade

2、v2.0   -->  v3.0              不走onCreate,走onUpgrade

3、v3.0(直接安装v3.0)          走onCreate,不走onUpgrade

那数据库添加表语句在那里写呢?数据库有一个版本号用DATABASE_VERSION表示

其实想一下,就知道不是onCreate写就是onUpgrade写,就是要兼容各种情况下安装app,都能把数据库表添加进去就好了。这里很巧妙:

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。做判断是否执行onUpgrade该怎么判断呢,所以有了数据库版本的概念了,DATABASE_VERSION保存当前的数据库版本,只要当前的数据库版本比已经安装的数据库版本大时,就进入onUpgrade,这时还会把上一个数据库版本号(oldVersion)跟安装的数据库版本号(newVersion)做比较,不同的DATABASE_VERSION添加自己所需要的表(跨版本升级数据库)。

下面做一个简单的实例:

(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.java是建表语句

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

就是这样,无论v1.0升级到v3.0,或者v2.0升级到3.0,还是v3.0直接安装,安装后的v3.0数据库结构都是一样的,理解透彻就是好啊,刚做sqlite数据库的肯定会遇到这些问题,所以在这里详细地写了一下,不过还是要注意一下,就是onUpgrade升级时候一定要写对,测试好,不然安装后的数据库都有问题就麻烦了。

本人原创,转发请附上链接http://www.cnblogs.com/liqw/p/4264925.html

Android SQLite数据库版本升级原理解析的更多相关文章

  1. 转载:Android SQLite数据库版本升级原理解析

    Android使用SQLite数据库保存数据,那数据库版本升级是怎么回事呢,这里说一下. 一.软件v1.0 安装v1.0,假设v1.0版本只有一个account表,这时走继承SQLiteOpenHel ...

  2. 图解IntelliJ IDEA 13版本对Android SQLite数据库的支持

    IntelliJ IDEA 13版本的重要构建之一是支持Android程序开发.当然对Android SQLite数据库的支持也就成为了Android开发者对IntelliJ IDEA 13版本的绝对 ...

  3. Android SQLite 数据库 增删改查操作

    Android SQLite 数据库 增删改查操作 转载▼ 一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库--SQLite,SQLite3支持NU ...

  4. Android Sqlite 数据库版本更新

      Android Sqlite 数据库版本更新 http://87426628.blog.163.com/blog/static/6069361820131069485844/ 1.自己写一个类继承 ...

  5. Android——SQLite/数据库 相关知识总结贴

    android SQLite简介 http://www.apkbus.com/android-1780-1-1.html Android SQLite基础 http://www.apkbus.com/ ...

  6. Android SQLite 数据库详细介绍

    Android SQLite 数据库详细介绍 我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用 ...

  7. Android sqlite数据库存取图片信息

    Android sqlite数据库存取图片信息 存储图片:bitmap private byte[] getIconData(Bitmap bitmap){ int size = bitmap.get ...

  8. Android SQLite数据库增删改查操作

    一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库——SQLite,SQLite3支持NULL.INTEGER.REAL(浮点数字). TEXT(字符 ...

  9. android: SQLite 数据库的最佳实践

    6.5.1    使用事务 前面我们已经知道,SQLite 数据库是支持事务的,事务的特性可以保证让某一系列的操 作要么全部完成,要么一个都不会完成.那么在什么情况下才需要使用事务呢?想象以下场 景, ...

随机推荐

  1. git入门知识了解

    文章转自:http://www.cnblogs.com/cocowool/archive/2012/02/17/2356125.html 源代码管理系统(SCM)与版本控制   版本控制是一种记录若干 ...

  2. smarty 操作符号,大于、小于。。。

    eq相等,6 w% x7 w6 |3 _ne.neq不相等,( i" }" ~( `# V( t& C, k; [gt大于,lt小于,gte.ge大于等于,lte.le 小 ...

  3. RHEL 安装gcc 艰难历程

    装好系统后···· 各种搜的方案都不好使····· 最后搜到有人说在刚装系统的时候定制软件之类的那个地方选上“开发工具”就可以...

  4. Android - 文件读写操作 总结

    在android中的文件放在不同位置,它们的读取方式也有一些不同. 本文对android中对资源文件的读取.数据区文件的读取.SD卡文件的读取及RandomAccessFile的方式和方法进行了整理. ...

  5. HNU 12845 Ballot Analyzing Device

    题目链接:http://acm.hnu.cn/online/?action=problem&type=show&id=12845&courseid=270 解题报告:有m个认给 ...

  6. [Effective JavaScript 笔记]第38条:在子类的构造函数中调用父类的构造函数

    示例 场景类 场景图(scene)是在可视化的过程中(如游戏或图形仿真场景)描述一个场景的对象集合.一个简单的场景包含了在该场景中的所有对象(称角色),以及所有角色的预加载图像数据集,还包含一个底层图 ...

  7. HDU 1203 I NEED A OFFER (01背包&&概率dp)

    M - I NEED A OFFER! Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...

  8. Windows上搭个Nginx集群环境玩玩

    一.在windows上安装nginx 1.从这里下载nginx的windows版本 2.把压缩文件解压至c盘根目录,并将文件夹重命名成nginx 3.在conf目录下的nginx.conf文件中,指定 ...

  9. 如何实现SSH断开后 进程仍然在后台运行

    1.nohup命令功能:不挂断地运行命令,忽略HUP信号.语法:nohup command & 实例:nohup ping www.google.com & 转自: http://bl ...

  10. Html5 History API解析

    浏览器前进与回退操作 在传统的浏览器中我们只能通过调用window.history对象的 forward() . back() 或 go(number|url) 方法来进行页面的前进.回退或跳转到某一 ...