日志

Android之数据库升级onUpgrade降级onDowngrade

 来源    2016-12-01    0  

借用API文档解释:

public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)

当数据库需要升级时,会调用这个方法。应该使用这个方法来实现删除表、添加表或者做一些需要升级新的策略版本的事情。

SQLite ALTER TABLE的文档可以在以下网址中找到:

http://sqlite.org/lang_altertable.html

如果要给表添加一个新列,那么使用使用ALTER TABLE能够把新列插入到表中。如果要重命名或删除列,那么你能够使用ALTER TABLE能够重命名旧表,然后,创建一个新表,并把旧表中内容复制到新表中。

这个方法是事务中执行的,如果有异常被抛出,所有的改变都会被自动的回滚。

参数:

db:指定要降级的数据库

oldVersion:旧的数据库版本

newVersion:新的数据库版本

总结:

  

v1.0
  1.没有安装过 onCreate()

--------------------------------------
v2.0 [onUpgrade 情况:n-1,onCreate 情况:1]
  1.v1.0 --> v2.0 onUpgrade
  2.没有安装过 onCreate()
-----------------------------------------
v3.0 [onUpgrade 情况:n-1,onCreate 情况:1]
  1. v1.0 -->v3.0 onUpgrade
    alter table t_message add column isdel bit default 0;
  插入数据
  * 2. v2.0 -->v3.0 onUpgrade
    alter table t_message add column isdel bit default 0;
  3. 没有安装过 onCreate()


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

当数据库需要被降级时,调用这个方法。这个方法与onUpgrade(SQLiteDatabase, int, int)方法非常相似,但是它是在当前版本比请求的版本新的时候,才会被调用。但是这个方法不是抽象的,因此它不是强制要求客户实现它的。如果这个方法没有被重写,默认的实现会拒绝降级处理,并抛出SQLiteException异常。

这个方法是在事务中执行的。如果有异常被抛出,所有的改变都会被回滚。

参数:

db:指定要降级的数据库

oldVersion:旧的数据库版本

newVersion:新的数据库版本

总结:

降级的设计关键点
  1、考虑云端要保存用户【自定义数据、行为习惯】。专业术语profile-->>提高用户黏度
  2、考虑[当前]的最低版本要求-->>降低维护成本
  3、尽可能本地的数据转移(所有新版本,都不删除字段)-->尽可能把未知变已知
  try catch

下面是老师上课的案例:


