Android版本更新时对SQLite数据库升级或者降级遇到的问题

SQLite是Android内置的一个很小的关系型数据库。SQLiteOpenHelper是一个用来辅助管理数据库创建和版本升级问题的抽象类。我们可以继承这个抽象类,实现它的一些方法来对数据库进行自定义操作。下面两个方法必须重写:

  • public void onCreate(SQLiteDatabase db)
  • public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)

另外SQLiteOpenHelper子类在构造实例时必须指定当前数据库的名称(name)、版本号(version)。而这里名称就决定了数据库存储时的文件名称,而这里的版本号与App在AndroidMainfest.xml定义的versionCode没有绝对关联。也就是在App更新时如果数据库的数据结构没有发生变化那么数据库的版本号则不用增加。

onCreate:调用时机是用户首次安装应用后启动,或是清除App数据库文件后启动。这时可以在这个函数中完成初始的数据表的创建。

onUpgrade:调用时机是用户在做应用更新,覆盖安装后启动,如果新版本中数据库版本号要比旧版本中的数据库版本号高则会调用。这时可以在这个函数完成数据库版本升级带来的旧版本的兼容问题,以及数据迁移问题。

还有一个一般情况下不需要重写,但在应用出现逆向降级(如应用由版本号4降级安装版本号为3的包)时必须重写的方法onDowngrade,如果应用降级覆盖安装时没有重写该方法则会崩溃。

在数据库版本升级时, 我们可能会遇到这样一些情况:

  • 需要扩展一个表的字段
  • 删除掉原来表上某个冗余的字段
  • 新建一个表

而处理上面这些问题都要在不损害旧数据库历史数据的前提下完成。这里我们假设用户手机上之前安装的是数据库版本为1的包,升级安装的是数据库版本号为2的包。这时我们要在数据库版本为2的包在去处理这些升级逻辑。

首先是扩展一个表的字段在onUpgrade中的实现为:

[java] view plain copy

  1. @Override
  2. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  3. //旧数据库版本为1,才为表pedant添加一个student_name字段
  4. if(oldVersion < 2) {
  5. db.execSQL("ALTER TABLE pedant ADD COLUMN student_name text");
  6. }
  7. }

SQLite对ALTER TABLE的支持是有限的,你可以在一个存在表上添加一个字段到末尾,或者是改变表的名称。但如果你想做更复杂的操作,比如删除一个表已有的字段,就要重新创建这个表并完成数据迁移,而不能使用DROP COLUMN这样方便的命令了。详见SQLite
Frequently Questions

比如表pedant原来有三个字段a、b、c,现在想删除c字段,那么在onUpgrade中写法如下:

[java] view plain copy

  1. @Override
  2. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  3. //旧数据库版本为1,删除表pedant的c字段
  4. if(oldVersion < 2) {
  5. db.beginTransaction();
  6. try {
  7. db.execSQL("CREATE TEMPORARY TABLE pe_backup (a, b);");
  8. db.execSQL("INSERT INTO pe_backup SELECT a, b FROM pedant;");
  9. db.execSQL("DROP TABLE pedant;");
  10. db.execSQL("CREATE TABLE pedant(a text, b text);");
  11. db.execSQL("INSERT INTO pedant SELECT a, b FROM pe_backup;");
  12. db.execSQL("DROP TABLE pe_backup;");
  13. db.setTransactionSuccessful();
  14. } finally {
  15. db.endTransaction();
  16. }
  17. }
  18. }

这样就既完成了对c字段的删除也保留了原来表上的数据。

最后一种情况最简单直接执行CREATE语句就要可以了。

[java] view plain copy

  1. @Override
  2. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  3. //旧数据库版本为1,创建新表newtb
  4. if(oldVersion < 2) {
  5. db.execSQL("CREATE TABLE newtb(a text, b text);");
  6. }
  7. }

数据库在做升级时我们能明确地知道当前我们要对各旧表进行什么样的操作来兼容新版本。但如果在数据库降级时,情况就不一样了,针对我们开发新版本2时,
我们不能明确地知道以后的新版本比如版本3、4的数据库结构走向是怎样的。比如以后用户从版本3回退到我们正在开发的版本2,由于我们开发当时不能预知版本3的表结构,不知版本3的数据表能否兼容到版本2(假如版本3升级时删除了一个版本2一直在用的表字段,这时回退数据结构可能就不兼容了),那么我们在开发版本2时最稳妥的做法是重写onDowngrade时把所有当前版本将用到的表全部重建,即降级时扔掉以前全部的数据。

