Android SQLite 数据库不丢失数据自动升级流程

       正常我们在开发中经常会遇到sqlite数据库升级的问题,比如增加字段/删除字段/表结构重构等等,随着apk版本的升高,不同版本可能需要对数据库进行修改,但是要求是数据库升级不能影响用户的已存数据,所以今天就来看看数据库升级流程是怎样的。

目录

SQLiteDatabase源码调用流程

数据库自动升级流程


  • SQLiteDatabase源码调用流程

  1. 首先我们需要继承 SQLiteOpenHelper, 下面是 SQLiteOpenHelper 的源码注释:
SQLiteOpenHelper is a helper class to manage database creation and version management.

然后会提示让我们去重写他的三个方法:

    public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,
            @Nullable CursorFactory factory, int version) {
        this(context, name, factory, version, null);
        // 传入我们的数据库名称 和 版本号version
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // 创建表
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 版本升级
    }

       2. 分析以下上述三个方法调用的时机,何时会被调用。

  1. 构造方法--首先我们创建数据库操作类的时候先走构造方法,通过构造方法会把数据库名称和版本号 传 SQLiteOpenHelper
    当然这只是创建了,数据库操作类,数据库还没有创建。
  2. onCreate() 方法是创建表的,只有第一次才会走这个方法,首次创建数据库的时候才会走,之后就不会走了。
  3. onUpgrade()数据库升级,这个方法只有构造方法中传的版本号发生了升级才会走,所以我们升级的逻辑就在这里处理。

                    以上只是常用的方法,还有数据库降级等等方法按需重写。

       3. 方法调用的源码流程图

根据这个流程图配合我们的源码更容易理解 sqlite 整个创建流程,这就是整个数据库版本检测和获得db的过程。对整个流程熟悉了之后,接下来我们就好理解数据库升级。

  • 数据库自动升级流程

对于升级我们就举一个例子,从db version 1 升级到db version 2的过程: 

假如我们的表结构是这样的
* version = 1;
* auto     integer   REAL      REAL
* _id     color     loc_x     loc_y      


* version = 2; 添加了一个 字段 time
* auto     integer   REAL         REAL       REAL
* _id     color     loc_x        loc_y       time

通过分析源码我们知道数据库升级是在 onUpgrade() 方法中的,接下来分析升级流程:

  1. 创建临时缓存表 用于缓存老表里面的数据
  2. 查询老表中的数据并且把数据插入到缓存的表中去
  3. 删除老表,创建新的表结构
  4. 把缓存表数据重新插入到新的表结构中去
  5. 调用查询,插入检测是否升级成功
  6. 升级结束

整个流程就这些,接下来把升级的代码贴上,特别要注意的是升级的流程要放到子线程中去!

@Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //创建临时缓存表 用于缓存老表里面的数据
        String createTable = "CREATE TABLE " + snapCachedTableName
                + " (" + CustomColorEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + CustomColorEntry.COLUMN_NAME_COLOR + " INTEGER,"
                + CustomColorEntry.COLUMN_NAME_LOCX + " REAL,"
                + CustomColorEntry.COLUMN_NAME_LOCY + " REAL)";
        db.execSQL(createTable);
        //查询所有的老表数据
        List<CustomColor> colors = getCustomColors(CustomColorEntry.TABLE_NAME,db);
        //把数据插入到缓存的表中去
        for (CustomColor color : colors){
            insertCustomColor(color, snapCachedTableName,db);
        }
        db.execSQL("drop table " + CustomColorEntry.TABLE_NAME);
        //创建新的表结构
        String createNewTable = "CREATE TABLE " + CustomColorEntry.TABLE_NAME
                + " (" + CustomColorEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + CustomColorEntry.COLUMN_NAME_COLOR + " INTEGER,"
                + CustomColorEntry.COLUMN_NAME_LOCX + " REAL,"
                + CustomColorEntry.COLUMN_NAME_LOCY + " REAL,"
                + CustomColorEntry.COLUMN_NAME_TIME + " REAL)";
        db.execSQL(createNewTable);
        //查询所有的缓存表中的数据
        List<CustomColor> cachedColors = getCustomColors(snapCachedTableName,db);
        //把数据插入到新的表中去
        for (CustomColor color : cachedColors){
            insertCustomColor(color, CustomColorEntry.TABLE_NAME,db);
        }
        db.execSQL("drop table " + snapCachedTableName);
    }

传送门github:https://github.com/WangRain1/DbUpgradeDemo 大家给点支持,笑嘻嘻

发布了119 篇原创文章 · 获赞 140 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/WangRain1/article/details/89228255
今日推荐