• Android_SQLite版本升级,降级 管理


    今天我们主要学习了数据库版本升级对软件的管理操作。

    我们手机经常会收到xxx软件升级什么的提醒,你的软件版本更新,同时你的数据库对应的版本也要相应的更新。

    数据库版本更新需要主要的问题:

      软件的1.0版本升级到1.1版本时,老的数据不能丢。

      那么在1.1版本的程序中就要有地方能够检测出来新的软件版本与老的数据库不兼容,并且能够有办法把1.0软件的数据库升级到1.1软件能够使用的数据库。

      换句话说,要在1.0软件的数据库的那个表中增加那个字段,并赋予这个字段默认值。

    当然有的时候我们对更新后的 版本并没有什么好感,还不如原来的版本用的顺手,那么我们就会对自己的软件进行降级操作。

    接下来是对升降级数据库版本操作的一个分析。

      当系统在构造SQLiteOpenHelper类的对象时,如果发现版本号不一样,就会自动调用onUpgrade函数,让你在这里对数据库进行升级。

    根据上述场景,在这个函数中把老版本数据库的相应表中增加字段,并给每条记录增加默认值即可。

    新版本号和老版本号都会作为onUpgrade函数的参数传进来,便于开发者知道数据库应该从哪个版本升级到哪个版本。

    升级完成后,数据库会自动存储最新的版本号为当前数据库版本号。

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

      我们用代码描述下版本升级的操作。

    这个mainActivity.class 启动数据库连接

    package com.example.testdb;
    
    import android.app.Activity;
    import android.database.sqlite.SQLiteDatabase;
    import android.os.Bundle;
    
    
    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //创建数据库
            MyDatabaseOpenHelper helper = new MyDatabaseOpenHelper(MainActivity.this);
            //获取数据库连接
            SQLiteDatabase db = helper.getWritableDatabase();
            //关闭数据库
            db.close();
            
        }
    
       
        
    }

    我们创建一个 MyDatabaseOpenHelper .class 进行数据库版本更新操作。

    package com.example.testdb;
    
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    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 = 1;//数据库版本
        
        
        public MyDatabaseOpenHelper(Context context) {
            super(context, DB_NAME, null, version);
            
        }
        
        //问题:什么时候执行? 当没有前生的时候执行
        //onCrate 是一个回调函数
        @Override
        public void onCreate(SQLiteDatabase db) {
            //编写 [从0开始到最新状态]
            //建表语句
            Log.i("hey", "没有数据库,创建数据库。创建1.0成功");
            String sql_message = "create table t_message (uid integer primary key autoincrement,toul  varchar(50),userName varchar(50),lastMessage varchar(50),datetime  varchar(50) )";
            db.execSQL(sql_message);
            String inset_sql1 = "insert into t_message(toul,userName,lastMessage,datetime) values('aaa1','oracle1','oracle, hhz 1','11月20日')";
            String inset_sql2 = "insert into t_message(toul,userName,lastMessage,datetime) values('aaa2','oracle2','oracle, hhz 2','11月20日')";
            String inset_sql3 = "insert into t_message(toul,userName,lastMessage,datetime) values('aaa3','oracle3','oracle, hhz 3','11月20日')";
            db.execSQL(inset_sql1);
            db.execSQL(inset_sql2);
            db.execSQL(inset_sql3);
            
        }
    //从版本一升级到版本二,给表添加数据
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            
            
        }
    
    }

    运行后会在logcat 打印 

    说明最初它是从0 开始进行版本1  的创建。并插入了初始数据

    我们利用昨天的方法将数据库导出,select 一下,也是可以清楚他最初的这个 onCreate 操作。

    那么我们现在在有版本1的情况下对版本进行升级。添加一个列

    这里我们就要用到onUpgrade() 我们参照前面的分析表,当升级的时候分两种情况,

    package com.example.testdb;
    
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    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);
            
        }
        
        //问题:什么时候执行? 当没有前生的时候执行
        //onCrate 是一个回调函数
        @Override
        public void onCreate(SQLiteDatabase db) {
            //编写 [从0开始到最新状态]
            //建表语句
            Log.i("hey", "没有数据库,创建数据库。创建1.0成功");
            String sql_message = "create table t_message (uid integer primary key autoincrement,toul  varchar(50),userName varchar(50),lastMessage varchar(50),datetime  varchar(50),isdel bit default 0 )";
            db.execSQL(sql_message);
            String inset_sql1 = "insert into t_message(toul,userName,lastMessage,datetime) values('aaa1','oracle1','oracle, hhz 1','11月20日')";
            String inset_sql2 = "insert into t_message(toul,userName,lastMessage,datetime) values('aaa2','oracle2','oracle, hhz 2','11月20日')";
            String inset_sql3 = "insert into t_message(toul,userName,lastMessage,datetime) values('aaa3','oracle3','oracle, hhz 3','11月20日')";
            db.execSQL(inset_sql1);
            db.execSQL(inset_sql2);
            db.execSQL(inset_sql3);
            
        }
    //从版本一升级到版本二,给表添加数据
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            
            if(oldVersion == 1) {
                String update_1 = "alter table t_message add column  isdel bit default 0";
                db.execSQL(update_1);
                String inset_sql1 = "insert into t_message(toul,userName,lastMessage,datetime) values('aaa1','oracle1','oracle, hhz 1','11月20日')";
                String inset_sql2 = "insert into t_message(toul,userName,lastMessage,datetime) values('aaa2','oracle2','oracle, hhz 2','11月20日')";
                String inset_sql3 = "insert into t_message(toul,userName,lastMessage,datetime) values('aaa3','oracle3','oracle, hhz 3','11月20日')";
                db.execSQL(inset_sql1);
                db.execSQL(inset_sql2);
                db.execSQL(inset_sql3);
                Log.i("db", "版本1升级到2成功");
            }
            
        }
    
    }

      运行后我们成功将版本一升级至版本二。

    这里的其他操作我就不演示了。

    接下来我们讲讲降级的操作。

    我先将版本3降级至版本2

    /* 模拟从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 (uid integer primary key autoincrement,toul  varchar(50),userName varchar(50),lastMessage varchar(50),datetime  varchar(50),isdel bit default 0 )";
                db.execSQL(sql_message);
                Log.i("down", "2.建立2.0表结构成功");
                //第三、把备份的数据,copy到 新建的2.0的表
                String sql_copy = "insert into t_message select uid,toul,userName,lastMessage,datetime,isdel 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";
                db.execSQL(sql_drop_old_table);
                onCreate(db);
            }
        }

    注意记得将版本号改为2

    当看见logcat的打印上面的内容就说明版本降级成功了。

    当然最后我们还是要将表导出,在cmd查询一遍内容是否一致。

    今天的内容大概这么多,还有很多不懂 ,请大家一起指教。

  • 相关阅读:
    React中 checkbox 与 label 标签的搭配
    HTML5 FileReader对象
    HTML5 FormData 模拟表单控件 支持异步上传二进制文件 移动端
    Nginx 反向代理
    HTML5触摸事件
    利用React遍历数组,并且用数组的元素生成<li>arrItem</li>标签组
    ECMAScript5 [].reduce()
    E:Unable to locate package
    mv和cp命令
    Error response from daemon: Conflict. The container name "xinying_face" is already in use by container
  • 原文地址:https://www.cnblogs.com/heyhhz/p/6118657.html
Copyright © 2020-2023  润新知