实在抱歉,从 封装篇——DataBase 数据库整理(greenDao示例) 到现在已经整整有9个月了,在里面我说过,要做一篇 geenDao数据库升级的文章,拖到现在才开始动手。
4月份到7月份这段时间,我忙着准备找工作以及找工作,时间比较紧没来得及做。 这相信大家能谅解。
然而7月份到12月这段时间没有写,确是笔者本身出了很大的问题,简直让人不可原谅,除了愧对各位粉丝同学以外,更是对不起我父母、我女朋友。
7月中旬 笔者微信加了一个群,红包踩雷群,大概就是 我指定一个数字 发一个100元7包的红包给你们抢, 抢到金额倒数第二位为我指定的数字的那个人就需要私包给我一个150的红包。一开始也没什么,那时候工作换好,女朋友也相处得不错,手里也有几个闲钱,就娱乐消遣下,也能克制住,两个月下来也就输个两三千。对生活几乎没什么影响。笔者也没太在意感觉这东西小赌怡情,感觉自身意志力坚定 不会陷进去的。
噩耗开始了….. 下次再讲,开始撸代码吧!!!
我们数据升级 都是通过 SQLiteOpenHelper
类的方法 onUpgrade()
;
greenDao 默认的 onUpgrade()
是内先删除所有的表,在新建所有的表,来达到一个数据库升级的功能;
然而以上存在一个弊端:“数据库数据全部丢失”;这在我们上线后是绝对不可取的方式!
所以我们要控制数据库升级方式。
数据库表升级
数据在数据库升级过后不丢失
思路
1、在DBHelper 的 onUpgrade() 内 判断当前版本与最新版本,修改相应的表
2、新建临时表保存数据,表结构更新完成后,数据在拷贝数据进入新表,在删除临时表结构。
前方高能
修改表结构:备份,删除表,新建表,数据还原。
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) {
}
}
}
技术点就这么多, 主要是个思路,先备份数据,在还原数据。
为了广大同学 我也已经将它做成框架了 一行代码集成使用。
代码:https://github.com/LidongWen/greenDaoUpgradeHepler