package com.example.winxin2;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class MyDatabaseOpenHelper extends SQLiteOpenHelper {

    private static final String DB_NAME = "mydata.db"; // 数据库名称
    private static final int version = 2; // 数据库版本

    public MyDatabaseOpenHelper(Context context) {
        super(context, DB_NAME, null, version);
    }

    // 问题:什么时候执行
    // 没有前生
    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        // 编写【从0开始到最新状态】建表语句
        Log.i("hi", "没有数据库,创建数据库,创建v2.0成功");
        String sql_message = "create table t_message (id int primary key,tou1  varchar(50),userName varchar(50),lastMessage varchar(50),datetime  varchar(50))";
        String sql_init_1 = "insert into t_message values (1,'abc','abc1','abcd1','hi1')";
        String sql_init_2 = "insert into t_message values (2,'abc','abc2','abcd2','hi1')";
        String sql_init_3 = "insert into t_message values (3,'abc','abc2','abcd2','hi1')";
        db.execSQL(sql_message);
        db.execSQL(sql_init_1);
        db.execSQL(sql_init_2);
        db.execSQL(sql_init_3);

    }

    // v2.0 现在进行时
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (oldVersion == 2){
            String sql_upgrade_1 = "alter table t_message add column isdel bit default 0";
            db.execSQL(sql_upgrade_1);
            Log.i("db", "从2到3,升级成功!");
        }
        
        if (oldVersion == 1) {
            String sql_upgrade_1 = "alter table t_message add column isdel bit default 0";
            db.execSQL(sql_upgrade_1);
            String sql_init_1 = "insert into t_message values (1,'abc','abc1','abcd1','hi1',0)";
            String sql_init_2 = "insert into t_message values (2,'abc','abc2','abcd2','hi1',0)";
            String sql_init_3 = "insert into t_message values (3,'abc','abc2','abcd2','hi1',0)";
            db.execSQL(sql_init_1);
            db.execSQL(sql_init_2);
            db.execSQL(sql_init_3);
            Log.i("db", "从1到3,升级成功!");
        }
    }
    
    /* 模拟从3.0 降低会2.0 */
    @Override
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //正常来讲大于2.0的,应该有t_message 这张表,且2.0有的字段,3.0都有
        try {
            //第一、先把t_message 未来的表,改名
            String rename_sql = "alter table t_message rename to t_message_bak";
            db.execSQL(rename_sql);
            Log.i("down", "1.改名成功");
            //第二、建立2.0的表结构
            String sql_message = "create table t_message (id int primary key,tou1  varchar(50),userName varchar(50),lastMessage varchar(50),datetime  varchar(50))";
            db.execSQL(sql_message);
            Log.i("down", "2.建立2.0表结构成功");
            //第三、把备份的数据,copy到 新建的2.0的表
            String sql_copy = "insert into t_message select id,tou1,userName,lastMessage,datetime from t_message_bak";
            db.execSQL(sql_copy);
            Log.i("down", "3.copy到用户数据到 2.0的表");
            //第四、把备份表drop掉
            String drop_sql = "drop table if exists t_message_bak";
            db.execSQL(drop_sql);
            Log.i("down", "4.把备份表drop掉");
            
        } catch (Exception e) {
            //失败
            Log.i("hi", "降级失败,重新建立");
            String sql_drop_old_table = "drop table if exists t_message";
            String sql_message = "create table t_message (id int primary key,tou1  varchar(50),userName varchar(50),lastMessage varchar(50),datetime  varchar(50))";
            String sql_init_1 = "insert into t_message values (1,'abc','abc1','abcd1','hi1')";
            String sql_init_2 = "insert into t_message values (2,'abc','abc2','abcd2','hi1')";
            String sql_init_3 = "insert into t_message values (3,'abc','abc2','abcd2','hi1')";
            db.execSQL(sql_drop_old_table);
            db.execSQL(sql_message);
            db.execSQL(sql_init_1);
            db.execSQL(sql_init_2);
            db.execSQL(sql_init_3);
        }
    }
    
}

我自己总结了一下:

  1、创建一个继承SQLiteOpenHelper 的类,实现未实现的方法

  2、里面方法采用回调函数,当触发时,系统会自动调用,不用我们手动调

  3、onCreate()方法写最新版本的数据库创建和初始化

  4、onUpgrade()方法写版本更新时数据库更新代码(考虑新客户和老客户,如果太久远的版本可以直接放弃维护,直接弹框要求用户更新最新版本)

  5、onDowngrade()方法注意需要保存关键数据,和try catch

还有很多的不懂,如发现有错,留言告诉我,大家互相学习

