`
yangsongjing
  • 浏览: 248536 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

android 数据库版本升级

阅读更多

数据库升级的意义

我们在开发Android应用的时候,不可避免地要使用数据库。而数据库的结构在第一版的时候定下来,之后发布功能更新,或增加业务逻辑,原来的数据库结构可能就不适用了。而如果数据库的结构与之前版本的结构不同,新版本的应用读取旧数据库肯定会出问题。解决办法只有两种:

1.让用户卸载老版本再安装新的程序;

2.软件自行更新数据库结构。

第一种办法很明显不具备可操作性,而且用户一旦卸载软件,数据就丢失了,这是不能容忍的事情。因此,作为开发者必须妥善处理数据库的升级问题。

当然了,有的同学会说,这问题没意义嘛。我们在设计软件的时候就把数据库设计得完备一点就好了,一开始就考虑周全,以后再也不用管升级的事情。这种方法理论上虽然可行,但实际操作起来是非常困难的,除非你在开发定制软件(例如某些和硬件结合的产品,其硬件发布之后就不再更新或很少更新,这样的软件确实没多大改动)。对于面向市场的应用来说,很可能在立项之初根本不会知道以后会增加哪些功能。这样,我们终究还是要面对这个问题。

保留数据的升级

现在以一个假想的程序数据库来谈如何保留原有的数据库进行升级。为直观起见,这里在每次软件版本安装之后导出了数据库文件,并使用SQLite Studio显示表结构和内容,过程从略。并且为了代码的简洁,省略了一些异常处理。我们假设数据库有这样三个版本:

v1:t_user(username, password);

v2: t_user(username, password),  t_region(region, code);

v3: t_user(username, password),  t_region(region, code, country);

可以看出,第一次升级增加了一张表,而第二次升级修改了表的定义。

创建和升级数据表的基本知识

我们在使用数据库之前,基本上会自定义一个类继承自SQLiteOpenHelper。该类的其中一个构造函数形式是这样的(另一个多出来一个DatabaseErrorHandler):

    public SQLiteOpenHelper(Context context, String name, 
                    CursorFactory factory, int version) {
        this(context, name, factory, version, null);
    }

这个构造函数里面的version参数即是我们设定的版本号。第一次使用数据库时传递的这个版本将被系统记录,并调用SQLiteOpenHelper#onCreate()方法进行建表操作。后续传入的版本如果比这个高,则会调用SQLiteOpenHelper#onUpgrade()方法进行升级。

增加一张表

很明显,增加新表(或者删除没有外键的表)的操作代价很小,只需要在onUpgrade()中写好建表操作和插入初始数据就好了。

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion==1){
db.execSQL("CREATE TABLE t_region(_id integer primary key"
 + "autoincrement, region varchar, code varchar)");
//insert data...
}
}

wKioL1PjS46A0YztAAEsNiHN2ns849.jpg

wKioL1PjQQvCoE7JAAEoZeplm10837.jpg

从上面的图里可以看到,新版本的数据库中已经有t_region表了。

修改表定义

SQLite数库对ALTER TABLE命令支持非常有限,只能在表末尾添加列,不能修改列定义,不能删除已有的列。那么如果要修改表呢?我们可以采用临时表的办法。具体来说有四步:

  1. 将现有表重命名为临时表;

  2. 创建新表;

  3. 将临时表的数据导入新表(注意处理修改的列);

  4. 删除临时表。

以例子中的v2升级到v3为例:

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion==2){
db.execSQL("ALTER TABLE t_region RENAME TO t_region_temp");
db.execSQL("CREATE TABLE t_region(_id integer primary key"
     + "autoincrement, region varchar, code varchar, "
     + "country varchar)");
db.execSQL("insert into t_region(_id, region, code, country) " 
    + "select _id, region, code, \"CHINA\" from t_region_temp");
db.execSQL("DROP TABLE t_region_temp");
}
}

wKioL1PjRYui_CqZAAExr2IApJw742.jpg

wKioL1PjRYvzqrd-AAElIqNNLCI543.jpg

需要注意:

  • 重命名表的SQL格式为ALTER TABLE <oldname> RENAME TO <newname>;

  • 导入新数据的insert into select语句中 不能出现values关键字 ;

  • 记得删除临时表 

跨越版本的升级

处理好了单个版本的升级,还有一个更加棘手的问题:如果应用程序发布了多个版本,以致出现了三个以上数据库版本, 如何确保所有的用户升级应用后数据库都能用呢?有两种方式:

方式一:确定 相邻版本 的差别,从版本1开始依次迭代更新,先执行v1到v2,再v2到v3……

方式二:为 每个版本 确定与现在数据库的差别,为每个case撰写专门的升级代码。

方式一的优点是每次更新数据库的时候只需要在onUpgrade方法的末尾加一段从上个版本升级到新版本的代码,易于理解和维护,缺点是当版本变多之后,多次迭代升级可能需要花费不少时间,增加用户等待;

方式二的优点则是可以保证每个版本的用户都可以在消耗最少的时间升级到最新的数据库而无需做无用的数据多次转存,缺点是强迫开发者记忆所有版本数据库的完整结构,且每次升级时onUpgrade方法都必须全部重写。

以上简单分析了两种方案的优缺点,它们可以说在花费时间上是刚好相反的,至于如何取舍,可能还需要结合具体情况分析。

分享到:
评论

相关推荐

    Android 完成数据库的升级,给旧表中添加字段并保持原有数据

    2. `onUpgrade()`方法:当数据库版本升级时调用,用于更新表结构或执行其他必要的升级操作。 二、数据库版本管理 每个SQLite数据库都有一个版本号,可以在SQLiteOpenHelper的构造函数中设置。每次升级时,都需要...

    android 数据库升级方法

    - 当有多个版本升级时,需要在onUpgrade方法中逐个处理,确保所有中间版本都得到正确升级。例如,从版本1直接升级到版本3,需要先执行从1到2的升级,再执行从2到3的升级。 6. **错误处理**: - 如果旧版本号与新...

    Android数据库升级不丢失数据解决方案 OrmLite

    在Android应用开发中,随着应用的迭代更新,数据库版本也需要随之升级以添加新的表或修改已有结构。然而,数据库升级过程中如何确保用户数据不丢失是一个关键问题。Ormlite是一款轻量级的Java ORM(对象关系映射)库...

    android数据库Realm版本更新

    Realm数据库的核心特性之一是其自动版本管理,这使得在应用程序升级时可以方便地进行数据库迁移。 Realm通过内部维护一个版本号来跟踪数据库的变更。当你需要添加新的字段或更改现有模型时,就需要更新这个版本号,...

    Android xutils的数据库增删改查带数据库升级

    在`onCreate`方法中定义了数据库的初始表结构,`onUpgrade`方法则用于处理数据库版本升级。 接下来,我们可以通过XUtils的`DbUtils`类进行数据库的操作。首先,获取到数据库操作对象: ```java DbUtils dbUtils = ...

    Android数据库SQLite详解

    - **onUpgrade()**: 当数据库版本升级时调用,用于更新或删除旧表。 ### 3. CRUD操作 - **创建(CREATE)**: 使用SQL语句`CREATE TABLE`创建新表,例如:`CREATE TABLE IF NOT EXISTS TableName (Column1 DataType, ...

    Android数据库升级demos

    总之,“Android数据库升级demos”是一个很好的学习资源,它展示了如何处理Android应用中的数据库版本升级问题。通过理解和实践这些示例,开发者可以更好地掌握Android数据库管理,确保应用在更新时能顺利地迁移和...

    Android数据库升级保留历史数据库数据

    总结来说,Android数据库升级是一个涉及数据安全和用户体验的重要任务。使用GreenDAO这样的ORM框架可以简化这一过程,但开发者仍需谨慎处理每一个升级步骤,确保数据的完整性和一致性。通过合理的规划和详尽的测试,...

    Android 操作数据库实例sqlite的一些基本操作,包括数据库创建、数据库版本升级、创建表、数据的增删改查

    Android 操作数据库实例sqlite的一些基本操作,包括数据库创建、数据库版本升级、创建表、数据的增删改查

    android数据库应用实例

    综上所述,Android数据库应用实例主要涵盖了SQLite的使用、数据操作、数据库版本管理、性能优化等多个方面,通过实例代码MyDatabase,我们可以深入理解并掌握这些知识,为开发高效、可靠的Android应用程序奠定基础。

    android数据库操作封装

    `onCreate()`用于首次安装应用时创建数据库,`onUpgrade()`则在数据库版本升级时被调用,可以用来更新表结构或数据。 2. 数据表的创建: 在`onCreate()`方法中,我们会编写SQL语句来创建数据表。例如: ```java ...

    android 数据库升级,增加字段

    以上就是Android数据库升级,增加字段的基本步骤和注意事项。在实际开发中,还要考虑更多细节,比如在大量用户数据的情况下,升级操作的性能优化,以及如何避免因升级导致的用户数据丢失等问题。理解并熟练掌握这些...

    Android高级应用源码-sqlite的一些基本操作,包括数据库创建、数据库版本升级、创建表、数据的增删改查.rar

    `onUpgrade()`则在数据库版本升级时调用,可以用来更新或重构数据库结构。 2. **数据库版本升级**: 数据库的版本管理是通过SQLiteOpenHelper的构造函数中的version参数实现的。每次修改数据库结构(如添加新表、...

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

    Android SQLite数据库版本升级的管理实现 Android SQLite数据库版本升级的管理实现是指在Android应用程序中实现数据库版本升级的管理,以便在数据库结构或数据格式发生变化时,能够正确地升级数据库版本。本文主要...

    android 数据库表结构更新步骤

    首先,我们需要创建一个`SQLiteOpenHelper`的子类,这是管理数据库版本和结构的关键类。 - 在这个子类中,我们需要重写`onCreate()`方法来创建初始的数据库表,以及`onUpgrade()`方法来处理数据库升级。 2. **表...

    Android数据库示例源码

    而在onUpgrade()中,我们可以处理数据库版本升级,如添加新表、删除表或修改表结构。 2. **打开/关闭数据库**: 使用SQLiteOpenHelper的getWritableDatabase()或getReadableDatabase()方法来打开数据库。完成后,...

    Android数据库框架-----GreenDao3的相关使用和版本升级更新

    总结,GreenDao3作为Android数据库框架,因其高效、易用的特点,在开发中被广泛采用。正确理解和使用GreenDao3,可以帮助开发者更轻松地处理数据存储和管理,提升应用的开发效率。通过不断学习和实践,可以更好地...

    android数据库操作实例

    `onUpgrade()`则在数据库版本升级时执行,可以用来修改表结构或删除旧表。 在实例中,我们通常会创建一个自定义的SQLiteOpenHelper子类,例如`MyDatabaseHelper`。在`MyDatabaseHelper`中,你可以这样定义`onCreate...

    Android数据库Sqlite的基本用法及升级策略

    **Android数据库SQLite的基本用法** SQLite是Android系统中默认的轻量级数据库,它支持标准的关系型数据库操作,如创建、查询、更新和删除数据。SQLite数据库文件存储在应用程序的私有目录下,保证了数据的安全性。...

    android数据库实践demo

    你需要重写`onCreate()`方法来定义数据库的初始结构,以及`onUpgrade()`方法来处理数据库版本升级。 ```java public class DBDemoHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME =...

Global site tag (gtag.js) - Google Analytics