greenDao数据库升级

致歉

实在抱歉,从 封装篇——DataBase 数据库整理(greenDao示例) 到现在已经整整有9个月了,在里面我说过,要做一篇 geenDao数据库升级的文章,拖到现在才开始动手。


原由

4月份到7月份这段时间,我忙着准备找工作以及找工作,时间比较紧没来得及做。 这相信大家能谅解。
然而7月份到12月这段时间没有写,确是笔者本身出了很大的问题,简直让人不可原谅,除了愧对各位粉丝同学以外,更是对不起我父母、我女朋友。
7月中旬 笔者微信加了一个群,红包踩雷群,大概就是 我指定一个数字 发一个100元7包的红包给你们抢, 抢到金额倒数第二位为我指定的数字的那个人就需要私包给我一个150的红包。一开始也没什么,那时候工作换好,女朋友也相处得不错,手里也有几个闲钱,就娱乐消遣下,也能克制住,两个月下来也就输个两三千。对生活几乎没什么影响。笔者也没太在意感觉这东西小赌怡情,感觉自身意志力坚定 不会陷进去的。
噩耗开始了….. 下次再讲,开始撸代码吧!!!

撸代码

Why do?

我们数据升级 都是通过 SQLiteOpenHelper 类的方法 onUpgrade()
greenDao 默认的 onUpgrade()是内先删除所有的表,在新建所有的表,来达到一个数据库升级的功能;
然而以上存在一个弊端:“数据库数据全部丢失”;这在我们上线后是绝对不可取的方式!
所以我们要控制数据库升级方式。

What we want?

数据库表升级
数据在数据库升级过后不丢失

Ideas

思路

1、在DBHelper 的 onUpgrade() 内 判断当前版本与最新版本,修改相应的表

2、新建临时表保存数据,表结构更新完成后,数据在拷贝数据进入新表,在删除临时表结构。

这里写图片描述

How we do? _ _ _ _ _ _ _ 前方high-energy

前方高能

修改表结构:备份,删除表,新建表,数据还原。
DBMigrationHelper

public class DBMigrationHelper2 extends AbstractMigratorHelper {
   private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION = "MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS";

    public void onUpgrade(SQLiteDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        generateTempTables(db,daoClasses); //备份数据(表结构改变的表)
        dropAllTables(db, true, daoClasses);  //删除旧表(结构修改/新增)
        createAllTables(db, false, daoClasses); //创建 新表(结构修改/新增)
        restoreData(db, daoClasses);           //恢复数据(结构修改)
    }

    private void dropAllTables(SQLiteDatabase db, boolean b, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        if (daoClasses != null) {
            reflectMethod(db, "dropTable", b, daoClasses);
        }
    }

    private void createAllTables(SQLiteDatabase db, boolean b, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        if (daoClasses != null) {
            reflectMethod(db, "createTable", b, daoClasses);
        }
    }

    /**
     * 反射出方法执行
     */
    private static void reflectMethod(SQLiteDatabase db, String methodName, boolean isExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
        if (daoClasses.length < 1) {
            return;
        }
        try {
            for (Class cls : daoClasses) {
                Method method = cls.getDeclaredMethod(methodName, cls);
                method.invoke(null, db, isExists);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 备份数据
     *
     * @param db
     * @param daoClasses(表结构改变的表)
     */
    private void generateTempTables(xxx){
// 备份数据  思路 建一个临时表 把数据insert进去,,具体代码我在下方会个链接
    }
    /**
     * 恢复数据
     *
     * @param db
     * @param daoClasses(结构修改的表)
     */
    private void restoreData(SQLiteDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
    //还原数据 删除临时表 具体代码请看下方链接
    }
    .......
}

新建一个 DBOpenHelper 类
DBOpenHelper.class

public class DBOpenHelper extends SQLiteOpenHelper {
    public DBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    public DBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
        super(context, name, factory, version, errorHandler);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        DaoMaster.createAllTables(sqLiteDatabase, false);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int currentVersion, int lastestVersion) {
        try {
            DBMigrationHelper migratorHelper = new DBMigrationHelper();
            migratorHelper.onUpgrade(db, FileInfoDao.class); //这边自己通过版本自行判断需要修改的表
        } catch (ClassCastException e) {
        }
    }
 }

END…

技术点就这么多, 主要是个思路,先备份数据,在还原数据。
为了广大同学 我也已经将它做成框架了 一行代码集成使用。
代码:https://github.com/LidongWen/greenDaoUpgradeHepler

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值