相关文章
Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())的注意点
日志以下内容可以作为面试官在面试的时候的问题,感觉比较好,是比较常用的知识点,可以用来考察基础是否扎实. 也可以程序猿学习.开发中的注意点.因为稍微不注意,就有可能导致数据库不能用. DBAdapter. ...
Android版本更新时对SQLite数据库升级或者降级遇到的问题
日志SQLite是Android内置的一个很小的关系型数据库.SQLiteOpenHelper是一个用来辅助管理数据库创建和版本升级问题的抽象类.我们可以继承这个抽象类,实现它的一些方法来对数据库进行自定 ...
04_数据库升级onUpgrade&ondowngrade
日志如果想操作多个数据库就不要把数据库的名字写死了 public MyOpenHelper(Context context, String name){ //第一个参数上下文 //第二个参数 数据库的名字 ...
Android SQLite数据库升级,怎么做(事物更改)
日志SQLiteOpenHelper // 如果数据库文件不存在,只有onCreate()被调用(该方法在创建数据库时被调用一次) public abstract void onCreate(SQLite ...
Android -- 面试 -- 数据库升级策略
日志升级:重写onUpgrade方法 确定 相邻版本 的差别,从版本1开始依次迭代更新,先执行v1到v2,再v2到v3…… 为 每个版本 确定与现在数据库的差别,为每个case撰写专门的升级代码. 降级 ...
android – 不能将数据库从“n”版本降级到“n-1”
问答我有一个使用数据库的应用程序,使用标准的SQLiteOpenHelper创建和打开. 每当我升级数据库版本时,我也升级了应用程序的版本代码,所以没有办法让数据库下载(数据库版本号总是增加,从不减少). ...
android – 无法将数据库从版本2降级为1
问答任何人都可以帮我解决我的代码中发生的这个异常吗? 02-10 17:16:32.406: E/AndroidRuntime(8619): android.database.sqlite.SQLiteE ...
为什么没有在Android sqlite数据库上调用onUpgrade()?
问答我想在安装到我的Android模拟器上时升级我的数据库. 我已经将DbHelper中的db版本设置为继承自SQLiteOpenHelper的数据库版本. 但是,当我的第一个活动加载时,我实例化了我的D ...
android – 混乱:SQLiteOpenHelper onUpgrade()的行为如何?并连同导入旧数据库备份?
问答我们假设我有一个数据库表test_table与2列和相应的创建脚本在SQLiteOpenHelper中: DB_VERSION = 1: public void onCreate(SQLiteData ...
powershell – 用于将SQL Azure数据库升级/降级到标准和高级服务级别的脚本
问答我有一个SQL Azure数据库,在工作时间需要Premium(P1)服务级别,但可以在夜间和周末期间降级为标准(S2)以节省成本. 我可以通过Azure管理门户执行这些操作,没有任何问题,但希望通过 ...
从资产文件夹升级Android SQLite数据库
问答我目前有一个我在Assets文件夹中使用的数据库.我有升级它的问题.每当我启动DATABASE_VERSION数字时,它只会更新某些时间.当它升级时,它会在开始时崩溃,我必须重新打开应用程序. 这是我 ...
Android 数据库升级解决方案
日志请考虑如下情况: 在数据库升级时,不同版本的数据库,他们定义的表结构完全可能是不一样的,比如V1.0的表A有10个column,而在V1.1的表A有12个colum,在升级时,表A增加了两列,此时我们 ...
Android——SQLite数据库(二)升级数据库、增、删、改、查、事务
日志xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= ...
Android数据库升级,数据不丢失解决方案
日志假设要更新TableC表,建议的做法是:        1) 将TableC重命名为TableC_temp        SQL语句可以这样写:ALERT TABLE TableC RENAME TO ...
Android 数据库升级中数据保持和导入已有数据库
日志一.数据库升级: 在我们的程序中,或多或少都会涉及到数据库,使用数据库必定会涉及到数据库的升级,数据库升级带来的一些问题,如旧版本数据库的数据记录的保持,对新表的字段的添加等等一系列问题,还记得当我来 ...
优雅的处理Android数据库升级的问题
日志原始完成于:2015-04-27 19:28:22 提供一种思路,优雅的处理Android数据库升级的问题,直接上代码: package com.example.databaseissuetest; ...
android数据库升级的措辞
日志在基类table增加upgrade操作: public abstract class DbBaseTable { private static final String TAG = "DbB ...
android – Firebase数据库存储到sqlite数据库,其中一些属性不变
问答好的,所以我的app数据库完全存储在firebase上, 我的应用程序每天都会更新其数据库. 我在更新数据期间每次都遵循什么程序: >删除当前的sqlite表 >再次创建表格 >填写 ...
android – 结构数据库Firestore帖子
问答实时x Firestore数据库结构 实时系统结构帖子: Posts --ID_USER_1 ----IdPost1 ------Date ------Image ---IdPost2 ------D ...
尽管使用内容提供程序和顺序数据库访问,android sqlite“数据库已被锁定”
问答我有一个应用程序(Android 2.2 Google API第8级),它有多个活动从内容提供者(仅限SELECT数据库访问)中提取数据. 它还具有接受任何数据库写入任务的中央阻止任务队列的服务;活动 ...