// 因为我们无法预知未来版本的表结构,向下兼容时最稳妥的方法就是将该版本自己需要的表重构一次

@Override

public void onDowngrade (SQLiteDatabase db, int oldVersion, int newVersion) {

db.execSQL("DROP TABLE IF EXISTS t1;");

db.execSQL("DROP TABLE IF EXISTS t2;");

db.execSQL("DROP TABLE IF EXISTS t3;");

db.execSQL("DROP TABLE IF EXISTS t4;");

....

onCreate(db); // 建表

}
时间: 2024-11-05 12:29:25

Android版本更新时对SQLite数据库升级或者降级遇到的问题的相关文章

App版本更新时对SQLite数据库升级或者降级遇到的问题

SQLite是Android内置的一个很小的关系型数据库.SQLiteOpenHelper是一个用来辅助管理数据库创建和版本升级问题的抽象类.我们可以继承这个抽象类,实现它的一些方法来对数据库进行自定义操作.下面两个方法必须重写: public void onCreate(SQLiteDatabase db) public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 另外SQLiteOpenHelper子类在

Android——使用SQLiteDatabase操作SQLite数据库

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

Android学习笔记(42):SQLite数据库

(1)SQLite数据库 先简单介绍一下SQLite数据库: 2000年由D.Richard Hipp发布. 是一款轻型.开源嵌入式关系数据库,占用资源非常低.目前用于很多嵌入式产品中,在嵌入式设备中,SQLite可能只需要几百K的内存就够了. 与Mysql.PostgreSQL这两款开源世界著名的数据库管理系统相比,它的处理速度更快. 在Android平台下,除了可以在Android程序中操作SQLite数据库之外,还可以在命令行模式下进行各种数据库的操作,包括表的各种操作,对数据的增加.删除

Android 查看和管理sqlite数据库

在Android中可以使用Eclipse插件DDMS来查看,也可以使用Android工具包中的adb工具来查看.android项目中的sqlite数据库位于/data/data/项目包/databases中. 使用DDMS导出sqlite数据库. 1.首先打开android项目的调试模式,然后找到显示DDMS: 选择DDMS 2.切换到DDMS,显示File Explorer窗口,找到/data/data/ 然后找到程序包的文件夹,打开databases,就能看到sqlite数据库文件了.选择将

Android技术8:SQLite数据升级

由于应用程序的升级,往往伴随着数据库的升级,数据库升级一般设计表的增加与删除,表添加删除字段,数据的备份等操作. 1.数据库升级 我们都通过继承SQLiteOpenHelper类,实现对数据库的操作和版本升级等.版本升级有关方法 onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion); 当版本号大于当前数据库版本号,会调用onUpgrade方法. 2.演示数据库升级 对于表的增删相对比较简单,下面演示添加字段. 2.1原始数据库s

通过adb shell操作android真机的SQLite数据库

要通过命令行直接操作android真机上的SQLite数据库,可以直接通过adb shell来完成,不过,前提是必须获得root权限. 另外,android系统其实就是linux的shell,这个应该大家都知道,不过一般情况下,在/system/xbin/目录下, 没有sqlite3命令,需要手动copy一个进去,通常情况下,需要两个文件 sqlite3.libncurses.so 解压后两个文件都有了,比如解压到:~/Downloads/sqlite3/ 然后就是通过下面的这些个命令,一步一步

Android开发之通过Android的API对sqlite数据库的操作以及数据库事务的练习

一.通过Android的API对sqlite数据库的操作 通过已有的ContentValues类,实例一个对象value来调用其中内部的方法来操作sqlite数据库 代码: package com.example.databasedemo; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sql

android sqlite数据库升级

public class DataHelper extends SQLiteOpenHelper{ private static final int version=1; public DataHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version);//version代表数据库版本号码 // TODO Auto-generat

Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())

数据库版本升级对软件的管理操作. 我们手机经常会收到xxx软件升级什么的提醒,你的软件版本更新,同时你的数据库对应的版本也要相应的更新. 数据库版本更新需要主要的问题: 软件的1.0版本升级到1.1版本时,老的数据不能丢. 那么在1.1版本的程序中就要有地方能够检测出来新的软件版本与老的数据库不兼容,并且能够有办法把1.0软件的数据库升级到1.1软件能够使用的数据库. 换句话说,要在1.0软件的数据库的那个表中增加那个字段,并赋予这个字段默认值. 当然有的时候我们对更新后的 版本并没有什么好感,