• Android之数据库升级onUpgrade降级onDowngrade


    借用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

    下面是老师上课的案例:


     1 package com.example.winxin2;
     2 
     3 import android.content.Context;
     4 import android.database.sqlite.SQLiteDatabase;
     5 import android.database.sqlite.SQLiteDatabase.CursorFactory;
     6 import android.database.sqlite.SQLiteOpenHelper;
     7 import android.util.Log;
     8 
     9 public class MyDatabaseOpenHelper extends SQLiteOpenHelper {
    10 
    11     private static final String DB_NAME = "mydata.db"; // 数据库名称
    12     private static final int version = 2; // 数据库版本
    13 
    14     public MyDatabaseOpenHelper(Context context) {
    15         super(context, DB_NAME, null, version);
    16     }
    17 
    18     // 问题:什么时候执行
    19     // 没有前生
    20     @Override
    21     public void onCreate(SQLiteDatabase db) {
    22         // TODO Auto-generated method stub
    23         // 编写【从0开始到最新状态】建表语句
    24         Log.i("hi", "没有数据库,创建数据库,创建v2.0成功");
    25         String sql_message = "create table t_message (id int primary key,tou1  varchar(50),userName varchar(50),lastMessage varchar(50),datetime  varchar(50))";
    26         String sql_init_1 = "insert into t_message values (1,'abc','abc1','abcd1','hi1')";
    27         String sql_init_2 = "insert into t_message values (2,'abc','abc2','abcd2','hi1')";
    28         String sql_init_3 = "insert into t_message values (3,'abc','abc2','abcd2','hi1')";
    29         db.execSQL(sql_message);
    30         db.execSQL(sql_init_1);
    31         db.execSQL(sql_init_2);
    32         db.execSQL(sql_init_3);
    33 
    34     }
    35 
    36     // v2.0 现在进行时
    37     @Override
    38     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    39         if (oldVersion == 2){
    40             String sql_upgrade_1 = "alter table t_message add column isdel bit default 0";
    41             db.execSQL(sql_upgrade_1);
    42             Log.i("db", "从2到3,升级成功!");
    43         }
    44         
    45         if (oldVersion == 1) {
    46             String sql_upgrade_1 = "alter table t_message add column isdel bit default 0";
    47             db.execSQL(sql_upgrade_1);
    48             String sql_init_1 = "insert into t_message values (1,'abc','abc1','abcd1','hi1',0)";
    49             String sql_init_2 = "insert into t_message values (2,'abc','abc2','abcd2','hi1',0)";
    50             String sql_init_3 = "insert into t_message values (3,'abc','abc2','abcd2','hi1',0)";
    51             db.execSQL(sql_init_1);
    52             db.execSQL(sql_init_2);
    53             db.execSQL(sql_init_3);
    54             Log.i("db", "从1到3,升级成功!");
    55         }
    56     }
    57     
    58     /* 模拟从3.0 降低会2.0 */
    59     @Override
    60     public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    61         //正常来讲大于2.0的,应该有t_message 这张表,且2.0有的字段,3.0都有
    62         try {
    63             //第一、先把t_message 未来的表,改名
    64             String rename_sql = "alter table t_message rename to t_message_bak";
    65             db.execSQL(rename_sql);
    66             Log.i("down", "1.改名成功");
    67             //第二、建立2.0的表结构
    68             String sql_message = "create table t_message (id int primary key,tou1  varchar(50),userName varchar(50),lastMessage varchar(50),datetime  varchar(50))";
    69             db.execSQL(sql_message);
    70             Log.i("down", "2.建立2.0表结构成功");
    71             //第三、把备份的数据,copy到 新建的2.0的表
    72             String sql_copy = "insert into t_message select id,tou1,userName,lastMessage,datetime from t_message_bak";
    73             db.execSQL(sql_copy);
    74             Log.i("down", "3.copy到用户数据到 2.0的表");
    75             //第四、把备份表drop掉
    76             String drop_sql = "drop table if exists t_message_bak";
    77             db.execSQL(drop_sql);
    78             Log.i("down", "4.把备份表drop掉");
    79             
    80         } catch (Exception e) {
    81             //失败
    82             Log.i("hi", "降级失败,重新建立");
    83             String sql_drop_old_table = "drop table if exists t_message";
    84             String sql_message = "create table t_message (id int primary key,tou1  varchar(50),userName varchar(50),lastMessage varchar(50),datetime  varchar(50))";
    85             String sql_init_1 = "insert into t_message values (1,'abc','abc1','abcd1','hi1')";
    86             String sql_init_2 = "insert into t_message values (2,'abc','abc2','abcd2','hi1')";
    87             String sql_init_3 = "insert into t_message values (3,'abc','abc2','abcd2','hi1')";
    88             db.execSQL(sql_drop_old_table);
    89             db.execSQL(sql_message);
    90             db.execSQL(sql_init_1);
    91             db.execSQL(sql_init_2);
    92             db.execSQL(sql_init_3);
    93         }
    94     }
    95     
    96 }

    我自己总结了一下:

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

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

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

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

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

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

  • 相关阅读:
    纯CSS星级评价
    Enterprise Library启用签名后发生 PublicKeyToken错误,HRESULT:0x80131040解决
    SQL Server
    该如何选择国外VPS
    网站的伪静态化
    kernel FIELD_SIZEOF宏 NULL地址不访问不出错
    Activity的四种加载模式
    Git magic 简短git使用命令集
    为什么包含多句代码的宏要用do while包括起来?
    使用lsof来查看FD和进程的关系
  • 原文地址:https://www.cnblogs.com/lgk1002/p/6119607.html
Copyright © 2020-2023  润新知